STM32F104ZET6之ucosⅢ常用函数

跟風遠走 提交于 2019-12-05 19:23:49

一、OS的初始化与启动

  • 1.OS初始化,初始化各种内核对象和全局变量
函数原型:void  OSInit (OS_ERR  *p_err)
参数:p_err,用于返回错误码
返回值:无

它是第一个执行的函数。

  • 2.启动OS,创建任务后调用
函数原型:void  OSStart (OS_ERR  *p_err)
参数:p_err,用于返回错误码
返回值:无

二、任务的管理

  • 1.创建任务
void  OSTaskCreate (OS_TCB        *p_tcb,//类似于线程id,控制任务
                    CPU_CHAR      *p_name,//任务的名字,可以自定义
                    OS_TASK_PTR    p_task,//任务函数,类似线程函数
                    void          *p_arg,//任务传递参数,类似于给线程函数传递参数
                    OS_PRIO        prio,//任务的优先级
                    CPU_STK       *p_stk_base,//任务栈基址,提供一个数组基址(任务栈数组基地址)
                    CPU_STK_SIZE   stk_limit,//空出10%的栈空间给到堆栈检测函数使用,反过来说,当前任务只能使用90%栈空间
                    CPU_STK_SIZE   stk_size,//任务栈的大小,以字(32位)为单位
                    OS_MSG_QTY     q_size,//任务内消息队列的大小,若不使用,写0
                    OS_TICK        time_quanta,//时间片轮转调度算法,若不使用,写0(这是时间片的长度)
                    void          *p_ext,//提供额外存储空间用于存储浮点运算单元寄存器,若不提供,写NULL
                    OS_OPT         opt,//在创建任务的时候,提供额外操作,如果不使用,写OS_OPT_TASK_NONE
                    OS_ERR        *p_err)//返回错误码,没有错误的就返回OS_ERR_NONE

例如,创建任务1

//task control block,任务1控制块
OS_TCB Task1_TCB;
//任务1函数,类似线程函数
void task1(void *parg);
//任务1的任务堆栈,大小为128字,即512字节
CPU_STK task1_stk[128];

//创建任务1
    OSTaskCreate(   (OS_TCB *)&Task1_TCB,//任务控制块,等同于线程id                                    
                    (CPU_CHAR *)"Task1",//任务的名字,可以自定义                                   
                    (OS_TASK_PTR)task1,//任务函数,等同于线程函数                                   
                    (void *)0,//给任务函数传递参数                                           
                    (OS_PRIO)5,//任务优先级,数值越小,优先级越高                                               
                    (CPU_STK *)task1_stk,//任务堆栈基地址                                  
                    (CPU_STK_SIZE)128/10,//任务堆栈深度限位,用到这个位置,任务不能再继续使用                                    
                    (CPU_STK_SIZE)128,//任务堆栈大小                                      
                    (OS_MSG_QTY)0,//任务内消息队列的大小,不使用,写0                                           
                    (OS_TICK)0,//时间片轮转调度算法,若不使用,写0(默认时间片长度)                                         
                    (void  *)0,//提供额外存储空间用于存储浮点运算单元寄存器,若不提供,写NULL                                           
                    (OS_OPT)OS_OPT_TASK_NONE,//在创建任务的时候,提供额外操作,如果不使用,写OS_OPT_TASK_NONE                              
                    &err//返回错误码,没有错误的就返回OS_ERR_NONE                                             
                );


注意:
创建任务特别检查传递的数组的大小是否空间充足,因为它是作为任务的栈空间使用,若空间不足,会导致程序不能执行,直接跑到HardFault_Handler这个函数。
原因如下:
1)任务里申请大空间的局部变量,例如数组、结构体......,将会占用大量的栈空间
2)任务里包含很多复杂的函数,将会占用大量的栈空间
3)若任务需要用到浮点数运算,要特别注意,出现HardFault_Handler可以尝试分配大一点任务栈,或则提供额外存储空间用于存储浮点运算单元寄存器

  • 2.任务挂起
    暂停任务的执行
void   OSTaskSuspend (OS_TCB  *p_tcb,
                      OS_ERR  *p_err)
参数: p_tcb,类似于线程id,控制任务
      p_err,返回错误码,没有错误的就返回OS_ERR_NONE
返回值:无
用途:1)如果当前任务不是经常要执行的,可以挂起
     2)保护共享资源,可以挂起
  • 3.任务恢复执行
void  OSTaskResume (OS_TCB  *p_tcb,
                    OS_ERR  *p_err)
参数:p_tcb,类似于线程id,控制任务
     p_err,返回错误码,没有错误的就返回OS_ERR_NONE
返回值:无

4.任务的删除

void  OSTaskDel (OS_TCB  *p_tcb,
                 OS_ERR  *p_err)
参数:p_tcb,类似于线程id,控制任务
     p_err,返回错误码,没有错误的就返回OS_ERR_NONE
返回值:无
用途:专门用于初始化硬件,一般来说,硬件只做一次初始化,完毕后可将该任务删除。

三、中断代码编写

void USART1_IRQHandler(void)                    
{
    uint8_t d=0;

    //进入中断,告诉UCOS,要停止任务调度,因为中断处理是一个原子过程,不可拆分 bug kernel:interrupt atom
    //中断里面不能再有任务调度
    OSIntEnter(); 

    //添加中断处理代码
    .....   

    //退出中断,告诉UCOS,准备可以进行任务调度
    OSIntExit();  
}

四、互斥锁

互斥锁常用于任务之间的共享资源(任务之间访问到相同的函数、相同的全局变量)访问,当某个任务得到互斥锁后,就可以访问共享资源,其他任务等待该任务释放互斥锁才能进行访问。

void task(void *parg)
{
    while(1)
    {
        加锁
        访问共享资源
        解锁(立即)

        .....
        加锁
        访问共享资源
        解锁(立即)
        ....
    }
}
  • 1.创建互斥锁
void  OSMutexCreate (OS_MUTEX  *p_mutex,
                     CPU_CHAR  *p_name,
                     OS_ERR    *p_err)
参数:p_mutex,互斥锁对象
     p_name,互斥锁名字
     p_err,返回错误码,没有错误的就返回OS_ERR_NONE
返回值:无
  • 2.等待互斥锁,若等待成功,则锁定共享资源
void  OSMutexPend (OS_MUTEX  *p_mutex,
                   OS_TICK    timeout,
                   OS_OPT     opt,
                   CPU_TS    *p_ts,
                   OS_ERR    *p_err)
参数:p_mutex,互斥锁对象
     timeout,超时时间,默认写0,一直等待
     opt,设置当前等待互斥锁的阻塞方式,默认写OS_OPT_PEND_BLOCKING,阻塞等待
     p_ts,用于记录等待互斥锁花了多长时间,默认写NULL,不记录。
     p_err,返回错误码,没有错误的就返回OS_ERR_NONE
  • 3.释放互斥锁,解锁
void  OSMutexPost (OS_MUTEX  *p_mutex,
                   OS_OPT     opt,
                   OS_ERR    *p_err)
参数:p_mutex,互斥锁对象
     opt,释放互斥锁后希望其他等待锁的任务(最高优先级及就绪)得到立即执行,可以填写这个参数OS_OPT_POST_NONE。
         若使用了OS_OPT_POST_NO_SCHED这个参数,得到互斥锁的任务不会立即执行,会等到当前任务让出cpu才会执行。
     p_err,返回错误码,没有错误的就返回OS_ERR_NONE
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!