目录

实验目的

实验涉及知识点

实验过程

消息队列的使用

使用程序模板(queue_demo.c)添加如下头文件、全局变量和字符缓冲区代码

添加任务函数

添加测试函数Queue_Demo

添加自定义命令

修改两个BUILD.gn文件

编译运行


实验目的

  1. 掌握LiteOS-M核心中进程间(任务间)的通信机制和基本的方法原理。
  2. 了解对资源同步和异步访问,掌握如何使用合适的方法对公共资源的访问实现同步操作。
  3. 熟悉LiteOS-M内核中主要的通信函数函数接口及其使用。
  4. 掌握实验开发平台和本地集成开发工具的使用。

实验涉及知识点

  1. 进程通信的方法和基本原理。
  2. 同步、异步的基本概念。
  3. LiteOS-M中内核通信(消息队列相关)的基本函数接口的使用、任务创建及管理的函数接口的使用。
  4. 本地集成开发工具(交叉编译工具)及映像文件烧录工具。

实验过程

消息队列的使用

在openHarmony/device/qemu/arm_mps2_an386/liteos_m/board路径下创建新文件夹并导入程序模板

openharmony的hap如何运行在harmonyos上 openharmony内核_harmonyos

使用程序模板(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文件中进行修改

openharmony的hap如何运行在harmonyos上 openharmony内核_华为_02

在/home/openharmony/kernel/liteos_m/components/shell路径下的BUILD.gn中添加用户命令

openharmony的hap如何运行在harmonyos上 openharmony内核_消息队列_03

在/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进行修改

openharmony的hap如何运行在harmonyos上 openharmony内核_消息队列_04

在创建的queue_demo文件夹下创建新的BUILD.gn文件

openharmony的hap如何运行在harmonyos上 openharmony内核_鸿蒙系统_05

编译运行

运行系统镜像后输入help命令,以观察用户命令是否添加成功。

openharmony的hap如何运行在harmonyos上 openharmony内核_消息队列_06

此时可以看到queue_demo命令添加成功

运行queue_demo如下所示

openharmony的hap如何运行在harmonyos上 openharmony内核_华为_07