OpenHarmony——内核通信(消息队列)
目录
实验目的
实验涉及知识点
实验过程
使用程序模板(queue_demo.c)添加如下头文件、全局变量和字符缓冲区代码
添加任务函数
添加测试函数Queue_Demo
添加自定义命令
修改两个BUILD.gn文件
编译运行
实验目的
- 掌握LiteOS-M核心中进程间(任务间)的通信机制和基本的方法原理。
- 了解对资源同步和异步访问,掌握如何使用合适的方法对公共资源的访问实现同步操作。
- 熟悉LiteOS-M内核中主要的通信函数函数接口及其使用。
- 掌握实验开发平台和本地集成开发工具的使用。
实验涉及知识点
- 进程通信的方法和基本原理。
- 同步、异步的基本概念。
- LiteOS-M中内核通信(消息队列相关)的基本函数接口的使用、任务创建及管理的函数接口的使用。
- 本地集成开发工具(交叉编译工具)及映像文件烧录工具。
实验过程
消息队列的使用
在openHarmony/device/qemu/arm_mps2_an386/liteos_m/board路径下创建新文件夹并导入程序模板
使用程序模板(queue_demo.c)添加如下头文件、全局变量和字符缓冲区代码
#include "queue_demo.h"UINT32 g_testTaskID001;UINT32 g_testQueueID001;QUEUE_INFO_S queueInfo;CHAR send_buff[QUEUE_SHORT_BUFFER_LENGTH] = "Hi Task!";CHAR recv_buff[QUEUE_SHORT_BUFFER_LENGTH] = " ";CHAR queue_send_buff[QUEUE_SHORT_BUFFER_LENGTH] = "Hi Demo!";CHAR queue_recv_buff[QUEUE_SHORT_BUFFER_LENGTH] = " ";
- g_testTaskID001用于标识任务;g_testQueueID001用于标识队列;结构体变量queueInfo用户获得队列的相关信息。
- 字符缓冲区分别用于QueueTaskF01和Queue_Demo两个任务的消息收发,send_buff为发出消息的缓冲区,recv_buff为收取消息的缓冲区。
添加任务函数
static VOID QueueTaskF01(VOID){ UINT32 ret; printf("\n++++++++++QueueTaskF01:start\n"); ret = LOS_QueueReadCopy(g_testQueueID001, &queue_recv_buff, QUEUE_BASE_MSGSIZE, LOS_WAIT_FOREVER); if(ret == LOS_OK) printf("\n++++++++++QueueTaskF01:message received = %s\n", queue_recv_buff); ret = LOS_QueueWriteCopy(g_testQueueID001, &queue_send_buff, QUEUE_BASE_MSGSIZE, 0); if(ret == LOS_OK) printf("\n++++++++++QueueTaskF01:message send = %s\n", queue_send_buff); return;}
- 任务函数QueueTaskF01内部调用函数LOS_QueueReadCopy从消息队列g_testQueueID001中读取消息,并把读取的消息内容存储到缓冲区queue_recv_buff中,缓冲数据大小为QUEUE_BASE_MSGSIZE宏定义的值(8字节),如果消息队列没有读到信息,则任务会一直处于挂起状态(LOS_WAIT_FOREVER)。
- 随即使用LOS_QueueWriteCopy函数向队列中写入一条信息,写入信息在缓存区queue_send_buff中存放,发送消息长度为QUEUE_BASE_MSGSIZE。
添加测试函数Queue_Demo
VOID Queue_Demo(VOID){ UINT32 ret; //Create a queue here ret = LOS_QueueCreate("Q1", 8, &g_testQueueID001, 0, QUEUE_BASE_MSGSIZE); if(ret == LOS_OK) printf("\n++++++++++Queue Demo:queue create ok! the queue ID = %d\n", g_testQueueID001); ret = LOS_QueueInfoGet(g_testQueueID001, &queueInfo); if(ret == LOS_OK) printf("\n++++++++++Queue Demo:queue info get ok!\n"); //Create the QueueTaskF01 TSK_INIT_PARAM_S queue_task1; (void)memset_s(&queue_task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); queue_task1.pfnTaskEntry = (TSK_ENTRY_FUNC)QueueTaskF01; queue_task1.uwStackSize = TASK_STACK_SIZE_TEST; queue_task1.pcName = "queueTsk1"; queue_task1.usTaskPrio = TASK_PRIO_TEST; queue_task1.uwResved = LOS_TASK_STATUS_DETACHED; ret = LOS_TaskCreate(&g_testTaskID001, &queue_task1); if(ret == LOS_OK) printf("\n++++++++++Queue Demo:QueueTaskF01 created ok! taskID = %d\n", g_testTaskID001); ret = LOS_QueueWriteCopy(g_testQueueID001, &send_buff, QUEUE_BASE_MSGSIZE, 0); if(ret == LOS_OK) printf("\n++++++++++Queue Demo:message send = %s with address = 0x%x\n", send_buff, send_buff); LOS_TaskDelay(20); ret = LOS_QueueReadCopy(g_testQueueID001, &recv_buff, QUEUE_BASE_MSGSIZE, LOS_WAIT_FOREVER); printf("\n++++++++++Queue Demo:message received = %s\n", recv_buff); ret = LOS_QueueDelete(g_testQueueID001); ret = LOS_TaskDelete(g_testTaskID001); return ret;}
- 首先调用函数LOS_QueueCreate创建队列,队列名称为“Q1”;队列有8个消息块,每块的大小为QUEUE_BASE_MSGSIZE;队列标识ID为g_testQueueID001;第四个参数暂不使用,用“0”代替。
- 调用LOS_QueueInfoGet函数可以获得刚创建的队列信息,可以查看队列是否按照输入的参数创建,也可以用于随时观察队列的状态。
- 初始化任务参数并创建队列任务QueueTaskF01。
- 使用函数LOS_QueueWriteCopy函数向队列g_testQueueID001写入缓冲区send_buff中的字符串信息,长度为QUEUE_BASE_MSGSIZE。注意区分另外一个函数LOS_QueueWrite,此函数只写入缓冲区的地址,不会写入字符串的内容。
- 加入延迟LOS_TaskDelay(20),此时调度器可以调度队列任务QueueTaskF01运行,从而执行任务中读取队列消息的操作。
- 由于队列任务QueueTaskF01在收到消息以后又会发出一条消息,在延迟20个时钟周期以后,调用函数LOS_QueueReadCopy读取队列任务QueueTaskF01回发的消息。
添加自定义命令
在/home/openharmony/device/qemu/arm_mps2_an386/liteos_m/board路径下的main.c文件中进行修改
在/home/openharmony/kernel/liteos_m/components/shell路径下的BUILD.gn中添加用户命令
在/home/openharmony/kernel/liteos_m/components/shell/src/cmds路径下添加用户命令源文件my_shellcmd.c
#include "shell.h"extern void Queue_Demo();UINT32 Shell_Cmd_Queue(UINT32 argc, const CHAR **argv){ (void)argc; (void)argv; printf("This is queue demo launch command.\n"); Queue_Demo(); return 0;}void regMyShellCmd(void){ osCmdReg(CMD_TYPE_STD, "queue_demo", 0, Shell_Cmd_Queue);}
修改两个BUILD.gn文件
对device/qemu/arm_mps2_an386/liteos_m/board路径下的BUILD.gn进行修改
在创建的queue_demo文件夹下创建新的BUILD.gn文件
编译运行
运行系统镜像后输入help命令,以观察用户命令是否添加成功。
此时可以看到queue_demo命令添加成功
运行queue_demo如下所示