Ucosiii学习笔记(一)创建任务

针对官网给的uc/os-IIIfor stm32 arm Cortex-M3书籍的学习笔记。
第三章 开始使用ucos-III
1.文件介绍:与其他的C程序一样,在使用前必须包含应用程序所需要的头文件。对应Ucosiii来说,我们可以将需要的头文件放入“includes.h”的文件中,并在拥有主函数的文件中(如app.c)中将它包含进来。
根据书上的历程,其中包含有“app_cfg.h”,“bsp.h”,“os.h”.

  1. “app_cfg.h”文件:可以用来定义任务优先级(APP_TASK_START_PRIO),
    任务堆栈大小(APP_TASK_START_STK_SIZE)
    其他应用程序的细节。
  2. “bsp.h”文件:用来定义应用程序需要使用的外设的函数原型,如
    “BSP_Init()”“LED_set_high()”"OS_TS_GET()"等应用程序需要的功能即可以将使用的外设引进此文件中,并在其定义如外设初始化,外设相关功能等函数,并通过
    include“bsp.h”将其引入app.c中供应用程序调用。
  3. “os.h”文件:为UcosIII的主头文件,其包含以下头文件“os_cfg.h”,“cpu.h”,“cpu_core.h”,“lib_bef.h”,“os_type.h”,“os_cpu.h”.

2.创建应用程序任务,必要的操作是为任务分配任务控制模块(OS_TCB),声明任务堆栈,声明任务函数的原型。并在主函数中创建开始任务

/*在app_cfg.h文件中声明*/
#define  APP_TASK_START_PRIO                        2	//任务的优先级
#define  APP_TASK_START_STK_SIZE                    128 //任务堆栈的大小

/*在app.c文件主函数前*/
static  OS_TCB   AppTaskStartTCB;					//定义任务模块
static  CPU_STK  AppTaskStartStk[APP_TASK_START_STK_SIZE]; //定义任务堆栈大小
static  void  AppTaskCreate (void);					//声明任务函数原型

其中任务优先级是数字约小级别约高,其值必须设置在1到OS_CFG_PRIO_MAX-2之间,其中0与OS_CFG_PRIO_MAX-2优先级用于UcosIII自己保留,OS_CFG_PRIO_MAX其在os_cfg.h文件中定义。
对于任务堆栈的大小定义需要根据所使用MCU的大小去做决定,假如你想分配1KB的空间,而CPU_STK为32为,则可以设置堆栈大小为256.
主函数如下:

int main(void)
{
    OS_ERR  err;
    
    bsp_Init();
    
    OSInit(&err);
    
    OSTaskCreate((OS_TCB     *)&AppTaskStartTCB,                //指向任务的任务控制块
                 (CPU_CHAR   *)"App Task Start",                //任务名
                 (OS_TASK_PTR ) AppTaskStart,                   //任务函数名
                 (void       *) 0,                              //传递给任务的参数
                 (OS_PRIO     ) APP_TASK_START_PRIO,            //任务优先级
                 (CPU_STK    *)&AppStartTaskStk[0],             //任务堆栈基地址
                 (CPU_STK_SIZE) APP_TASK_START_STK_SIZE / 10,   //任务堆栈深度限位
                 (CPU_STK_SIZE) APP_TASK_START_STK_SIZE,        //任务堆栈大小
                 (OS_MSG_QTY  ) 0u,                             //任务内部消息队列能够接收的最大消息数,为0禁止接收消息
                 (OS_TICK     ) 0u,                             //当使能时间片轮时的时间片长度,为0时为默认长度
                 (void       *) 0,                              //用户补充的存储区
                 (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),//任务选项
                 (OS_ERR     *)&err);                           //存放该函数错误时的返回值
                 
    OSStart(&err);
}

