欣欣学习网,老工程师带你学习单片机技术,欢迎来坐坐。
首  页 | 学习NIOSII | 学习C51 | 学习CPLD | 51+CPLD实验板 | | | MY-RTOS

 系统简介
 系统启动
 创建任务
 等待与休眠
 使用互斥量
 使用信号量
 信号量组
 使用事件
 使用事件组
 消息队列
 动态内存管理
 只读内存管理
 临界段与内核锁
 任务复位与终止


玛雅实时操作系统(MY-RTOS)

信 号 量 组


版权声明:玛雅实时操作系统(MY-RTOS)软件及其说明文档由 欣欣学习网 版主 Stoneway QI 创作,作者保留其版权。任何人可以免费在其产品设计或著作中使用或引用该软件及其说明文档,但要求保留原作品当中的版权声明,并注明引用段落的出处。

-- Stoneway QI 主页: http://www.xxworks.com 邮箱: Stonewayqi@hotmail.com

在有些情下,任务在处理事务时对所需要的资源的选择不是唯一的,或者对所需要的时机的选择不是唯一的。这种情况下,让任务通过等待单一的信号量的方式来等待所需要的资源或者时机,往往是不恰当的。在玛雅系统中,内核为应用程序提供了等待信号量组的机制,很好的解决了这一问题。

一个信号组中可以包含有多个信号量。而等待信号量组的任务则可以从其中的任何一个信号量中获得信号。也就是说,向一个信号量组中的任何一个信号量投送信号,都可以触发等待该信号量组的任务。

在使用信号量组之前,首先要定义一系列的信号量和一个信号量指针数组,以及一个信号量组。玛雅系统要求这些变量都要定义成全局变量或者是静态局部变量。当然,也可以在动态内存中建立这些变量。在使用之前,这些变量要予以赋初值。信号量指针数组中的每一个元素分别指向一个所要使用的信号量,而信号量组的3个成员的初值分别为:信号量指针数组的起始地址、0和所包含的信号量的数量。以包含有3个信号量的信号量组为例,示例代码如下:

...
OS_SEM Sem1 = {0, 0};                     //将信号量定义成全局变量
OS_SEM Sem2 = {0, 0};                     //将信号量定义成全局变量
OS_SEM Sem3 = {0, 0};                     //将信号量定义成全局变量

OS_SEM * pSem[3] = {&Sem1, &Sem2, &Sem3}; //定义一个信号量指针数组

OS_SEM_LIST SemList = {&pSem, 0, 3};      //定义一个信号量组
...
void main(void)
{
    BSP(); // 硬件初化
    OSInit(72000); //玛雅系统初始化
    ...
    while(1)
    {
        ...
    }
}                       (1)

任务通过调用系统函数OSWaitSemList()来等待一个信号量组。该函数有两个入口参数,第1个入口参数的取值是所要等待的信号量组的地址,第2个参数的取值是超时限定时间,单位为系统节拍,当对其赋值为-1时表示无限期等待。如果该函数的返回值为OS_STATUS_OK,则表示成功的获得了一个信号,如果是其它值,则分别代表各种错误。当任务通过调用该函数成功的获得信号时,信号量组的成员Id中会存有提供该信号的信号量在信号量指针数组中的序号。任务可以通过甄别该值来判断信号来自何处。在玛雅系统中,要求同一时间内一个信号量组只能有1个任务等待,但对于信号量组中所包含的信号量可以有多个任务同时等待。下面仍以包含有3个信号量的信号量组为例,示例代码如下:

...
void main(void)
{
    BSP(); // 硬件初化
    OSInit(72000); //玛雅系统初始化
    ...
    while(1)
    {
        ...
        OSWaitSemList(&SemList, -1);  //无限期等待一个信号量组
        switch(SemList.Id)            //取出信号量组中的信号量代码,加以判断
        { 
        case 0:                       //信号来自第1个信号量
           ...
           break;
        case 1:                       //信号来自第2个信号量
           ...
           break;
        case 2:                       //信号来自第3个信号量
           ...
           break;
        default:                      //非法取值
           ...
           break;
        }
        ...
    }   
}     

void Task1(coid)
{
    ...
    while(1)
    {
        ...
        if(...)
        {
            OSPostSem(&Sem1);         //任务1在条件适当时投送信号给信号量Sem1
        }                       
        ...
    }
}

void Task2(coid)
{
    ...
    while(1)
    {
        ...
        if(...)
        {
            OSPostSem(&Sem2);         //任务2在条件适当时投送信号给信号量Sem2
        }   
        ...
    }
}

void Task3(coid)
{
    ...
    while(1)
    {
        ...
        if(...)
        {
            OSPostSem(&Sem3);         //任务3在条件适当时投送信号给信号量Sem3
        } 
        ...
    }
}                  (2)


管理员信箱: stonewayqi@hotmail.com

欣 欣 学 习 网

粤ICP备2023138008号