目录
使用程序模板(queue_demo.c)添加如下头文件、全局变量和字符缓冲区代码
实验目的
- 掌握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如下所示