任务的同步与通信

    xiaoxiao2022-06-29  45

    信号量、信号量的操作(创建信号量、请求信号量、发送信号量、删除信号量、查询信号量的状态)

    4.2信号量及其操作

    4.2.1信号量

    (1)当事件控制块成员OSEventType的值被设置为OS_EVENT_TYPE_SEM时,这个事件控制块描述的就是一个信号量。

    (2)信号量是由信号量计数器和任务等待表两部分组成。

    (3)每当有任务申请信号量时,

    如果信号量计数器OS_EventCnt() > 0,OSEventCnt – 1,任务继续运行;

    OS_EventCnt() == 0, OSEventCnt = 0,任务列入等待表;

    如果正在使用信号量的任务释放了该信号量,就会在任务等待表中找出优先级别最高的等待任务,并在使它就绪后调用调度器引发一次调度;

    如果任务等待表汇总没有等待任务,信号量+ 1;

     

    4.2.2信号量的操作

    1.创建信号量

    在使用信号量之前,应用程序必须调用函数OSSemCreate()来创建一个信号量。

    函数原型:

    OS_EVENT *OSSemCreate(

                          INT16U cot            //信号量计数器初值

    );

    返回值为已创建的信号量的指针。

    2.请求信号量

    (1)任务通过调用函数OSSemPend()请求信号量,函数原型:

    void OSSemPend(

                   OS_EVNET *pevent,    //信号量的指针

                   INT16U timeout,      //等待时限

                   INT8U *err           //错误信息

    );

    参数pevent是被请求信号量的指针。

    timeout:任务等待时间限制,超过该时间可以结束等待状态而进入就绪状态。

            timeout = 0时,等待时间无限长。

    err:调用成功后值为OS_NO_ERR,失败则会根据出现的具体错误产生不同的值。

    (2)访问共享资源时,先请求管理该资源的信号量,根据信号量是否有效决定该任务是否可以继续运行。

    (3)如果希望在信号量无效时准许任务不进入等待状态而继续运行,则不用函数OSSemPend(),而是调用函数OSSemAccept()来请求信号量。

    3.发送信号量

    (1)释放信号量也叫发送信号量;

    (2)发送信号量必须调用函数OSSemPost():

    该函数对信号量计数器操作之前,先检查是否还有等待该信号量的任务;

    没有—>OSEvemtCnt + 1;

    有  -->调度器OS_Sched()运行等待任务中优先级别最高的任务。

    4.删除信号量

    (1)OSSemDel()

    原型:

    OS_EVENT *OSSemDel(

                       OS_EVENT *pevent,     //信号量的指针

                       INT8U opt,            //删除条件选择

                       INT8U *err            //错误信息

    );

    opt:指明信号量的删除条件,该参数有两个参数值可以选择:

    OS_DEL_NO_PEND,当等待任务表中已没有等待任务时才删除信号量

    OS_DEL_ALLWAYS,等待任务中无论是否有等待任务,都立即删除信号量。

    (2)注意:只能在任务中删除信号量,不能在中断服务程序中删除。

    5.查询信号量的状态

    (1)OSSemQuery(),随时查询信号量的当前状态;

    (2)原型:

    INT8U OSSemQuery

    {

       OS_EVENT_ *pevent,      //信号量指针

       OS_SEM_DATA *pdata      //存储信号量装入结构

    };

    转载请注明原文地址: https://ju.6miu.com/read-1125448.html

    最新回复(0)