μC/OSIII——任务通信(消息传递)

使用情况

  一个任务或者中断服务程序与另一个任务交流信息

使用方法

  消息队列服务函数的实现代码在os_q.c文件中,在编译时,将os_cfg.h文件中的配置常数OS_CFG_Q_EN设为1就可启用这些服务函数。

  常用消息队列的服务函数有:

  • OSQCreate()       创建消息队列
  • OSQPend()          等待消息队列中的信息
  • OSQPost()           向消息队列中发送消息

void  OSQCreate (OS_Q        *p_q,                    指向消息队列控制块的指针
                          CPU_CHAR    *p_name,           指向字符串的指针——消息队列的名字
                          OS_MSG_QTY   max_qty,        指定消息队列的最大长度(必须为非零)
                          OS_ERR      *p_err)                该函数返回的错误码

void  *OSQPend (OS_Q         *p_q,                    指向消息队列控制块的指针
                         OS_TICK       timeout,              指定等待消息的超时时间(时钟节拍数)
                         OS_OPT        opt,                    
                         OS_MSG_SIZE  *p_msg_size,   接受的消息的大小(字节数,可用sizeof获取)
                         CPU_TS       *p_ts,                   指向一个时间戳的指针
                         OS_ERR       *p_err)                 该函数返回的错误码

opt  OS_OPT_PEND_BLOCKING  阻塞模式(任务挂起等待该对象)

OS_OPT_PEND_NON_BLOCKING  非阻塞模式(没有任何消息存在时,任务直接返回)

void  OSQPost (OS_Q         *p_q,                        指向消息队列控制块的指针  
                       void         *p_void,                      实际发送的消息内容
                       OS_MSG_SIZE   msg_size,           设定消息的大小(字节数)
                       OS_OPT        opt,                  
                       OS_ERR       *p_err)                    该函数返回的错误码

opt  OS_OPT_POST_FIFO   待发送的消息保存在消息队列的末尾(FIFO)

OS_OPT_POST_LIFO   待发送的消息保存在消息队列的开头(LIFO)

+OS_OPT_POST_ALL  向所有等待该消息队列的任务发送消息(否则只发送到最高级)

+OS_OPT_POST_NO_SCHED 禁止在本函数内执行任务调度操作

