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进行烧录。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部