CMSIS 2.0接口中的消息(Message)功能主要涉及到实时操作系统(RTOS)中的线程间通信。在CMSIS 2.0标准中,消息通常是通过消息队列(MessageQueue)来进行处理的,以实现不同线程之间的信息交换。
注意事项
在使用CMSIS 2.0的消息队列API时,需要确保在RTOS内核启动之前(即在调用osKernelStart()之前)创建并初始化消息队列。
发送和接收消息时,需要确保传递的指针和缓冲区是有效的,并且大小与创建消息队列时指定的参数相匹配。
如果在超时时间内无法发送或接收消息,函数将返回相应的错误状态。开发人员需要根据这些状态来处理可能的错误情况。
MessageQueue API
API名称 | 说明 |
osMessageQueueNew | 创建和初始化一个消息队列 |
osMessageQueueGetName | 返回指定的消息队列的名字 |
osMessageQueuePut | 向指定的消息队列存放1条消息,如果消息队列满了,那么返回超时 |
osMessageQueueGet | 从指定的消息队列中取得1条消息,如果消息队列为空,那么返回超时 |
osMessageQueueGetCapacity | 获得指定的消息队列的消息容量 |
osMessageQueueGetMsgSize | 获得指定的消息队列中可以存放的最大消息的大小 |
osMessageQueueGetCount | 获得指定的消息队列中当前的消息数 |
osMessageQueueGetSpace | 获得指定的消息队列中还可以存放的消息数 |
osMessageQueueReset | 将指定的消息队列重置为初始状态 |
osMessageQueueDelete | 删除指定的消息队列 |
代码编写
修改D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\BUILD.gn文件
# Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/config/component/lite_component.gni")
lite_component("demo") {
features = [
#"base_00_helloworld:base_helloworld_example",
#"base_01_led:base_led_example",
#"base_02_loopkey:base_loopkey_example",
#"base_03_irqkey:base_irqkey_example",
#"base_04_adc:base_adc_example",
#"base_05_pwm:base_pwm_example",
#"base_06_ssd1306:base_ssd1306_example",
#"kernel_01_task:kernel_task_example",
#"kernel_02_timer:kernel_timer_example",
#"kernel_03_event:kernel_event_example",
#"kernel_04_mutex:kernel_mutex_example",
#"kernel_05_semaphore_as_mutex:kernel_semaphore_as_mutex_example",
#"kernel_06_semaphore_for_sync:kernel_semaphore_for_sync_example",
#"kernel_07_semaphore_for_count:kernel_semaphore_for_count_example",
"kernel_08_message_queue:kernel_message_queue_example",
]
}
创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\kernel_08_message_queue文件夹
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\kernel_08_message_queue\kernel_message_queue_example.c文件D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\kernel_08_message_queue\BUILD.gn文件
# Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("kernel_message_queue_example") {
sources = [
"kernel_message_queue_example.c"
]
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/kal/cmsis",
]
}
/*
* Copyright (C) 2023 HiHope Open Source Organization .
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#define STACK_SIZE (1024)
#define DELAY_TICKS_3 (3)
#define DELAY_TICKS_5 (5)
#define DELAY_TICKS_20 (20)
#define DELAY_TICKS_80 (80)
#define QUEUE_SIZE 3
typedef struct {
osThreadId_t tid;
int count;
} message_entry;
osMessageQueueId_t qid;
void sender_thread(void)
{
// 定义一个静态变量count,用于记录发送的消息的次数
static int count = 0;
// 定义一个message_entry类型的变量sentry
message_entry sentry;
// 无限循环
while (1) {
// 将当前线程的ID赋值给sentry的tid
sentry.tid = osThreadGetId();
// 将count的值赋值给sentry的count
sentry.count = count;
// 打印当前线程的名字和count的值
printf("[Message Test] %s send %d to message queue.\r\n",
osThreadGetName(osThreadGetId()), count);
// 将sentry放入消息队列中
osMessageQueuePut(qid, (const void *)&sentry, 0, osWaitForever);
// count加1
count++;
// 延时5个节拍
osDelay(DELAY_TICKS_5);
}
}
void receiver_thread(void)
{
// 定义一个消息队列rentry
message_entry rentry;
// 无限循环
while (1) {
// 从队列qid中获取消息
osMessageQueueGet(qid, (void *)&rentry, NULL, osWaitForever);
// 打印当前线程名称、接收到的消息计数和发送线程名称
printf("[Message Test] %s get %d from %s by message queue.\r\n",
osThreadGetName(osThreadGetId()), rentry.count, osThreadGetName(rentry.tid));
// 延时3个时钟周期
osDelay(DELAY_TICKS_3);
}
}
osThreadId_t newThread(char *name, osThreadFunc_t func, char *arg)
{
osThreadAttr_t attr = {
name, 0, NULL, 0, NULL, STACK_SIZE*2, osPriorityNormal, 0, 0
};
osThreadId_t tid = osThreadNew(func, (void *)arg, &attr);
if (tid == NULL) {
printf("[Message Test] osThreadNew(%s) failed.\r\n", name);
} else {
printf("[Message Test] osThreadNew(%s) success, thread id: %d.\r\n", name, tid);
}
return tid;
}
void rtosv2_msgq_main(void)
{
qid = osMessageQueueNew(QUEUE_SIZE, sizeof(message_entry), NULL);
osThreadId_t ctid1 = newThread("recevier1", receiver_thread, NULL);
osThreadId_t ctid2 = newThread("recevier2", receiver_thread, NULL);
osThreadId_t ptid1 = newThread("sender1", sender_thread, NULL);
osThreadId_t ptid2 = newThread("sender2", sender_thread, NULL);
osThreadId_t ptid3 = newThread("sender3", sender_thread, NULL);
osDelay(DELAY_TICKS_20);
uint32_t cap = osMessageQueueGetCapacity(qid);
printf("[Message Test] osMessageQueueGetCapacity, capacity: %u.\r\n", cap);
uint32_t msg_size = osMessageQueueGetMsgSize(qid);
printf("[Message Test] osMessageQueueGetMsgSize, size: %u.\r\n", msg_size);
uint32_t count = osMessageQueueGetCount(qid);
printf("[Message Test] osMessageQueueGetCount, count: %u.\r\n", count);
uint32_t space = osMessageQueueGetSpace(qid);
printf("[Message Test] osMessageQueueGetSpace, space: %u.\r\n", space);
osDelay(DELAY_TICKS_80);
osThreadTerminate(ctid1);
osThreadTerminate(ctid2);
osThreadTerminate(ptid1);
osThreadTerminate(ptid2);
osThreadTerminate(ptid3);
osMessageQueueDelete(qid);
}
static void MessageTestTask(void)
{
osThreadAttr_t attr;
attr.name = "rtosv2_msgq_main";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = STACK_SIZE;
attr.priority = osPriorityNormal;
if (osThreadNew((osThreadFunc_t)rtosv2_msgq_main, NULL, &attr) == NULL) {
printf("[MessageTestTask] Falied to create rtosv2_msgq_main!\n");
}
}
APP_FEATURE_INIT(MessageTestTask);
使用build,编译成功后,使用upload进行烧录。