使用实例

  1 #define  APP_TASK_START_PRIO                               4u
  2 #define  APP_TASK_1_PRIO                                   6u
  3 #define  APP_TASK_2_PRIO                                   5u
  4
  5
  6 #define  APP_TASK_START_STK_SIZE                         256u
  7 #define  APP_TASK_1_STK_SIZE                             256u
  8 #define  APP_TASK_2_STK_SIZE                             256u
  9
 10
 11 static  OS_TCB   AppTaskStartTCB;
 12 static  OS_TCB   AppTask1TCB;
 13 static  OS_TCB   AppTask2TCB;
 14
 15
 16 static  OS_Q   MY_Q;
 17
 18
 19 static  CPU_STK  AppTaskStartStk[APP_TASK_START_STK_SIZE];
 20 static  CPU_STK  AppTask1Stk[APP_TASK_1_STK_SIZE];
 21 static  CPU_STK  AppTask2Stk[APP_TASK_2_STK_SIZE];
 22
 23
 24 static  void  AppTaskStart(void  *p_arg);
 25 void AppTask1(void *p_arg);
 26 void AppTask2(void *p_arg);
 27
 28
 29 void *BLOCK1 = "Task1 is comunicating with Task2";
 30 void *BLOCK2;
 31
 32
 33
 34
 35 int  main (void)
 36 {
 37     OS_ERR  err;
 38
 39
 40
 41
 42     OSInit(&err);
 43
 44
 45     OSQCreate((OS_Q     *)&MY_Q,
 46               (CPU_CHAR *)"MY_Q",
 47               (OS_MSG_QTY)10,
 48               (OS_ERR   *)&err);
 49
 50
 51     OSTaskCreate((OS_TCB     *)&AppTaskStartTCB,
 52                  (CPU_CHAR   *)"App Task Start",
 53                  (OS_TASK_PTR ) AppTaskStart,
 54                  (void       *) 0,
 55                  (OS_PRIO     ) APP_TASK_START_PRIO,
 56                  (CPU_STK    *)&AppTaskStartStk[0],
 57                  (CPU_STK_SIZE) APP_TASK_START_STK_SIZE / 10u,
 58                  (CPU_STK_SIZE) APP_TASK_START_STK_SIZE,
 59                  (OS_MSG_QTY  ) 0u,
 60                  (OS_TICK     ) 0u,
 61                  (void       *) 0,
 62                  (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
 63                  (OS_ERR     *)&err);
 64
 65
 66     OSStart(&err);
 67 }
 68
 69
 70 static  void  AppTaskStart (void *p_arg)
 71 {
 72     OS_ERR  err;
 73
 74
 75
 76
 77    (void)p_arg;
 78
 79
 80     CPU_Init();
 81
 82
 83     OSTaskCreate((OS_TCB     *)&AppTask1TCB,
 84                 (CPU_CHAR   *)"AppTask1",
 85                 (OS_TASK_PTR)AppTask1,
 86                 (void       *)0,
 87                 (OS_PRIO)APP_TASK_1_PRIO,
 88                 (CPU_STK    *)&AppTask1Stk[0],
 89                 (CPU_STK_SIZE)APP_TASK_1_STK_SIZE / 10u,
 90                 (CPU_STK_SIZE)APP_TASK_1_STK_SIZE,
 91                 (OS_MSG_QTY)0u,
 92                 (OS_TICK)0u,
 93                 (void       *)0,
 94                 (OS_OPT)(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
 95                 (OS_ERR     *)&err);
 96     OSTaskCreate((OS_TCB     *)&AppTask2TCB,
 97                 (CPU_CHAR   *)"AppTask2",
 98                 (OS_TASK_PTR)AppTask2,
 99                 (void       *)0,
100                 (OS_PRIO)APP_TASK_2_PRIO,
101                 (CPU_STK    *)&AppTask2Stk[0],
102                 (CPU_STK_SIZE)APP_TASK_2_STK_SIZE / 10u,
103                 (CPU_STK_SIZE)APP_TASK_2_STK_SIZE,
104                 (OS_MSG_QTY)0u,
105                 (OS_TICK)0u,
106                 (void       *)0,
107                 (OS_OPT)(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
108                 (OS_ERR     *)&err);
109 }
110
111
112 void AppTask1(void *p_arg)
113 {
114     OS_ERR  err;
115
116
117     (void)p_arg;
118
119
120     while (DEF_ON){
121         APP_TRACE_DBG(("Task1 is running...\n\r"));
122         OSQPost((OS_Q      *)&MY_Q,
123                 (void      *)BLOCK1,
124                 (OS_MSG_SIZE)sizeof(BLOCK1),
125                 (OS_OPT     )OS_OPT_POST_FIFO,
126                 (OS_ERR    *)&err);
127         OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_DLY, &err);
128     }
129 }
130
131
132 void AppTask2(void *p_arg)
133 {
134     OS_ERR  err;
135
136
137     OS_MSG_SIZE size;
138     CPU_TS ts;
139
140
141     (void)p_arg;
142
143
144     while (DEF_ON){
145         BLOCK2=OSQPend((OS_Q       *)&MY_Q,
146                        (OS_TICK     )0,
147                        (OS_OPT      )OS_OPT_PEND_BLOCKING,
148                        (OS_MSG_SIZE*)&size,
149                        (CPU_TS      )&ts,
150                        (OS_ERR     *)&err);
151         APP_TRACE_DBG(("Task2 is running...\n\r"));
152         APP_TRACE_DBG(("%s...\n\r",BLOCK2));
153         OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_DLY, &err);
154     }
155 }

实验结果

时间: 2024-10-12 23:15:18

μC/OSIII——任务通信(消息传递)的相关文章

3D 视角看 Go 并发编程

主题:3D 视角看 Go 并发编程 Overview 并发编程综述 Goroutine Channel & Select & waitGroup 消息传递模式 可视化工具 GoTrace 主讲师:PP 先后在百度.第四范式.蚂蚁金服工作,百度 Go Good Coder, 对分布式计算.离线/实时大数据处理有丰富的实战经验.乐于分享自己的技术和学习心得. 一.并发编程综述 串行执行 并发与并行 多核时代的并发编程 左图:p1, p2, p3 这 3 个线程运行在单核上,分时复用 CPU,是

283.软件体系结构描述

4.6 使用“4+1”模型描述软件体系结构 对于同一座建筑,住户.建筑师.内部装修人员和电气工程师有各自的视角.这些视角反映了建筑物的不同方面,但它们彼此都有内在的联系,而且合起来形成了建筑物的总体结构. 软件体系结构反映了软件系统的总的结构,它和建筑物一样,存在不同的角度来反映系统的体系结构. 当面对一个复杂的系统时,必须从多个角度来考虑问题.在处理体系结构时我们通常只考虑系统功能方面的需求,而实际上除了功能,物理分布.过程通信和同步等也必须在体系结构一级加以考虑.这些来自不同方面的需求就形成

The All-in-One Note

基础 操作系统 I/O 模型 阻塞式 I/O 模型(blocking I/O) 描述:在阻塞式 I/O 模型中,应用程序在从调用 recvfrom 开始到它返回有数据报准备好这段时间是阻塞的,recvfrom 返回成功后,应用进程开始处理数据报 优点:程序简单,在阻塞等待数据期间进程/线程挂起,基本不会占用 CPU 资源 缺点:每个连接需要独立的进程/线程单独处理,当并发请求量大时为了维护程序,内存.线程切换开销较大,这种模型在实际生产中很少使用 非阻塞式 I/O 模型(non-blocking

浏览器插件开发-manifest文件解读

调研资料 manifest.json 官方文档 Chrome Extension API 360浏览器的插件文档中文, 虽然内核差不多但是不一定与 Chrome api 一致, 可以作为参考 Chrome 官方案例库 案例 如何实现网页和Chrome插件之间的通信 消息传递 manifest.json 配置说明 manifest.json 用于描述 Chrome 插件的源数据,配置信息等,基本内容如下 { "name": "名称", "descriptio

进程的通信:共享存储、消息传递和管道通信

进程通信是指进程之间的信息交换.PV操作是低级通信方式,高级通信方式是指以较高的效率传输大量数据的通信方式.高级通信方法主要有以下三个类. 共享存储 在通信的进程之间存在一块可直接访问的共享空间,通过对这片共享空间进行写/读操作实现进程之间的信息交换.在对共享空间进行写/读操作时,需要使用同步互斥工具(如P操作.V操作),对共享空间的写/读进行控制.共享存储又分为两种:低级方式的共享是基于数据结构的共享:高级方式则是基于存储区的共享.操作系统只负责为通信进程提供可共享使用的存储空间和同步互斥工具

架构设计:系统间通信(32)——其他消息中间件及场景应用(下2)

(接上文<架构设计:系统间通信(31)--其他消息中间件及场景应用(下1)>) 5-3.解决方案二:改进半侵入式方案 5-3-1.解决方法一的问题所在 方案一并不是最好的半侵入式方案,却容易理解架构师的设计意图:至少做到业务级隔离.方案一最大的优点在于日志采集逻辑和业务处理逻辑彼此隔离,当业务逻辑发生变化的时候,并不会影响日志采集逻辑. 但是我们能为方案一列举的问题却可以远远多于方案一的优点: 需要为不同开发语言分别提供客户端API包.上文中我们介绍的示例使用JAVA语言,于是 事件/日志采集

多线程的通信方法

转自 http://www.cnblogs.com/mengyan/archive/2012/08/30/2664607.html 一.进程通信方法 在说明线程通信前,有必要对进程通信进行说明: 进程间通信的方法主要有以下几种:  (1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信.  (2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关 系 进程间的通信.命名管道

angularJS的controller之间如何正确的通信

AngularJS中的controller是个函数,用来向视图的作用域($scope)添加额外的功能,我们用它来给作用域对象设置初始状态,并添加自定义行为. 当我们在创建新的控制器时,angularJS会帮我们生成并传递一个新的$scope对象给这个controller,在angularJS应用的中的任何一个部分,都有父级作用域的存在,顶级就是ng-app所在的层级,它的父级作用域就是$rootScope. 每个$scope的$root指向$rootScope, $cope.$parent指向父

Android:使用Handler在线程之间通信

概述 假设一个情景,在一个应用程序中,要完成一个比较复杂.耗时较长的计算任务,如果将这个任务直接在主线程中开始,那么用户界面就会停止对用户操作的响应,而去解决这个计算任务,直到任务完成. 显然,这不是我们想要的结果.那么就需要用到多线程来解决这个问题. 但是新的问题又出现了,在C#和Android中,子线程是不能直接修改用户界面的数据的.也就是说,子线程计算出的结果,不能直接在子线程中让它显示在用户界面上.那么就需要把数据首先传递给主线程,让主线程去修改用户界面. Handler就是为了解决这个