[uC/OSII]基本操作:新建任务,分配信号量

      对于习惯了单片机直接操作寄存器的人来说,操作系统是个云里雾里的东西,但是uC/OS-II不同,这是一个对底层驱动人员很好的理解操作系统各种概念的一个袖珍型嵌入式操作系统,uC/OS-II作为一个多任务的实时内核,允许建立多达63个用户任务。根据任务优先级和程序运行的情况,决定什么时候从一个任务切换到另一个任务。

首先让我们来看下uC/OS-II的Main函数里面放的是什么:

/* 定义TaskStart任务的堆栈空间 */
#define  APP_CFG_TASK_START_STK_SIZE           512
/* 任务优先级 */
#define  APP_CFG_TASK_START_PRIO                 4
static  void  App_TaskStart (void *p_arg);
/* 申请任务堆栈空间 */
static  OS_STK  App_TaskStartStk[APP_CFG_TASK_START_STK_SIZE];      

int  main (void)
{
    
/* 中断屏蔽 */
    BSP_IntDisAll();
    
/* 系统初始化 */
    OSInit();
    
/* 新建一个初始任务 */
    OSTaskCreate ( (
void (*)(void *))App_TaskStart, 
                   (
void *)0
                   (OS_STK 
*)&App_TaskStartStk[APP_CFG_TASK_START_STK_SIZE - 1],
                   (INT8U)APP_CFG_TASK_START_PRIO );   
    
/* 系统开始运行 */   
    OSStart();
}

      可见uC/OS-II的main非常简洁,仅仅包含初始化和一个初始任务。

      在OSTaskCreate这个函数中,我们新建了一个任务:它的第1个参数是指向该任务运行代码的指针;第2个参数是指向任务初始化数据的指针,这里不需要任何初始化数据,所以传递了一个空指针;第3个参数是任务的堆栈栈顶,由于堆栈是从下往上生长的,所以栈顶=堆栈大小-1;第4个参数指定建立的任务的优先级。这个参数的数值越小,任务的优先级越高。

      这样等运行到OSStart()这句时,多任务就开始运行了。

下面是信号量:

/* 定义一个信号量 */
OS_EVENT 
*LightSem;
/* 初始化信号量 */
LightSem 
= OSSemCreate( 1 );
/* 等待信号量 */
OSSemPend(LightSem,
0,&err);
/* 释放信号量 */
OSSemPost(LightSem);

  这4句就是互斥型信号量的用法,用之前必须初始化这个信号量,这边笔者用的是2值信号量,初始化为1,通常优先级高的任务等待信号量,任务优先级低的释放信号量,这样可以达到同步两个任务的目的。

我们知道在多任务状态下,如果两个任务同时使用了一个资源,则有可能会导致该资源数值与预期不一致,故可以通过信号量来防止同时使用一个资源:

OSSemPend(SharedDataSem, 0&err);

/* 共享数据的处理在此进行(中断是开着的) */

OSSemPost(SharedDataSem);

  这种情况下应该给信号量赋初值1,规则很简单,比如两个任务都需要用到打印机,则要想使用打印机的任务,先要得到该资源的信号量。


原文地址:https://www.cnblogs.com/evisie/p/2106484.html