【3】uC/OS-III应用开发————>任务管理(STM32F767)

  1. 简述:
    1. 多任务操作系统核心是对任务的管理,包括:任务创建、挂起、删除、调度和切换等
  2. 任务的基本概念:
    1. uC/OS是一个支持多任务的操作系统
    2. 每个任务独立运行,可共享同一个优先级
    3. 任务越多,堆栈空间越大,每个任务的堆栈空间各自独立
    4. 一个系统能运行多少任务,取决于硬件有多少RMA
    5. 高优先级任务可以打断低优先级任务
    6. 任务间用IPC实现任务之间的通信
    7. 删除任务函数可以将某一任务删除
  3. 任务调度器的基本概念:
    1. uC/OS中提供的任务调度器是基于优先级的全抢占式
    2. 优先级数值越大的任务,优先级越低
    3. (空闲任务)最低优先级= OS_CFG_PRIO_MAX - 1u
    4. 优先级查找的过程决定了调度时间是否具有确定性
    5. 查找优先级方法:
      1. 前导零指定:依拖于硬件
      2. 位图查表法:C语言模仿前导零指令(空间换时间)
    6. 相同优先级的调度:时间片轮转(分时调度器),只在当前系统中无更高优先级有效
    7. 调度原则:
      1. 一旦任务状态发生改变
      2. 并且当前运行任务优先级小于优先级队列中任务最高优先级时
      3. 立刻进行任务切换
    8. 任务的几种状态
      1. 任务状态迁移图:
      2. 就绪:
      3. 延时:
      4. 等待:
      5. 运行:
      6. 挂起:
      7. 延时+挂起:
      8. 等待+挂起:
      9. 超时等待+挂起:
      10. 删除:
  4. 常用任务函数解析:
    1. 任务挂起函数OS_TaskSuspend();
      1. 宏定义OS_CFG_TASK_SUSPEND_EN必须使能
      2. 不能挂起空闲任务
      3. 任务挂起只是将任务进入挂起态,其内部资源保留,
      4. 同时不会参与任务的调度,调用恢复函数,整个任务立即从挂起态进入就绪态
    2. 任务恢复函数OSTaskResume();
      1. 有挂起就有恢复
      2. 恢复任务就是让挂起的任务重新进入就绪状态
      3. 需要使能OS_CFG_TASK_SUSPEND_EN
    3. 删除任务函数OSTaskDel();
      1. 需要使能OS_CFG_TASK_DEL_EN
      2. 删除的任务将从所有就绪、阻塞、挂起和事件列表中删除
      3. 恢复删除的任务只能重新创建
      4. 删除的任务不会释放堆栈空间
    4. 延时函数OSTimeDly();
      1. 停止当前任务的运行,等待延时一段时间后再运行
    5. 延时函数OSTimeDlyHMSM();
      1. 与上述延时功能相同,用于停止当前任务的运行,等待延时一段时间后再运行
      2. 此函数更加直观,可以精确到延时多少个小时、分、秒、毫秒;
      3. 需要使能OS_CFG_TIME_DLY_HMSM_EN
  5. 任务设计要点:
    1. 任务运行的上、下文环境
      1. 中断服务函数:中断服务程序最好保持精简短小、快进快出,只做标记事件的发生
      2. 普通任务:优先级的处理,保证紧急任务的优先级更高
      3. 空闲任务:不允许出现阻塞情况
    2. 任务的执行时间
      1. 任务从开始到结束的时间
      2. 任务的周期
      3. 任务的时间,处理时间更短的任务优先级应该设置更高一些
  6. 例程
    1. /**************** (C) COPYRIGHT  SPT *************
       * 文件名      :main.c
       * 芯片        :STM32F767IGT6
       * 开发工具    :MDK V5.25
       * HAL版本     :STM32Cube_FW_F7_V1.4.0
       * uC/OSIII版本:UCOSIII 3.04
       * 作者        :spt
       * 时间        :2020-04-22
       * 联系方式    :
       * 功能简述    :
       *************************************************/
      #include "includes.h"
      #include "bsp.h"
      
      /*
      *********************************************************************************************************
      *                                         任务控制块TCB
      *********************************************************************************************************
      */
      static OS_TCB   AppTaskStartTCB;    //起始任务控制块
      
      static OS_TCB   AppTaskLedTCB;      //led任务控制块
      static OS_TCB   AppTaskUsartTCB;    //串口任务控制块
      
      /*
      *********************************************************************************************************
      *                                         任务堆栈
      *********************************************************************************************************
      */
      static CPU_STK  AppTaskStartStk[APP_TASK_START_STK_SIZE];   //起始任务堆栈大小
      
      static CPU_STK  AppTaskLedStk[APP_TASK_LED_STK_SIZE];       //led任务堆栈大小
      static CPU_STK  AppTaskUsartStk[APP_TASK_USART_STK_SIZE];   //串口任务堆栈大小
      
      
      /*
      *********************************************************************************************************
      *                                         函数原型
      *********************************************************************************************************
      */
      static void AppTaskStart(void *p_arg);      //起始任务函数
      
      static void AppTaskLed(void *p_arg);        //led任务函数
      static void AppTaskUsart(void *p_arg);      //串口任务函数
      
      /**************************************************
       * 函数名:main()
       * 描述  :主函数入口
       * 输入  :无
       * 输出  :无
       * 返回  :无 
       * 调用  :内部调用 
       **************************************************/
      int main(void)
      {
          OS_ERR err;
          
          CPU_IntDis();   //关闭所有中断
          
          OSInit(&err);   //系统初始化
          
      	/* 创建起始任务 */
          OSTaskCreate((OS_TCB     *)&AppTaskStartTCB,                            //任务控制块地址
                       (CPU_CHAR   *)"App Task Start",                            //任务名称
                       (OS_TASK_PTR ) AppTaskStart,                               //任务函数
                       (void       *) 0,                                          //传递给任务函数(形参p_arg)的实参
                       (OS_PRIO     ) APP_TASK_START_PRIO,                        //任务的优先级
                       (CPU_STK    *)&AppTaskStartStk[0],                         //任务堆栈的基地址
                       (CPU_STK_SIZE) APP_TASK_START_STK_SIZE / 10,               //任务堆栈空间剩下1/10时限制其增长
                       (CPU_STK_SIZE) APP_TASK_START_STK_SIZE,                    //任务堆栈空间(单位:sizeof(CPU_STK))
                       (OS_MSG_QTY  ) 5u,                                         //任务可接收的最大消息数
                       (OS_TICK     ) 0u,                                         //任务的时间片节拍数(0表默认值OSCfg_TickRate_Hz/10)
                       (void       *) 0,                                          //任务扩展(0表不扩展)
                       (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), //任务选项
                       (OS_ERR     *)&err);   
                       
           OSStart(&err);
      }
      
      /**************************************************
       * 函数名:static  void  AppTaskStart (void *p_arg)
       * 描述  :起始任务
       * 输入  :无
       * 输出  :无
       * 返回  :无 
       * 调用  :内部调用 
       **************************************************/
      static  void  AppTaskStart (void *p_arg)
      {
          CPU_INT32U  cpu_clk_freq;
          CPU_INT32U  cnts;
          OS_ERR      err;
      
      
         (void)p_arg;
      
          BSP_Init();                                                 /* Initialize BSP functions                             */
          CPU_Init();                                                 /* Initialize the uC/CPU services                       */
      
          //初始化滴答计数器
          cpu_clk_freq = BSP_CPU_ClkFreq();                           /* Determine SysTick reference freq.                    */
          cnts         = cpu_clk_freq                                 /* Determine nbr SysTick increments                     */
                       / (CPU_INT32U)OSCfg_TickRate_Hz;
          OS_CPU_SysTickInit(cnts);                                   /* Init uC/OS periodic time src (SysTick).              */
          //内存管理,堆内存池,内存池表
          Mem_Init();                                                 /* Initialize memory managment module                   */
      //    Math_Init();                                                /* Initialize mathematical module                       */
      
      
      #if OS_CFG_STAT_TASK_EN > 0u
          OSStatTaskCPUUsageInit(&err);                               /* Compute CPU capacity with no task running            */
      #endif
      
      #ifdef CPU_CFG_INT_DIS_MEAS_EN
          CPU_IntDisMeasMaxCurReset();
      #endif
      
      	/* 创建led任务 */
          OSTaskCreate((OS_TCB     *) &AppTaskLedTCB,                             //任务控制块地址
                       (CPU_CHAR   *) "App Task Led",                             //任务名称
                       (OS_TASK_PTR ) AppTaskLed,                                 //任务函数
                       (void       *) 0,                                          //传递给任务函数(形参p_arg)的实参
                       (OS_PRIO     ) APP_TASK_LED_PRIO,                          //任务的优先级
                       (CPU_STK    *) &AppTaskLedStk[0],                          //任务堆栈的基地址
                       (CPU_STK_SIZE) APP_TASK_LED_STK_SIZE / 10,               //任务堆栈空间剩下1/10时限制其增长
                       (CPU_STK_SIZE) APP_TASK_LED_STK_SIZE,                    //任务堆栈空间(单位:sizeof(CPU_STK))
                       (OS_MSG_QTY  ) 5u,                                         //任务可接收的最大消息数
                       (OS_TICK     ) 0u,                                         //任务的时间片节拍数(0表默认值OSCfg_TickRate_Hz/10)
                       (void       *) 0,                                          //任务扩展(0表不扩展)
                       (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), //任务选项
                       (OS_ERR     *)&err); 
                       
      	/* 创建串口任务 */
          OSTaskCreate((OS_TCB     *) &AppTaskUsartTCB,                             //任务控制块地址
                       (CPU_CHAR   *) "App Task Usart",                             //任务名称
                       (OS_TASK_PTR ) AppTaskUsart,                                 //任务函数
                       (void       *) 0,                                          //传递给任务函数(形参p_arg)的实参
                       (OS_PRIO     ) APP_TASK_USART_PRIO,                          //任务的优先级
                       (CPU_STK    *) &AppTaskUsartStk[0],                          //任务堆栈的基地址
                       (CPU_STK_SIZE) APP_TASK_USART_STK_SIZE / 10,               //任务堆栈空间剩下1/10时限制其增长
                       (CPU_STK_SIZE) APP_TASK_USART_STK_SIZE,                    //任务堆栈空间(单位:sizeof(CPU_STK))
                       (OS_MSG_QTY  ) 5u,                                         //任务可接收的最大消息数
                       (OS_TICK     ) 0u,                                         //任务的时间片节拍数(0表默认值OSCfg_TickRate_Hz/10)
                       (void       *) 0,                                          //任务扩展(0表不扩展)
                       (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), //任务选项
                       (OS_ERR     *)&err);
      
          OSTaskDel(&AppTaskStartTCB, &err);  //删除起始任务             
      }
      
      /*
      *********************************************************************************************************
      *                                         任务函数实现
      *********************************************************************************************************
      */
      /**************************************************
       * 函数名:static void AppTaskLed(void *p_arg)
       * 描述  :led应用
       * 输入  :无
       * 输出  :无
       * 返回  :无 
       * 调用  :内部调用 
       **************************************************/
      static void AppTaskLed(void *p_arg)
      {
          OS_ERR err;
          OS_REG value;
          
          (void)p_arg;
          
          
          for(;;)
          {
              value = OSTaskRegGet(0, 0, &err); //获取自身任务寄存器值
              if(value < 10)
              {
                  OSTaskRegSet(0, 0, ++value, &err); //继续累加任务寄存器值
              }
              else
              {
                  OSTaskRegSet(0, 0, 0, &err);   //将任务寄存器值归0
                  OSTaskResume(&AppTaskUsartTCB, &err);   //恢复串口任务
              }
              
       		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);	//PB1置1
      		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);	//PB0置1
              OSTimeDly ( 500,OS_OPT_TIME_DLY,&err);
              
      		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);	//PB1置0
      		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);	//PB0置0
              OSTimeDly ( 500,OS_OPT_TIME_DLY,&err);        
          }
      }
      /**************************************************
       * 函数名:static void AppTaskUsart(void *p_arg)
       * 描述  :串口打印
       * 输入  :无
       * 输出  :无
       * 返回  :无 
       * 调用  :内部调用 
       **************************************************/
      static void AppTaskUsart(void *p_arg)
      {
          OS_ERR err;
          OS_REG value;
          
          (void)p_arg;
          
          for(;;)
          {
              value = OSTaskRegGet(0, 0, &err); //获取自身任务寄存器值
              if(value < 5)
              {
                  OSTaskRegSet(0, 0, ++value, &err);
              }
              else
              {
                  OSTaskRegSet(0, 0, 0, &err);
                  OSTaskSuspend(0, &err);  //0表挂起自身
              }
              
              printf("灯亮了\r\n");
              OSTimeDly ( 500,OS_OPT_TIME_DLY,&err);
              
      		printf("灯灭了\r\n");
              OSTimeDly ( 500,OS_OPT_TIME_DLY,&err);  
          }
      }
      
      
      /************************ (C) COPYRIGHT  SPT END OF FILE***********************/
      

       

  7. 下载验证
    1.  
  8. 总结
    1. 任务的迁移状态、常用任务函数、延时函数;
  9. 参考资料:
    1. 正点原子《STM32F767 UCOS开发手册》
    2. 野火《uC/OS-III内核应用与开发》
    3. 《嵌入式实时操作系统 uC/OS-III原理及应用(第二版)》
    4. 官方源码
  10. 硬件平台:
    1. 正点原子阿波罗F767
  11. 软件平台:
    1. MDK5.2.5
  12. 库版本:
    1. TM32Cube_FW_F7_V1.4.0
  13. uC/OS-III版本
    1. UCOSIII 3.04
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值