From fcba94ac5c4ade03ece0754e5bd895cf5b63b3df Mon Sep 17 00:00:00 2001 From: mculover666 <2412828003@qq.com> Date: Fri, 17 Jul 2020 17:56:21 +0800 Subject: [PATCH] add cmsis-rtos-api use guide --- doc/23.CMSIS_RTOS_API_Use_Guide.md | 804 +++++++++++++++++++++++++++++ 1 file changed, 804 insertions(+) create mode 100644 doc/23.CMSIS_RTOS_API_Use_Guide.md diff --git a/doc/23.CMSIS_RTOS_API_Use_Guide.md b/doc/23.CMSIS_RTOS_API_Use_Guide.md new file mode 100644 index 00000000..334d4745 --- /dev/null +++ b/doc/23.CMSIS_RTOS_API_Use_Guide.md @@ -0,0 +1,804 @@ +# 1. CMSIS-RTOS API是什么 +CMSIS-RTOS是用于实时操作系统(RTOS)的一层通用API,它提供了一套标准的API接口,可以移植到各种各样的RTOS上,使得上层的软件、中间件、库以及其他组件在不同的RTOS之上都可以正常工作。 + +这套API表现为两个文件:cmsis-os.h和cmsis-os.c,在TencentOS-tiny中如下。 + +- 基于TencentOS-tiny的CMSIS-RTOS API v1.02版本实现: + - `cmsis_os.h` + - `cmsis_os.c` +- 基于TencentOS-tiny的CMSIS-RTOS API v2.1.3版本实现: + - `cmsis_os2.h` + - `cmsis_os2.c` + +CMSIS-RTOS API的整体架构如下图: +![](https://img-blog.csdnimg.cn/20200717092428321.png) +CMSIS-RTOS API官方参考文档链接:[https://www.keil.com/pack/doc/CMSIS/RTOS/html/index.html](https://www.keil.com/pack/doc/CMSIS/RTOS/html/index.html/) + +# 2. CMSIS-RTOS API列表 +下面列出了 CMSIS-RTOS API v1.02 版本提供的所有API。 + +CMSIS-RTOS 所有API使用的错误码(cmsis-os.h): +```c +typedef enum { + osOK = 0, ///< function completed; no error or event occurred. + osEventSignal = 0x08, ///< function completed; signal event occurred. + osEventMessage = 0x10, ///< function completed; message event occurred. + osEventMail = 0x20, ///< function completed; mail event occurred. + osEventTimeout = 0x40, ///< function completed; timeout occurred. + osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. + osErrorResource = 0x81, ///< resource not available: a specified resource was not available. + osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. + osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. + osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. + osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. + osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorValue = 0x86, ///< value of a parameter is out of range. + osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. + os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. +} osStatus; +``` +CMSIS-RTOS API一些可选项控制是否开启(cmsis-os.h): +```c +#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available +#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available +#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available +#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available +#define osFeature_Signals 0 ///< maximum number of Signal Flags available per thread +#define osFeature_Semaphore 30 ///< maximum count for \ref osSemaphoreCreate function +#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available +#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available +``` + + +## 2.1. 内核信息和控制(Kernel information and control) + +|API|描述| +|:---:|:---:| +|osKernelInitialize|初始化RTOS内核| +|osKernelStart|启动RTOS内核| +|osKernelRunning|Query if the RTOS kernel is running| +|osKernelSysTick (可选)|Get RTOS kernel system timer counter| +|osKernelSysTickFrequency (可选)|RTOS kernel system timer frequency in Hz| +|osKernelSysTickMicroSec (可选)|Convert microseconds value to RTOS kernel system timer value| + +- `osKernelInitialize` +```c +osStatus osKernelInitialize(void); +``` +返回值:status code + +- `osKernelStart` +```c +osStatus osKernelStart(void); +``` +返回值:status code + +- `osKernelRunning` +```c +int32_t osKernelRunning(void); +``` +返回值:0表示RTOS未启动,1表示RTOS已经启动 + +- `osKernelSysTick` +```c +uint32_t osKernelSysTick(void); +``` +返回值:RTOS内核系统当前的时间 + +## 2.2. 线程管理(Thread management) + +>`##`连接符的作用是连接两个字符串,合为一个字符串。 + +CMSIS-RTOS API 存放线程参数管理的结构体如下: +```c +typedef struct os_thread_def { + char *name; ///< Thread name + os_pthread pthread; ///< start address of thread function + osPriority tpriority; ///< initial thread priority + uint32_t instances; ///< maximum number of instances of that thread function + k_stack_t *stackbase; ///< base address of task + uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size + k_timeslice_t timeslice; ///< timeslice + k_task_t *task; +} osThreadDef_t; +``` + +CMSIS-RTOS API 定义线程的宏如下: +```c +#define osThreadDef(name, priority, instances, stacksz) \ + k_task_t task_handler_##name; \ + k_stack_t task_stack_##name[(stacksz)]; \ + const osThreadDef_t os_thread_def_##name = \ + { #name, (os_pthread)(name), (osPriority)(priority), (instances), \ + (&((task_stack_##name)[0])), (stacksz), ((k_timeslice_t)0u), (&(task_handler_##name)) } +``` +>宏定义中的 instances 表示基于此任务参数,创建出几个任务实例,比如instances为2,则会创建出两个任务。 + +CMSIS-RTOS API定义的获取线程参数结构体的宏如下: +```c +#define osThread(name) \ + &os_thread_def_##name +``` + +管理线程参数的API如下: + +|API|描述| +|:---:|:---:| +|osThreadCreate|创建线程并开始执行| +|osThreadTerminate|停止线程执行| +|osThreadYield|线程主动让出| +|osThreadGetID|获取当前正在运行线程的ID| +|osThreadSetPriority|改变线程优先级| +|osThreadGetPriority|获取线程优先级| + +- `osThreadCreate` +```c +osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument); +``` +其中osThreadId被定义为k_task_t指针类型: +```c +typedef k_task_t *osThreadId; +``` +返回值:TencentOS-tiny中的任务控制块类型指针。 + +- `osThreadTerminate` +```c +osStatus osThreadTerminate(osThreadId thread_id); +``` +返回值:osStatus + +- `osThreadYield` +```c +osStatus osThreadYield(void); +``` +返回值:osStatus + +- `osThreadGetID` +```c +osThreadId osThreadGetId(void); +``` +- `osThreadSetPriority` +```c +osStatus osThreadSetPriority(osThreadId thread_id, osPriority priority); +``` + +- `osThreadGetPriority` +```c +osPriority osThreadGetPriority(osThreadId thread_id); +``` + +>使用时需要特别注意,在TencentOS-tiny中,调用CMSIS-RTOS API提供的优先级选项设置之后,实际设置的任务值是不同的。 + +CMSIS-RTOS API提供的线程优先级宏定义如下: +```c +typedef enum { + osPriorityIdle = -3, ///< priority: idle (lowest) + osPriorityLow = -2, ///< priority: low + osPriorityBelowNormal = -1, ///< priority: below normal + osPriorityNormal = 0, ///< priority: normal (default) + osPriorityAboveNormal = +1, ///< priority: above normal + osPriorityHigh = +2, ///< priority: high + osPriorityRealtime = +3, ///< priority: realtime (highest) + osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority +} osPriority; +``` +在TecentOS-tiny中实现的时候进行了转化: +```c +static k_prio_t priority_cmsis2knl(osPriority prio) +{ + if (prio == osPriorityError) { + return K_TASK_PRIO_INVALID; + } + + return (k_prio_t)(3 - prio); +} + +static osPriority priority_knl2cmsis(k_prio_t prio) +{ + return (osPriority)(3 - prio); +} +``` +比如创建线程时设置为 osPriorityNormal=0,则**实际设置的任务优先级为3**。 + +## 2.3. 通用等待函数 +CMSIS-RTOS提供的等待函数API如下: + +|API|描述| +|:---:|:---:| +|osDelay|等待指定的时间| +|osWait(可选)|等待信号、消息、邮箱的某个事件| + +- `osDelay` +```c +osStatus osDelay(uint32_t millisec); +``` +返回值:osStatus。 + +## 2.4. 软件定时器管理 +CMSIS-RTOS API提供的存储定时器参数的结构体如下: +```c +typedef struct os_timer_def { + os_ptimer cb; ///< start address of a timer function + k_timer_t *timer; +} osTimerDef_t; +``` + +CMSIS-RTOS API提供的定义一个软件定时器的宏定义如下: +```c +#define osTimerDef(name, function) \ + k_timer_t timer_handler_##name; \ + const osTimerDef_t os_timer_def_##name = \ + { (os_ptimer)(function), (&(timer_handler_##name)) } +``` +CMSIS-RTOS API定义的获取软件定时器参数结构体的宏如下: +```c +#define osTimer(name) \ + &os_timer_def_##name +``` +CMSIS-RTOS API提供的软件定时器管理API如下: + +|API|描述| +|:---:|:---:| +|osTimerCreate|创建一个软件定时器| +|osTimerStart|启动软件定时器| +|osTimerStop|停止软件定时器| +|osTimerDelete|删除软件定时器| + +- `osTimerCreate` +```c +osTimerId osTimerCreate(const osTimerDef_t *timer_def, os_timer_type type, void *argument); +``` +其中osTimerId被定义为k_timer_t指针类型: +```c +typedef k_timer_t *osTimerId; +``` +type参数为 os_timer_type 类型,表示软件定时器的类型为单次触发或者周期触发: +```c +typedef enum { + osTimerOnce = 0, ///< one-shot timer + osTimerPeriodic = 1 ///< repeating timer +} os_timer_type; +``` + +- `osTimerStart` +```c +osStatus osTimerStart(osTimerId timer_id, uint32_t millisec); +``` +返回值:osStatus。 + +- `osTimerStop` +```c +osStatus osTimerStop(osTimerId timer_id) +``` +返回值:osStatus。 + +- `osTimerDelete` +```c +osStatus osTimerDelete(osTimerId timer_id); +``` +返回值:osStatus。 + +## 2.5. 信号量管理 +CMSIS-RTOS API提供的存储信号量参数的结构体如下: +```c +typedef struct os_semaphore_def { + uint32_t dummy; ///< dummy value. + k_sem_t *sem; +} osSemaphoreDef_t; +``` + +CMSIS-RTOS API提供的定义一个信号量的宏定义如下: +```c +#define osSemaphoreDef(name) \ + k_sem_t sem_handler_##name; \ + const osSemaphoreDef_t os_semaphore_def_##name = { 0, (&(sem_handler_##name)) } +``` +CMSIS-RTOS API定义的获取信号量参数结构体的宏如下: +```c +#define osSemaphore(name) \ + &os_semaphore_def_##name +``` +CMSIS-RTOS API提供的信号量管理API如下: + +|API|描述| +|:---:|:---:| +|osSemaphoreCreate|创建一个信号量| +|osSemaphoreWait|等待信号量| +|osSemaphoreRelease|释放信号量| +|osSemaphoreDelete|删除信号量| + +- `osSemaphoreCreate` +```c +osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def, int32_t count); +``` +其中 osSemaphoreId 被定义为k_sem_t指针类型: +```c +typedef k_sem_t *osSemaphoreId; +``` + +- `osSemaphoreWait` +```c +int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec); +``` +返回值:int32_t ,正常返回当前count数,失败返回-1。 + +如果需要阻塞延时,参数应该设置为CMSIS-RTOS API提供的宏定义 osWaitForever : +```c +#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value +``` + +- `osSemaphoreRelease` +```c +osStatus osSemaphoreRelease(osSemaphoreId semaphore_id); +``` +返回值:osStatus。 + +- `osSemaphoreDelete` +```c +osStatus osSemaphoreDelete(osSemaphoreId semaphore_id); +``` +返回值:osStatus。 + +## 2.6. 互斥锁管理 +CMSIS-RTOS API提供的存储互斥锁参数的结构体如下: +```c +typedef struct os_mutex_def { + uint32_t dummy; ///< dummy value. + k_mutex_t *mutex; +} osMutexDef_t; +``` + +CMSIS-RTOS API提供的定义一个互斥锁的宏定义如下: +```c +#define osMutexDef(name) \ + k_mutex_t mutex_handler_##name; \ + const osMutexDef_t os_mutex_def_##name = { 0, (&(mutex_handler_##name)) } +``` +CMSIS-RTOS API定义的获取互斥锁参数结构体的宏如下: +```c +#define osMutex(name) \ + &os_mutex_def_##name +``` +CMSIS-RTOS API提供的互斥锁管理API如下: + +|API|描述| +|:---:|:---:| +|osMutexCreate|创建一个互斥锁| +|osMutexWait|等待获取互斥锁| +|osMutexRelease|释放互斥锁| +|osMutexDelete|删除互斥锁| + +- `osMutexCreate` +```c +osMutexId osMutexCreate(const osMutexDef_t *mutex_def); +``` +其中 osMutexId 被定义为k_mutex_t指针类型: +```c +typedef k_mutex_t *osMutexId; +``` + +- `osMutexWait` +```c +osStatus osMutexWait(osMutexId mutex_id, uint32_t millisec); +``` +返回值:osStatus 。 + +如果需要阻塞延时,参数应该设置为CMSIS-RTOS API提供的宏定义 osWaitForever : +```c +#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value +``` + +- `osMutexRelease` +```c +osStatus osMutexRelease(osMutexId mutex_id); +``` +返回值:osStatus。 + +- `osMutexDelete` +```c +osStatus osMutexDelete(osMutexId mutex_id); +``` +返回值:osStatus。 + +## 2.7. 静态内存池管理 +CMSIS-RTOS API提供的存储静态内存池参数的结构体如下: +```c +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + void *pool; ///< pointer to memory for pool + k_mmblk_pool_t *mmblk_pool; ///< memory blk pool handler +} osPoolDef_t; +``` + +CMSIS-RTOS API提供的定义一个互斥锁的宏定义如下: +```c +#define osPoolDef(name, no, type) \ + k_mmblk_pool_t mmblk_pool_handler_##name; \ + uint8_t mmblk_pool_buf_##name[(no) * sizeof(type)]; \ + const osPoolDef_t os_pool_def_##name = \ + { (no), sizeof(type), (&((mmblk_pool_buf_##name)[0])), (&(mmblk_pool_handler_##name)) } +``` +CMSIS-RTOS API定义的获取互斥锁参数结构体的宏如下: +```c +#define osPool(name) \ + &os_pool_def_##name +``` +CMSIS-RTOS API提供的互斥锁管理API如下: + +|API|描述| +|:---:|:---:| +|osPoolCreate|创建一块固定大小的静态内存池| +|osPoolAlloc|申请分配内存| +|osPoolCAlloc|申请分配一块内存并全部初始化为0| +|osPoolFree|申请回收内存| + +- `osPoolCreate` +```c +osPoolId osPoolCreate(const osPoolDef_t *pool_def); +``` +其中 osPoolId 被定义为 k_mmblk_pool_t 指针类型: +```c +typedef k_mmblk_pool_t *osPoolId; +``` + +- `osPoolAlloc` +```c +void *osPoolAlloc(osPoolId pool_id); +``` + +- `osPoolCAlloc` +```c +void *osPoolCAlloc(osPoolId pool_id); +``` + +- `osPoolFree` +```c +osStatus osPoolFree(osPoolId pool_id, void *block); +``` +返回值:osStatus。 + +## 2.8. 消息队列管理 +CMSIS-RTOS API提供的存储消息队列参数的结构体如下: +```c +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for messages + k_msg_q_t *queue; ///< queue handler +} osMessageQDef_t; +``` + +CMSIS-RTOS API提供的定义一个消息队列的宏定义如下: +```c +#define osMessageQDef(name, queue_sz, type) \ + k_msg_q_t msg_q_handler_##name; \ + const osMessageQDef_t os_messageQ_def_##name = \ + { (queue_sz), sizeof(type), NULL, (&(msg_q_handler_##name)) } +``` +CMSIS-RTOS API定义的获取消息队列参数结构体的宏如下: +```c +#define osMessageQ(name) \ + &os_messageQ_def_##name +``` +CMSIS-RTOS API提供的消息队列管理API如下: + +|API|描述| +|:---:|:---:| +|osMessageCreate|初始化一个消息队列| +|osMessagePut|向消息队列中加入数据| +|osMessageGet|从消息队列中取出数据| + +- `osMessageCreate` +```c +osMessageQId osMessageCreate(const osMessageQDef_t *queue_def, osThreadId thread_id); +``` +其中 osMessageQId 被定义为 k_msg_q_t 指针类型: +```c +typedef k_msg_q_t *osMessageQId; +``` + +- `osMessagePut` +```c +osStatus osMessagePut(osMessageQId queue_id, uint32_t info, uint32_t millisec); +``` +返回值:osStatus 。 + +>因为TencentOS-tiny中消息队列实现机制的不同,此API中的 millisec 参数未用到。 + +- `osMessageGet` +```c +osEvent osMessageGet(osMessageQId queue_id, uint32_t millisec); +``` +返回值:osEvent ,其中包含了事件信息和错误码,以及消息队列收到的值。 + + +如果需要阻塞延时,参数应该设置为CMSIS-RTOS API提供的宏定义 osWaitForever : +```c +#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value +``` + +# 3. 使用示例 +## 3.1. 任务创建示例 +```c +#include + +void task1_entry(void *arg) +{ + while(1) + { + printf("task1 is running...\r\n"); + osDelay(1000); + } +} +osThreadDef(task1_entry, osPriorityNormal, 1, 512); + +void task2_entry(void *arg) +{ + + while(1) + { + printf("task2 is running...\r\n"); + osDelay(1000); + } +} +osThreadDef(task2_entry, osPriorityNormal, 1, 512); + +void application_entry(void *arg) +{ + + osThreadCreate(osThread(task1_entry), NULL); + osThreadCreate(osThread(task2_entry), NULL); + + return; +} +``` +任务运行结果如下: +```c +task1 is running... +task2 is running... +task1 is running... +task2 is running... +task1 is running... +task2 is running... +``` + +## 3.2. 软件定时器使用示例 +```c +#include + +void timer1_cb(void *arg) +{ + printf("timer1 is timeout!\r\n"); +} + +void timer2_cb(void *arg) +{ + printf("timer2 is timeout!\r\n"); +} + +osTimerDef(timer1, timer1_cb); +osTimerDef(timer2, timer2_cb); + +void application_entry(void *arg) +{ + osTimerId timer1; + osTimerId timer2; + + timer1 = osTimerCreate(osTimer(timer1), osTimerOnce, NULL); + timer2 = osTimerCreate(osTimer(timer2), osTimerPeriodic, NULL); + + osTimerStart(timer1, 5000); + osTimerStart(timer2, 1000); + + return; +} +``` +运行结果如下: +```c +timer2 is timeout! +timer2 is timeout! +timer2 is timeout! +timer2 is timeout! +timer1 is timeout! +timer2 is timeout! +timer2 is timeout! +timer2 is timeout! +timer2 is timeout! +``` + +## 3.3. 信号量使用示例 +```c +#include + +osSemaphoreId sync_sem_id; +osSemaphoreDef(sync_sem); + +void task1_entry(void *arg) +{ + while(1) + { + printf("task1 is waiting sem forever...\r\n"); + osSemaphoreWait(sync_sem_id, osWaitForever); + printf("task1 get sem!\r\n"); + } +} +osThreadDef(task1_entry, osPriorityNormal, 1, 512); + +void task2_entry(void *arg) +{ + + while(1) + { + printf("task2 will release a sem...\r\n"); + osSemaphoreRelease(sync_sem_id); + osDelay(1000); + } +} +osThreadDef(task2_entry, osPriorityNormal, 1, 512); + +void application_entry(void *arg) +{ + sync_sem_id = osSemaphoreCreate(osSemaphore(sync_sem), 0); + + osThreadCreate(osThread(task1_entry), NULL); + osThreadCreate(osThread(task2_entry), NULL); + + return; +} +``` +运行结果为: +```c +task1 is waiting sem forever... +task1 get sem! +task1 is waiting sem forever... +task2 will release a sem... +task1 get sem! +task1 is waiting sem forever... +task2 will release a sem... +task1 get sem! +task1 is waiting sem forever... +task2 will release a sem... +task1 get sem! +task1 is waiting sem forever... +task2 will release a sem... +task1 get sem! +task1 is waiting sem forever... +``` + +## 3.4. 互斥锁使用示例 +```c +#include + +osMutexId sync_mutex_id; +osMutexDef(sync_mutex); + +void task1_entry(void *arg) +{ + while(1) + { + osMutexWait(sync_mutex_id, osWaitForever); + + printf("task1 get mutex,doing sth...\r\n"); + HAL_Delay(1000); //死循环占用CPU + printf("task1 finish do sth!\r\n"); + + osMutexRelease(sync_mutex_id); + + osDelay(1000); + } +} +osThreadDef(task1_entry, osPriorityHigh, 1, 512); + +void task2_entry(void *arg) +{ + + while(1) + { + osMutexWait(sync_mutex_id, osWaitForever); + + printf("task2 get mutex,doing sth...\r\n"); + HAL_Delay(2000); //死循环占用CPU + printf("task2 finish do sth!\r\n"); + + osMutexRelease(sync_mutex_id); + + osDelay(1000); + } +} +osThreadDef(task2_entry, osPriorityNormal, 1, 512); + +void application_entry(void *arg) +{ + sync_mutex_id = osMutexCreate(osMutex(sync_mutex)); + + osThreadCreate(osThread(task1_entry), NULL); + osThreadCreate(osThread(task2_entry), NULL); + + return; +} +``` +运行结果为: +```c +task1 get mutex,doing sth... +task1 finish do sth! +task2 get mutex,doing sth... +task2 finish do sth! +task1 get mutex,doing sth... +task1 finish do sth! +task1 get mutex,doing sth... +task1 finish do sth! +task2 get mutex,doing sth... +``` +## 3.5. 动态内存使用示例 + + +## 3.6. 消息队列使用示例 +```c +#include + +#define STK_SIZE_TASK_RECEIVER 512 +#define STK_SIZE_TASK_SENDER 512 + +#define MESSAGE_MAX 10 + +osMessageQId msg_q_id; +osMessageQDef(msg_q,MESSAGE_MAX,uint32_t); + +void task_receiver_entry(void *arg) +{ + osEvent event; + osStatus ret; + uint32_t value; + + while (1) + { + event = osMessageGet(msg_q_id, osWaitForever); + ret = event.status; + if (ret == osOK) + { + value = event.value.v; + printf("receiver: msg incoming[%s]\r\n", (char*)value); + } + } +} +osThreadDef(task_receiver_entry, osPriorityNormal, 1, STK_SIZE_TASK_RECEIVER); + +void task_sender_entry(void *arg) +{ + char *msg_prio_0 = "msg 0"; + char *msg_prio_1 = "msg 1"; + char *msg_prio_2 = "msg 2"; + + printf("sender: post a messgae:[%s]\r\n", msg_prio_2); + osMessagePut(msg_q_id,(uint32_t)msg_prio_2,0); + + printf("sender: post a messgae:[%s]\r\n", msg_prio_1); + osMessagePut(msg_q_id,(uint32_t)msg_prio_1,0); + + printf("sender: post a messgae:[%s]\r\n", msg_prio_0); + osMessagePut(msg_q_id,(uint32_t)msg_prio_0,0); + +} +osThreadDef(task_sender_entry, osPriorityNormal, 1, STK_SIZE_TASK_SENDER); + +void application_entry(void *arg) +{ + msg_q_id = osMessageCreate(osMessageQ(msg_q),NULL); + + osThreadCreate(osThread(task_receiver_entry), NULL); + osThreadCreate(osThread(task_sender_entry), NULL); + + return; +} +``` + +运行结果为: +```c +sender: post a messgae:[msg 2] +sender: post a messgae:[msg 1] +sender: post a messgae:[msg 0] +receiver: msg incoming[msg 2] +receiver: msg incoming[msg 1] +receiver: msg incoming[msg 0] +```