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

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


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

使 用 信 号 量


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

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

信号传递是玛雅实时操作系统中任务之间或者中断服程序与任务之间进行协同的一种机制,而信号的传递是通“信号量”来完成的。任务在缺少某种资源而不能进一步处理事务时,可以通过等待相关的信号量来等待该资源的筹备;而在处理某种事务的时机尚不满足的时候,也可以通过等待某个信号量来等待该时机的到来。

任务所等待的资源或时机是由另外的任务或中断服务程序予以筹备或检测的。当相关的任务或者中断服务程序筹备好相关的资源,或检测到相关的条件已经满足之后,就会向信号量投送信号,从而触发等待该信号量的任务退出等待状态,断续运行。当一个紧急任务所等待的信号量被投送时,该任务的紧急信号会被触发,若此时它的紧急信号未被屏弊,它将转到紧急优先级上。在多个任务同时等待一个信号量情况下,信号被投送后,只能由其中一个任务获得且高优级的任务予以优先,其它任务则继续等待。

当任务或者中断服务程序向一个没任务等待的信号量投送信号时,该信号会保留在信号量中。当任务等待一个已存有信号的信号量时,它会立刻获得信号。

在玛雅系统中,信号的投送者可以是任务也可以是中断服务程序,而信号的等待者是一定是任务,中断服务程序不允许等待信号。

信号量在使用之前需要被定义。玛雅系统要求信号量被定义成全局变量或静态局部变量,在定义时要予以赋初值。信号量有两个成员,它们的初值都是0,如下列代所示:

...
OS_SEM Sem = {0, 0};                   //将信号量定义成全局变量
...
void main(void)
{
    static OS_SEM Sem = {0, 0};        //将信号量定义成静态局部变量
    BSP(); // 硬件初化
    OSInit(72000); //玛雅系统初始化
    ...
    while(1)
    {
        ...
    }
}                       (1)

在有些场合的应用中,需要在动态内存中建立信号量。这时可以调用系统函数OSResetSem()来对其进行初始化。当然,在要求对某个信号量做归0处理时也可使用该函数。

...
U8 * pMem;               //指向动态内的指针
...
void main(void)
{
    OS_SEM * pSem;
    ...
    pSem = (OS_SEM *)pMem;  //将信号量建立在动态内存中
    OSResetSem(pSem);       //调用系统函数初始化信号量
    ...    
    while(1)
    {
        ...
    }
}                       (2)

系统函数OSWaitSem()用于等待信号量,而系统函数OSPostSem()则用于投送信号量。OSWaitSem()有两个入口参数,第1个参数的取值是所等待的信号量的地址,第2个参数的取值是超时限定时间,单位为系统节拍。当对第2个参数赋予-1时,表示无限期等待。该函数的返回值为OS_STATUS_OK时,表示成功获提信号,而它值分别代表各种错误。函数OSPostSem()只有1个入口参数,指向接收信号的信号量的地址,而没有返回值。使用信号量的示例代码如下:

...
OS_SEM Sem = {0, 0};
...
void main(void)
{
    ...
    ...    
    while(1)
    {
        ...
        ...
        if(...)
        {      
            ...
            OSPostSem(&Sem);         //在某条件满足时投送信号量
            ...
        }
        ...
    }
}      

void Task(void)
{  
    ...
    while(1)
    {
        ...
        OSWaitSem(&Sem, -1);   //无限期等待一个信号量
        ...
        if(OSWaitSem(&Sem, 1000) == OS_STATUS_OK) //等待1000个系统节拍
        {                                         //并判断是否得到信号
            ...
        }
        else
        {
            ...
        }
        ...
    }
}                 (3)


管理员信箱: stonewayqi@hotmail.com

欣 欣 学 习 网

粤ICP备2023138008号