其中OS_ERR err;声明一个存在错误标志的变量。
第二行bsp_Init();初始化所有外设,可根据自己使用的外设和单片机去做处理。
第三行OSInit(&err);是os系统的初始化,初始化内部变量和数据结构,并且创建2到5个内部任务,至少会创建OS_IdleTask()任务用于在无其他任务就绪时执行,创建tick task用于记录时钟的允许。此外还会根据宏定义去创建统计任务(OS_StatTask()),计时器任务(OS_tmrTask()),和中断处理程序队列管理任务(OS_IntQTask()).如果os初始化成功则err为OS_ERR_NONE.否则返回相应错误标志,其错误标志以OS_ERR开头可在os.h文件中查询。需要保证OSInit(&err);最优先调用。
第四行任务创建函数OSTaskCreate():它有13个参数。
其中第一个参数时任务控制模块地址。即在主函数前声明的;
第二个是任务名,用于为每个任务分配名称,系统并没有限制其字符的数量;
第三是任务函数名,用于确定所执行的任务函数;
第四是传递给任务的参数,在例程中为0即空指针。可以是任何的指针,给任务函数使用;
第五是任务的优先级,假如你有B,C两个任务在A函数中创建时,当B函数优先级高于A时,任务创建完毕后会立即执行任务B,反之则继续执行任务A创建任务C;
第六是分配给任务的堆栈的基地址;
第七是任务堆栈深度,用于确定任务允许的堆栈增长,在本例中当堆栈剩余10%时达到极限。
第八任务堆栈的大小;
第九是任务内部消息队列接收的最大消息量,
第十是使能时间片轮时时间片长度,
第十一是用户补充的存储区,
第十二是在启用统计任务情况下检查堆栈并创建任务时清除堆栈的内容;
最后一个是任务创建失败时的错误标志返回值。
在创建任务后可以对err变量进行判断,并执行当任务创建失败时所需要执行的操作。
最后一个函数是OSStart(&err);即启动os多任务处理过程。
注意事项:在调用OSStart()函数之前,可以创建任意数量的任务,但是建议只创建 一个任务,因为在单个应用程序任务时允许UcosIII确定CPU的相对速度,允许UcosIII去决定CPU在运行时的使用量的比例,此外如果应用程序需要其他的内核对象如消息队列和信号量那么建议在调用OSStart()之前创建。最后检查中断是否使能。
所有先创建一个开始任务(AppTaskStart),之后在开始任务中创建应用程序所需要执行的任务。
代码如下

/* start task */
static void AppTaskStart(void *p_arg)
{
    CPU_INT32U  cnts;
    OS_ERR err;
    CPU_SR_ALLOC();
    cnts = SystemCoreClock / (CPU_INT32U)OSCfg_TickRate_Hz;        /* Determine nbr SysTick increments                     */
    OS_CPU_SysTickInit(cnts);
    OS_CRITICAL_ENTER();
    /* LED1任务创建 */
    OSTaskCreate((OS_TCB    *)&AppTaskLED1TCB,                      //任务控制块
                 (CPU_CHAR  *)"App Task LED1",                      //任务名
                 (OS_TASK_PTR)AppTaskLED1,                          //任务函数名
                 (void      *)0,                                    //传输给任务的参数
                 (OS_PRIO    )APP_TASK_LED1_PRIO,                   //任务优先级
                 (CPU_STK   *)&AppLED1TaskStk[0],                   //任务堆栈地址
                 (CPU_STK_SIZE)APP_TASK_LED1_STK_SIZE/10,           //任务堆栈深度
                 (CPU_STK_SIZE)APP_TASK_LED1_STK_SIZE,              //任务堆栈大小
                 (OS_MSG_QTY )0u,                                   //任务内部消息队列接收的最大消息量
                 (OS_TICK    )0u,                                   //使能时间片轮时的时间片长度,默认0
                 (void      *)0,                                    //用户补充的存储区        
                 (OS_OPT     )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),//任务选项
                 (OS_ERR    *)&err);                                //存放函数错误时的返回值
    /* LED2任务创建 */
    OSTaskCreate((OS_TCB    *)&AppTaskLED2TCB,
                 (CPU_CHAR  *)"App Task LED2",
                 (OS_TASK_PTR)AppTaskLED2,
                 (void      *)0,
                 (OS_PRIO    )APP_TASK_LED2_PRIO,
                 (CPU_STK   *)&APPLED2TaskStk[0],
                 (CPU_STK_SIZE)APP_TASK_LED2_STK_SIZE/10,
                 (CPU_STK_SIZE)APP_TASK_LED2_STK_SIZE,
                 (OS_MSG_QTY )0u,
                 (OS_TICK    )0u,
                 (void      *)0,
                 (OS_OPT     )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                 (OS_ERR    *)&err);
    OS_CRITICAL_EXIT();//退出临界区
    OSTaskDel((OS_TCB*)&AppTaskStartTCB,&err);//删除任务自身
}

/* App Task LED1 */
static void AppTaskLED1(void *p_arg)
{
    OS_ERR  err;
    while(1){
        GPIO_SetBits(GPIOB,GPIO_Pin_5);
        OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);   	//延时1s
        GPIO_ResetBits(GPIOB,GPIO_Pin_5);
        OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);   	//延时1s
    }
}


/* App Task LED2 */
static void AppTaskLED2(void *p_arg)
{
    OS_ERR  err;
    while(1){
        GPIO_SetBits(GPIOE,GPIO_Pin_5);
        OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);   	//延时1s
        GPIO_ResetBits(GPIOE,GPIO_Pin_5);
        OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);   	//延时1s
    }
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值