• 【LiteOS】LiteOS消息队列-实战



    前言

    链接

    参考

    • 上面链接

    笔录草稿

    • 最近工作有点忙,远吗阅读推迟了哈哈
    • 采用传地址方式
      • 其实这些组件的应用是很简单的,没太在意,很快就搭建好看见,准备测试并看源码,
      • 但是,今天下午却花了两小时,仅仅为了测试非拷贝方式通信失败问题
      • bug就是我在函数里创建一个局部存放消息内容的缓冲区,采用函数 LOS_QueueWrite 发送出去
      • 接收时却出现各种问题,很明显就是地址错误,但是我一丢丢都没想起消息内容被改写的注意点,唉
      • 采用地址方式时,必须保该地址内容没有被修改,且不推荐使用局部变量
      • 采用地址方式时,必须保该地址内容没有被修改,且不推荐使用局部变量
      • 采用地址方式时,必须保该地址内容没有被修改,且不推荐使用局部变量

    创建测试任务

    • 本任务用于 LiteOS 消息队列测试
    • 步骤
      1. 创建任务相关值及函数
        1. LssAppConfig.h 中添加
          1. 任务优先级宏 lssConfigvMsgQueueTaskPRIO (5)
          2. 任务堆栈宏 lssConfigvMsgQueueTaskSIZE 512u
          3. 任务初始化完成枚举 evMsgQueueTaskNum = 0x0D,
          4. 消息队列外部句柄 extern UINT32 MsgQueueTask_Handle;
        2. main.c 中添加
          1. 添加任务头文件 #include "MsgQueueAppTask.h"
          2. 添加句柄
            1. 任务句柄 UINT32 MsgQueueTask_Handle = NULL;
            2. 消息队列测试句柄 UINT32 TestAQue_Handle = NULL;
            3. 创建消息队列任务函数
            4. 在启动任务中
              1. 添加 uwRet = Creat_vMsgQueue_Task();,以表示创建该任务
              2. 添加 uwRet = LOS_QueueCreate("Msg Queue", 20, &TestAQue_Handle, 0, 10); , 以表示创建消息
      2. 创建任务文件 MsgQueueTask.cMsgQueueTask.h
        1. 主要用于消息队列的业务测试
        2. 编写任务函数 void vMsgQueueTask( void )
        3. 消息队列测试任务源文件
        4. 消息队列测试任务头文件
      3. IPCApp.c 文件中添加两个测试函数(框架需要)
        1. void IPCAppMsgQueueA(msgIpc_t *msg) 函数
          1. 就是消息的发送端
          2. 队列测试函数A
        2. void IPCAppMsgQueueB(msgIpc_t *msg) 函数
          1. 就是消息的发送端
          2. 队列测试函数B
        3. 头文件 PCApp.h 也要做外置函数处理
      4. IPCCoreTask.c 文件中 void msgDecode(msgIpc_t * msg) 函数中添加两条处理命令(框架需要)
        1. $QA#
        2. $QB#
        3. 命令处理添加部分源码

    部分源码

    • 创建消息队列任务函数
    /**
    * @brief  创建vMsgQueueTask任务
    * @param 
    * @retval 
    * @author lzm
    */
    static UINT32 Creat_vMsgQueue_Task()
    {
    	//定义一个创建任务的返回类型,初始化为创建成功的返回值
    	UINT32 uwRet = LOS_OK;			
    	
    	TSK_INIT_PARAM_S task_init_param;	
    
    	task_init_param.usTaskPrio = lssConfigvMsgQueueTaskPRIO;
    	task_init_param.pcName = "MsgQueue Task";
    	task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)vMsgQueueTask;
    	task_init_param.uwStackSize = lssConfigvMsgQueueTaskSIZE;
    	
    	uwRet = LOS_TaskCreate(&MsgQueueTask_Handle, &task_init_param);
    	return uwRet;
    }
    
    • 消息队列测试任务源文件
    /**
      ******************************************************************************
      * @file    MsgQueueTask.c
      * @author  lzm
      * @version V1.0
      * @date    2020-10-28
      * @brief
      * @attention
      *
      * 实验平台:LZM
      * 
      *
      *
      ******************************************************************************
      */
    #include "MsgQueueTask.h"
    #include "bsp_usart.h"
    
    /*
    *********************************************************************************************************
    *                                          FUNCTION
    *********************************************************************************************************
    */
    /**
    * @brief 该任务的软硬件配置初始化
    * @param 
    * @retval 
    * @author lzm
    */
    static void msgQueueInit(void)
    {
    	;
    }
    
    /**
    * @brief  任务函数
    * @param 
    * @retval 
    * @author lzm
    */
    void vMsgQueueTask( void )
    {
    	UINT32 uwRet = LOS_OK;
    	UINT32 msgLen = 30;
    	// 接收消息
    	UINT32 uwReadbuf;
    		
    	msgQueueInit();
    	WaitAllTaskInitOk(evMsgQueueTaskNum); // 系统就绪检测及等待
        
    	while(1)
    	{
    		/* 等待消息 */ 
    		uwRet = LOS_QueueRead(TestAQue_Handle,   // 消息队列 ID
                                                &uwReadbuf,            // 保存消息的位置
                                                msgLen,    // 接收消息的长度
                                                LOS_WAIT_FOREVER); // 等待 - 一直等
    		if(uwRet != LOS_OK)
    		{
    			dbgPrintf("read message failure,error:%x
    ",uwRet);
    		}
    		else
    		{
    			dbgPrintf("
    LOS_QueueRead is [%s]!",(char *)uwReadbuf);
    		}
    
    	}
    }
    
    • 消息队列测试任务头文件
    /**
      ******************************************************************************
      * @file    MsgQueueTask.h
      * @author  lzm
      * @version V1.0
      * @date    2020-10-28
      * @brief
      * @attention
      *
      * 实验平台:LZM
      *
      ******************************************************************************
      */
    #ifndef __MSG_QUEUE_TASK_H_
    #define __MSG_QUEUE_TASK_H_ 
    #include "LssAppConfig.h"
    #include "ipcConfig.h"
    /*
    *********************************************************************************************************
    *                                                API
    *********************************************************************************************************
    */
    /* function */
    void vMsgQueueTask( void );
    #endif
    
    • 队列测试函数A
    /**
      * @brief  
      * 命令 [$QA#] 的回调函数。
      * 消息队列测试 A
      * @param 
      * @retval 
      * @author lzm
      */
    void IPCAppMsgQueueA(msgIpc_t *msg)
    {
    	static UINT32 i = 0;
    	static CHAR ABuf[] = "Test is message x";
    	UINT32 msgLen = sizeof(ABuf);
    	
    	LOS_QueueWrite( TestAQue_Handle,      /* 消息队列的句柄 */
    									ABuf,              /* 发送的消息内容 发送字符串的地址*/
    									msgLen,
    									0);     /* 消息大小 */
    }
    
    • 队列测试函数B
    /**
      * @brief  
      * 命令 [$QB#] 的回调函数。
      * 消息队列测试 B
      * @param 
      * @retval 
      * @author lzm
      */
    void IPCAppMsgQueueB(msgIpc_t *msg)
    {
    	static UINT32 i = 0;
    	static CHAR BBuf[] = "Test is message n";
    	UINT32 msgLen = sizeof(BBuf);
    	
    	LOS_QueueWrite( TestAQue_Handle,      /* 消息队列的句柄 */
    									BBuf,              /* 发送的消息内容 发送字符串的地址*/
    									msgLen,
    									0);     /* 消息大小 */
    }
    
    • 命令处理添加部分源码
    ...
    else if(msg->data[msg->index + 1] == 'Q')
    	{
    		if(msg->data[msg->index + 2] == 'A')
    		{
    			MALLOC_REGISTER_INSTEREND_CBFUN_LIST(cmd, cmdItem, 2, msg, callbackFunctionList, xCBFunListSem_Handle, IPCAppMsgQueueA);		
    			
    			// ¸æÖªÖ´ÐÐÈÎÎñ
    			uwRet = LOS_SemPost(ListApp_Handle);
    			if (uwRet != LOS_OK){;}		
    		}
    		else if(msg->data[msg->index + 2] == 'B')
    		{
    			MALLOC_REGISTER_INSTEREND_CBFUN_LIST(cmd, cmdItem, 3, msg, callbackFunctionList, xCBFunListSem_Handle, IPCAppMsgQueueB);		
    			
    			// ¸æÖªÖ´ÐÐÈÎÎñ
    			uwRet = LOS_SemPost(ListApp_Handle);
    			if (uwRet != LOS_OK){;}		
    		}
    	}
    ...
    
  • 相关阅读:
    2016年之前优秀的单目SLAM系统
    EPSON四轴机械臂原点校准
    运动控制之手眼定位
    【已解决】移动端页面手势滑动触发touch 事件时,在左右上下部分出现空白部分的问题
    es分组排序和聚合后再筛选
    git配置ssh和小乌龟配置ssh
    单调栈的简单分享 Marathon
    es6.18升级到es7.17的不同点记录 Marathon
    input的ref属性
    手写axios
  • 原文地址:https://www.cnblogs.com/lizhuming/p/13944550.html
Copyright © 2020-2023  润新知