ucos-iii 信号量、互斥信号量

目录

一  ucos-iii 信号量相关函数

二  使用信号量

三  互斥量(互斥信号量)常用函数

四  使用互斥信号量访问共享资源

五  任务内置信号量相关函数

六   使用任务内置信号量


一  ucos-iii 信号量相关函数

创建信号量OSSemCreate()OS_CFG_SEM_EN

OS_SEM SwSem;

OS_ERR err;

OSSemCreate(&SwSem, “Switch Semaphore”,
                         0,&err);

删除信号量OSSemDel()  

OS_CFG_SEM_EN

OS_CFG_SEM_DEL_EN

OS_SEM SwSem;

OS_ERR err;
OS_OBJ_QTY qty;

qty = OSSemDel(&SwSem,OS_OPT_DEL_ALWAYS,
           &err);

等待信号量OSSemPend()OS_CFG_SEM_EN

OS_SEM SwSem;

OS_ERR err;
CPU_TS ts;
OS_SEM_CTR ctr;

ctr = OSSemPend(&SwSem,0,
               OS_OPT_PEND_BLOCKING,&ts,&err);

取消等待OSSemPendAbort()

OS_CFG_SEM_EN

OS_CFG_SEM_PEND_ABORT_EN

OS_SEM SwSem;

OS_ERR err;
OS_OBJ_QTY nbr_tasks;

nbr_tasks = OSSemPendAbort(&SwSem,
                OS_OPT_PEND_ABORT_ALL,&err);

释放信号量OSSemPost() OS_CFG_SEM_EN

OS_SEM SwSem;

OS_ERR err;
OS_SEM_CTR ctr;

ctr = OSSemPost(&SwSem,
OS_OPT_POST_1 +OS_OPT_POST_NO_SCHED,
&err);

强制设置信号量的值OSSemSet() 

OS_CFG_SEM_EN

OS_CFG_SEM_SET_EN

OS_SEM SwSem;

OS_ERR err;

OSSemSet(&SwSem,0,&err);

二  使用信号量

使用信号量访问共享资源:

如果一个资源被多个任务访问,则在访问前调用OSSemPend()请求资源,在访问结束后调用OSSemPost ()函数释放资源

OS_SEM MY_SEM;  //定义一个信号量,用于访问共享资源
uint8_t share_res[30]; //共享资源区

//创建一个信号量
OSSemCreate ((OS_SEM*  )&MY_SEM, //指向信号量
                (CPU_CHAR*  )"MY_SEM", //信号量名字
                (OS_SEM_CTR )1, //信号量值为 1
                (OS_ERR* )&err);

void sem0_task(void *p_arg)
{
    OS_ERR err;
    uint8_t task0_str[]="sem0 Running!";
    p_arg = p_arg;
    while(1)
    {
        printf("sem0_task:\r\n");
        OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); // 请求信号量
        memcpy(share_res,task0_str,sizeof(task0_str));    // 向共享资源区拷贝数据
        OSTimeDly (100, OS_OPT_TIME_DLY, &err );          //相对性延时1000个时钟节拍(1s)
        OSSemPost (&MY_SEM,OS_OPT_POST_1,&err);           // 释放信号量
        OSTimeDly (100, OS_OPT_TIME_DLY, &err );          //相对性延时1000个时钟节拍(1s)
    }
}

void sem1_task(void *p_arg)
{
    OS_ERR err;
    p_arg = p_arg;
    uint8_t task1_str[]="sem1 Running!";
    while(1)
    {
        printf("sem1_task:\r\n");
        OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); // 请求信号量
        memcpy(share_res,task1_str,sizeof(task1_str));    // 向共享资源区拷贝数据
        OSTimeDly (100, OS_OPT_TIME_DLY, &err );          //相对性延时1000个时钟节拍(1s)
        OSSemPost (&MY_SEM,OS_OPT_POST_1,&err);           // 释放信号量
        OSTimeDly (100, OS_OPT_TIME_DLY, &err );          //相对性延时1000个时钟节拍(1s)
    }
}

使用信号量访问共享资源会导致优先级翻转,所以一般不推荐使用,下面举例说明:

