你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

查看: 3372|回复: 1

[STM32L496] 【NUCLEO-L496ZG评测】+ UCOSIII:任务内建信号量和消息队列

[复制链接]

60

主题

2051

回帖

31

蝴蝶豆

版主

最后登录
2020-12-9
发表于 2017-4-18 22:53:51 | 显示全部楼层 |阅读模式
  
   和UCOSII相比UCOSIII做了很多改进和提升,特别是在内核性能方面,比如任务内建信号量和消息队列。UCOSIII任务内建信号量允许ISR或者任务直接发送信号量给其他的任务,这样避免了创建一个中间级的内核对象-信号量只用来标记一个单独的任务,同样UCOSIII任务内建的消息队列也可以从ISR或者任务直接发送消息给另外一个任务。
  
   通过分析UCOSIII的任务级的时基处理代码可以很好的了解任务内建信号量和消息队列的用法。在初始化OS的时候会定一个事件任务,该任务的优先级默认为1(数字越低优先级越高)。通常情况下UCOSIII第一次调度会进入这个任务。


   
  1. OSTaskCreate((OS_TCB     *)&OSTickTaskTCB,
  2.                  (CPU_CHAR   *)((void *)"uC/OS-III Tick Task"),
  3.                  (OS_TASK_PTR )OS_TickTask,
  4.                  (void       *)0,
  5.                  (OS_PRIO     )OSCfg_TickTaskPrio,
  6.                  (CPU_STK    *)OSCfg_TickTaskStkBasePtr,
  7.                  (CPU_STK_SIZE)OSCfg_TickTaskStkLimit,
  8.                  (CPU_STK_SIZE)OSCfg_TickTaskStkSize,
  9.                  (OS_MSG_QTY  )0u,
  10.                  (OS_TICK     )0u,
  11.                  (void       *)0,
  12.                  (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR | OS_OPT_TASK_NO_TLS),
  13.                  (OS_ERR     *)p_err);
复制代码
时基任务的代码如下:任务信号量pend的调用直接使用OSTaskSemPend()即可。和创建内核信号量的pend函数相比省略了第一个信号量定义的参数。在进入该函数之后如果没有请求到信号量就会被阻塞。

  1. void  OS_TickTask (void  *p_arg)
  2. {
  3.     OS_ERR  err;
  4.     CPU_TS  ts_delta;
  5.     CPU_TS  ts_delta_dly;
  6.     CPU_TS  ts_delta_timeout;
  7.     CPU_SR_ALLOC();


  8.     (void)&p_arg;                                               /* Prevent compiler warning                             */

  9.     while (DEF_ON) {
  10.         (void)OSTaskSemPend((OS_TICK  )0,
  11.                             (OS_OPT   )OS_OPT_PEND_BLOCKING,
  12.                             (CPU_TS  *)0,
  13.                             (OS_ERR  *)&err);                   /* Wait for signal from tick interrupt                  */
  14.         if (err == OS_ERR_NONE) {
  15.             OS_CRITICAL_ENTER();
  16.             OSTickCtr++;                                        /* Keep track of the number of ticks                    */
  17. #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
  18.             TRACE_OS_TICK_INCREMENT(OSTickCtr);                 /* Record the event.                                    */
  19. #endif
  20.             OS_CRITICAL_EXIT();
  21.             ts_delta_dly     = OS_TickListUpdateDly();
  22.             ts_delta_timeout = OS_TickListUpdateTimeout();
  23.             ts_delta         = ts_delta_dly + ts_delta_timeout; /* Compute total execution time of list updates         */
  24.             if (OSTickTaskTimeMax < ts_delta) {
  25.                 OSTickTaskTimeMax = ts_delta;
  26.             }
  27.         }
  28.     }
  29. }
复制代码
在时基中断函数中OSTimeTick()进行了时基任务的信号量post,同时也进行了软件定时器任务型号的post,这个函数驱动了UCOSIII的调度和软件定时器。

  1. void  OSTimeTick (void)
  2. {
  3.     OS_ERR  err;

  4.     OSTimeTickHook();                                       /* Call user definable hook                               */


  5.    (void)OSTaskSemPost((OS_TCB *)&OSTickTaskTCB,            /* Signal tick task                                       */
  6.                        (OS_OPT  ) OS_OPT_POST_NONE,
  7.                        (OS_ERR *)&err);

  8.    (void)err;

  9. #if OS_CFG_SCHED_ROUND_ROBIN_EN > 0u
  10.     OS_SchedRoundRobin(&OSRdyList[OSPrioCur]);
  11. #endif

  12. #if OS_CFG_TMR_EN > 0u
  13.     OSTmrUpdateCtr--;
  14.     if (OSTmrUpdateCtr == (OS_CTR)0u) {
  15.         OSTmrUpdateCtr = OSTmrUpdateCnt;
  16.         OSTaskSemPost((OS_TCB *)&OSTmrTaskTCB,              /* Signal timer task                                      */
  17.                       (OS_OPT  ) OS_OPT_POST_NONE,
  18.                       (OS_ERR *)&err);
  19.     }
  20. #endif

  21. }
复制代码
1、任务内建信号量


我们将前面的创建的内核信号量的例子修改为使用任务的信号量来测试。


  在任务中直接调用任务的信号量pend函数:
TIM截图20170418223209.png
在按键函数中post函数中:
TIM截图20170418223144.png
信号量的post和pend地方都和之前的一样只是调用的函数略有不同。
测试如下:

0.gif

2、任务内建消息队列
同样的将之前的消息队列的例子稍加修改即可使用任务内建消息队列进行传输。
消息队列的post和pend分别如下:


TIM截图20170418224052.png

post 消息

TIM截图20170418224121.png

测试如下。消息队列超过12个也会提示内存不足。

1.gif


对于同步单个任务的信号量或者和单个任务进行通信的消息队列,使用任务内建的信号量和消息队列非常的简单方便。除此之外UCOSIII比UCOSII还有很多的提示,通过研究UCOSIII的源代码我们可以更加详细的了解这种不同进而更加的熟练的掌握这个OS。


测试代码:

UCOSIII-Task-Sem.rar (1.49 MB, 下载次数: 28)
<
回复

使用道具 举报

76

主题

683

回帖

17

蝴蝶豆

论坛元老

最后登录
2020-11-19
发表于 2017-4-19 10:07:43 | 显示全部楼层
很好的帖子,先标记下,顶起来。
回复 支持 反对

使用道具 举报

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版