1. 假设有ABC三个任务,优先级A>B>C,任务AC访问共享资源“res”,任务B不访问共享资源。
2. 现在C正在使用共享资源res,在使用过程中进行了任务调度,由于A的优先级最高,所以接下来执行任务A
3. 由于A需要访问共享资源res,而res正在被C访问,所以任务A进入挂起状态,任务C继续执行。
4. 此时任务C仍在访问共享资源,任务A为挂起态,任务B为就绪态,所以当任务C进行了任务调度后,接下来执行任务B

    在这种情况下,任务 A 的优先级实际上降到了任务 C 的优先级水平,任务 B 的优先级高于任务A。因为任务 A 要一直等待直到任务C释放其占用的那个共享资源。这就是优先级反转。

使用信号量实现任务同步:

任务一通过OSSemPost()发送信号量。
任务二通过OSSemPend()不断请求信号量,如果没有请求到信号量,则进行任务调度,执行下一个任务;如果请求到信号量,则继续运行该任务。

OS_SEM SYNC_SEM;  //定义一个信号量,用于访问共享资源

//创建一个信号量
OSSemCreate ((OS_SEM*  )&MY_SEM, //指向信号量
                (CPU_CHAR*  )"MY_SEM", //信号量名字
                (OS_SEM_CTR )1, //信号量值为 1
                (OS_ERR* )&err);

void sem0_task(void *p_arg)
{
    OS_ERR err;
    p_arg = p_arg;
    while(1)
    {
        OSSemPost(&SYNC_SEM,OS_OPT_POST_1,&err);//发送信号量
        OSTimeDly (100, OS_OPT_TIME_DLY, &err );//延时
    }
}

void sem1_task(void *p_arg)
{
    OS_ERR err;
    uint16_t num = 0;
    p_arg = p_arg;
    while(1)
    {
        OSSemPend(&SYNC_SEM,0,OS_OPT_PEND_BLOCKING,0,&err);// 请求信号量
        num++;
        printf("请求信号量次数: %d\r\n",num);
        OSTimeDly (1000, OS_OPT_TIME_DLY, &err );          //延时
    }
}

三  互斥量(互斥信号量)常用函数

创建互斥信号量OSMutexCreate() OS_CFG_MUTEX_EN

OS_MUTEX DispMutex;

OS_ERR err;

OSMutexCreate(&DispMutex, 

                          “Display Mutex”,&err);

删除互斥型信号量OSMutexDel()

OS_CFG_MUTEX_EN

OS_CFG_MUTEX_DEL_EN

OS_MUTEX DispMutex;

OS_ERR err;
OS_OBJ_QTY qty;

qty = OSMutexDel(&DispMutex,
                    OS_OPT_DEL_ALWAYS,&err);

等待互斥型信号量OSMutexPend()OS_CFG_MUTEX_EN

OS_MUTEX DispMutex;

OS_ERR err;

CPU_TS ts;

OSMutexPend(&DispMutex,0,
        OS_OPT_PEND_BLOCKING,&ts,&err);

取消等待OSMutexPendAbort()

OS_CFG_MUTEX_EN

OS_CFG_MUTEX_PEND_ABORT_EN

OS_MUTEX DispMutex;

OS_ERR err;
OS_OBJ_QTY qty;

qty = OSMutexPendAbort(&DispMutex,
            OS_OPT_PEND_ABORT_ALL,&err);

释放互斥型信号量OSMutexPost()OS_CFG_MUTEX_EN

OS_MUTEX DispMutex;

OS_ERR err;

OSMutexPost(&DispMutex,
                    OS_OPT_POST_NONE,&err);

四  使用互斥信号量访问共享资源

OS_MUTEX TEST_MUTEX;  //定义一个互斥信号量
uint8_t share_res[30]; //共享资源区

//创建一个互斥信号量
OSMutexCreate((OS_MUTEX* )&TEST_MUTEX,
            (CPU_CHAR* )"TEST_MUTEX",
            (OS_ERR* )&err);

void sem0_task(void *p_arg)
{
    OS_ERR err;
    uint8_t task0_str[]="sem0 Running!";
    p_arg = p_arg;
    while(1)
    {
        OSMutexPend (&TEST_MUTEX,0,OS_OPT_PEND_BLOCKING,0,&err);// 请求互斥信号量
        memcpy(share_res,task0_str,sizeof(task0_str));     
        OSMutexPost(&TEST_MUTEX,OS_OPT_POST_NONE,&err);// 释放互斥信号量
        OSTimeDly (100, OS_OPT_TIME_DLY, &err );//延时
    }
}


void sem1_task(void *p_arg)
{
    OS_ERR err;
    uint16_t num = 0;
    uint8_t task1_str[]="sem1 Running!";
    p_arg = p_arg;
    while(1)
    {
        OSMutexPend (&TEST_MUTEX,0,OS_OPT_PEND_BLOCKING,0,&err);// 请求互斥信号量
        memcpy(share_res,task1_str,sizeof(task1_str));      
        OSMutexPost(&TEST_MUTEX,OS_OPT_POST_NONE,&err);// 释放互斥信号量
        OSTimeDly (100, OS_OPT_TIME_DLY, &err );//延时
    }
}

五  任务内置信号量相关函数

等待任务信号量OSTaskSemPend()   

OS_ERR err;
OS_SEM_CTR ctr;
CPU_TS ts;

ctr = OSTaskSemPend(100,
         OS_OPT_PEND_BLOCKING,
         &ts,&err);

取消等待任务信号量OSTaskSemPendAbort() OS_CFG_TASK_SEM_PEND_ABORT_EN

OS_TCB CommRxTaskTCB;

OS_ERR err;
CPU_BOOLEAN aborted;

aborted = OSTaskSemPendAbort(&CommRxTaskTCB,
OS_OPT_POST_NONE,&err);

发送任务信号量OSTaskSemPost()  

OS_TCB CommRxTaskTCB;

OS_ERR err;

OS_SEM_CTR ctr;

ctr = OSTaskSemPost(&CommRxTaskTCB,
                    OS_OPT_POST_NONE,&err);

强行设置任务信号量计数OSTaskSemSet()  

OS_TCB TaskY;

OS_ERR err;

ctr = OSTaskSemSet(&TaskY,0,&err);

六   使用任务内置信号量

使用任务信号量不需要再定义与创建信号量,一般用作同步功能,如下列所示:

extern OS_TCB SEM1TaskTCB;  
void sem0_task(void *p_arg)
{
    OS_ERR err;
    p_arg = p_arg;
    while(1)
    {
        OSTaskSemPost(&SEM1TaskTCB, OS_OPT_POST_NONE,&err); // 使用系统内建信号量向任务发送信号量
        OSTimeDly (1000, OS_OPT_TIME_DLY, &err );//延时
    }
}

void sem1_task(void *p_arg)
{
    OS_ERR err;
    p_arg = p_arg;
    while(1)
    {
        OSTaskSemPend(0,OS_OPT_PEND_BLOCKING,0,&err); // 请求任务内建的信号量
        printf("成功请求到内置信号量\r\n");
        OSSched();  
    }
}

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嵌入式实时操作系统μC/OS-III是一款非常流行且广泛应用的实时操作系统。它被设计用于嵌入式系统中,满足实时性要求高的应用程序的需求。 uCos-III的电子书是对该实时操作系统的详细介绍和使用指南。这本电子书可以帮助读者了解嵌入式系统的基本概念、实时操作系统的工作原理和应用开发方面的技术。它提供了一系列有关uCos-III的知识和实例,使读者能够快速了解和掌握该实时操作系统的使用方法。 这本电子书主要涵盖以下内容: 1. uCos-III的基本概念:介绍了实时操作系统的定义、特点和应用领域,让读者了解操作系统在嵌入式系统中的重要性和作用。 2. uCos-III的架构和特性:介绍了uCos-III的体系结构和主要特性,如任务调度、时钟管理、内存管理、同步与通信等。 3. uCos-III的安装和配置:详细介绍了如何安装和配置uCos-III实时操作系统,包括编译器设置、硬件支持、内核配置等。 4. uCos-III的任务管理:讲解了任务的创建、删除、挂起和恢复等管理操作,同时介绍了任务优先级和实时调度算法。 5. uCos-III的管理服务和通信机制:介绍了信号互斥锁、消息队列、事件标志等管理服务和通信机制,帮助读者实现任务间的同步和通信。 6. uCos-III的中断处理和硬件驱动:讲解了中断处理的机制和方法,以及如何编写硬件驱动程序与uCos-III集成。 这本电子书适合嵌入式系统开发人员、学生以及对实时操作系统感兴趣的人阅读。通过学习这本电子书,读者可以准确理解uCos-III实时操作系统的概念和工作原理,并掌握如何使用uCos-III开发和调试嵌入式应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值