打印
[学习笔记]

AC78013 FreeRtos 消息队列使用

[复制链接]
8437|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hello1030|  楼主 | 2021-5-24 15:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
消息队列:异步通信机制

1.当队列中的消息是空时,读取消息的任务将被阻塞
2.可以指定阻塞的任务时间 xTicksToWait(这段时间中,如果队列为空,该任务将保持阻塞状态以等待队列数据有效)
3.等待期间如果队列有消息,会唤醒被阻塞的任务并处理消息
4.等待超时,即使队列没有数据也会让任务进入就绪状态


5.消息先进先出
6.允许不同长度(限定范围之内)
7.一个消息队列可以服务于一个或多个任务
6.队列使用结束后通过删除队列函数删除


消息队列基本要素
头指针 pcHead、尾指针 pcTail、消息大小 uxItemSize 以及队列长度 uxLength  
消息队列与消息空间占用一段连续内存
一经创建不可改变

发送消息(任何任务或者中断函数都可以) 队列未满或者允许覆盖入队(消息安全性如何保证?),也可以是消息阻塞状态(那么发送消息的任务进入阻塞状态?是的)如果等待超时任务会进入就绪状态并会报错(errQUEUE_FULL)
普通消息加入队尾(先进先出),紧急消息加入队头。
发送到消息队列的数据是拷贝数据,不是引用数据

如果消息的长度过长可以将消息的地址作为消息发送(要保证数据不被多次擦写)


消息读取:
某任务试图读取消息时可以指定超时时间等待消息


保护机制:


阻塞机制:

读取阻塞:
任务A对队列L进行读操作的时候如果队列中没有消息:
1.任务直接放弃读取
2.任务A等待(进入阻塞状态)等待时间由软件定义
3.任务A一直等待,A进入阻塞状态直到消息队列有数据才会恢复为就绪状态

写入阻塞
任务B被允许对队列L写入时
1.如果队列已满,任务B可以等待阻塞超时时间,指定时间内如果不能完成写入操作返回错误吗errQUEUEFULL,然后进入就绪状态
2.中断中发送队列消息不允许有阻塞机制
3.如果有多个消息阻塞在队列操作中,这些任务将按照优先级进行排序



安全设计思想:
一个队列尽可能只对应一个任务可以写入和读取,生产者和消费者保证唯一性。
一个队列由多任务或中断写入是经常的事,但由多个任务读出倒是用的比较少。



实验:设计两个任务,一个按键检测任务Key,一个LED点亮任务Led
检测到Key(扫描方式)发送消息给到Led任务点亮Led
检测到Key(中断方式)发送消息给到Led任务点亮Led



下面贴部分代码
* AutoChips Inc. (C) 2021. All rights reserved.
  *
  * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
  * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
  * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
  * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
  * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
  * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
  * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
  * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
  * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
  * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
  * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
  * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
  * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
  * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
  * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
  *
  ******************************************************************************  
  */

/* --------------------------------- Includes -------------------------------*/
#include "main.h"
#include "ac780x_irq_cb.h"
#include "ac780x_uart.h"
#include "ac780x_uart_reg.h"
#include "ac780x_gpio.h"
/* USER CODE BEGIN Includes */
#include  <stdarg.h>
#include  <stdio.h>
#include  <stdlib.h>
#include  <math.h>


#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "croutine.h"
/* USER CODE END Includes */

/* --------------------------------- Typedefs -------------------------------*/
/* USER CODE BEGIN Typedefs */
static TaskHandle_t xHandleTaskLed = NULL;
static TaskHandle_t xTaskTaskKey = NULL;
QueueHandle_t      Test_GpioQueue =NULL;  //消息队列句柄

/* USER CODE END Typedefs */

/* --------------------------------- Defines --------------------------------*/
/* USER CODE BEGIN Defines */

/* USER CODE END Defines */

/* --------------------------------- Macros ---------------------------------*/
/* USER CODE BEGIN Macros */

/* USER CODE END Macros */

/* --------------------------------- Variables ------------------------------*/

/* USER CODE BEGIN Variables */

/* USER CODE END Variables */

/* --------------------------------- Function Prototypes --------------------*/
void SystemClock_Config(void);
static void ATC_GPIO_Init(void);
static void ATC_UART2_Init(void);
static void ATC_UART1_Init(void);
void MSP_Init(void);
void MSP_UART_Init(UART_Type* UARTx);

/* USER CODE BEGIN Function_Prototypes */
static void vTaskTaskLed(void* parameter)
{

BaseType_t xReturn = pdPASS;
uint8_t    xRekeydata[2]={0x0};

while (1)
{
        printf("Scan msg \r\n");
       
        xReturn = xQueueReceive(Test_GpioQueue, xRekeydata, 500);
       
        if(xReturn == errQUEUE_EMPTY)
                {
                        printf("empty\r\n");
                }
               
        if(xReturn == pdTRUE)
        {
                printf("Get  %d,%d\r\n",xRekeydata[0],xRekeydata[1]);
               
                if(xRekeydata[0] == 0x01)
                        GPIO_SetPinLevel(LED2_GPIO_Port,LED2_Pin,GPIO_LEVEL_LOW);
                else
                        GPIO_SetPinLevel(LED2_GPIO_Port,LED2_Pin,GPIO_LEVEL_HIGH);
        }
        else
        {
               
        }


         /*
        printf("Task Led 0\r\n");
       GPIO_SetPinLevel(LED1_GPIO_Port,LED1_Pin,GPIO_LEVEL_LOW);
                vTaskDelay(500);
        printf("Task Led 1\r\n");
        GPIO_SetPinLevel(LED1_GPIO_Port,LED1_Pin,GPIO_LEVEL_HIGH);
                vTaskDelay(500);
     */
}
}
static void vTaskTaskKey(void* parameter)
{

BaseType_t xReturn = pdPASS;
uint8_t    xkeydata[2]={0x0};
while (1)  
{
        //L  enable
/*        printf("Task Key\r\n");
        if(GPIO_GetPinLevel(KEY2_GPIO_Port, KEY2_Pin) == 0)
                {
        //        GPIO_SetPinLevel(LED2_GPIO_Port,LED2_Pin,GPIO_LEVEL_LOW);
                xkeydata[0] = 0x00;
                xkeydata[1] = 0x00;
                xReturn =  xQueueSend( Test_GpioQueue, xkeydata,0);
                }
        else
                {
        //        GPIO_SetPinLevel(LED2_GPIO_Port,LED2_Pin,GPIO_LEVEL_HIGH);
                xkeydata[0] = 0x01;
                xkeydata[1] = 0x01;
                xReturn =  xQueueSend( Test_GpioQueue, xkeydata,0);
                }
        vTaskDelay(5000);
*/
}
}
/* USER CODE END Function_Prototypes */

/* USER CODE BEGIN 0 */

static void AppTaskCreate (void)
{

Test_GpioQueue = xQueueCreate(16, 2);

if(NULL != Test_GpioQueue)
{
printf("消息队列创建成功\r\n");
}
else
{
printf("消息队列创建失败\r\n");
}




    xTaskCreate( vTaskTaskLed,            
                 "vTaskLed",              
                 512,                        
                 NULL,                       
                 1,                          
                 &xHandleTaskLed );   

        xTaskCreate( vTaskTaskKey,            
                 "vTaskUserTRE",              
                 512,                        
                 NULL,                       
                 1,                          
                 &xTaskTaskKey );   
       
}



/*******************************************************************************
* Function Name  :void ACC_IRQHandler(void *device, uint32_t wpara, uint32_t lpara)
* Description    :ACC  引脚中断处理程序
* Output         : None
* Return         : None
*******************************************************************************/
void SocGpioACC_IRQHandler(void *device, uint32_t wpara, uint32_t lpara)
{
uint8_t    xkeydata[2]={0x0};
//if(GPIO_GetPendingExtInterrupt() & KEY2_Pin)
{
          GPIO_ClearPendingExtInterrupt(KEY2_Pin);
xkeydata[0] =GPIO_GetPinLevel(KEY2_GPIO_Port, KEY2_Pin);
xQueueSend( Test_GpioQueue, xkeydata,0);


}
}


/*******************************************************************************
* Function Name  :void  SocGpioEXITAccDet(void)
* Description    :使能 ACC   中断
* Output         : None
* Return         : None
*******************************************************************************/
void  SocGpioEXITKeyDet(void)
{


        GPIO_SetPullup(KEY2_GPIO_Port,KEY2_Pin, ENABLE);

       
GPIO_EnableExtInterrupt(KEY2_GPIO_Port, KEY2_Pin, EXTI_TRIGGER_RISING_FALLING);
       
GPIO_SetCallback(KEY2_Pin, SocGpioACC_IRQHandler);


}
















/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  *
  * @retval int
  */
int main(void)
{
    /* USER CODE BEGIN 1 */

    /* USER CODE END 1 */

    /* MCU Configuration------------------------------------------------------*/

    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* Configure the system clock */
    SystemClock_Config();

    /* USER CODE BEGIN SysInit */

    /* USER CODE END SysInit */

    /* Initialize all configured peripherals */
    ATC_GPIO_Init();
    ATC_UART2_Init();
    ATC_UART1_Init();

    /* USER CODE BEGIN 2 */

        SocGpioEXITKeyDet();
        InitDebug();
        AppTaskCreate();
        vTaskStartScheduler();
       
       
       
    /* USER CODE END 2 */

    /* Infinite loop */
    while(1)
    {

        /* USER CODE BEGIN WHILE */

        /* USER CODE END WHILE */

    }

    /* USER CODE BEGIN 3 */

    /* USER CODE END 3 */
}

/**
    * @brief System Clock Configuration
    * @retval None
    */
void SystemClock_Config(void)
{
    SPM_EnableXOSC(ENABLE);
    SPM_EnablePLL(ENABLE);
    CKGEN_SetPLLReference(PLL_REF_INTERAL_OSC);
    CKGEN_SetPllPrevDiv(PLL_PREDIV_1);
    CKGEN_SetPllFeedbackDiv(96);
    CKGEN_SetPllPostDiv(PLL_POSDIV_16);
    CKGEN_SetSysclkDiv(SYSCLK_DIVIDER_1);
    CKGEN_SetSysclkSrc(SYSCLK_SRC_PLL_OUTPUT);
    CKGEN_SetAPBClockDivider(APBCLK_DIVIDER_2);
}

/* UART1 init function */
static void ATC_UART1_Init(void)
{
    /* USER CODE BEGIN UART1_Init 0 */

    /* USER CODE END UART1_Init 0 */

    UART_ConfigType uartConfig;
    memset(&uartConfig, 0, sizeof(uartConfig));

    /* USER CODE BEGIN UART1_Init 1 */

    /* USER CODE END UART1_Init 1 */

    MSP_UART_Init(UART1);

    uartConfig.baudrate = 115200;
    uartConfig.dataBits = UART_WORD_LEN_8BIT;
    uartConfig.stopBits = UART_STOP_1BIT;
    uartConfig.parity = UART_PARI_NO;
    uartConfig.fifoByteEn = DISABLE;
    uartConfig.dmaEn = UART_DMA_TXRX_NONE;
    uartConfig.sampleCnt = UART_SMP_CNT0;

    UART_Init(UART1, &uartConfig);

    /* USER CODE BEGIN UART1_Init 2 */

    /* USER CODE END UART1_Init 2 */
}

/* UART2 init function */
static void ATC_UART2_Init(void)
{
    /* USER CODE BEGIN UART2_Init 0 */

    /* USER CODE END UART2_Init 0 */

    UART_ConfigType uartConfig;
    memset(&uartConfig, 0, sizeof(uartConfig));

    /* USER CODE BEGIN UART2_Init 1 */

    /* USER CODE END UART2_Init 1 */

    MSP_UART_Init(UART2);

    uartConfig.baudrate = 115200;
    uartConfig.dataBits = UART_WORD_LEN_8BIT;
    uartConfig.stopBits = UART_STOP_1BIT;
    uartConfig.parity = UART_PARI_NO;
    uartConfig.fifoByteEn = DISABLE;
    uartConfig.dmaEn = UART_DMA_TXRX_NONE;
    uartConfig.sampleCnt = UART_SMP_CNT0;

    UART_Init(UART2, &uartConfig);

    /* USER CODE BEGIN UART2_Init 2 */

    /* USER CODE END UART2_Init 2 */
}

/** Configure pins as
              * Analog
              * Input
              * Output
              * EVENT_OUT
              * EXTI
*/
static void ATC_GPIO_Init(void)
{
    GPIO_SetFunc(KEY2_GPIO_Port, KEY2_Pin, GPIO_FUN0);
    GPIO_SetFunc(KEY1_GPIO_Port, KEY1_Pin, GPIO_FUN0);
    GPIO_SetFunc(LED2_GPIO_Port, LED2_Pin, GPIO_FUN0);
    GPIO_SetFunc(LED1_GPIO_Port, LED1_Pin, GPIO_FUN0);
    GPIO_SetDir(KEY2_GPIO_Port, KEY2_Pin, GPIO_IN);
    GPIO_SetDir(KEY1_GPIO_Port, KEY1_Pin, GPIO_IN);
    GPIO_SetDir(LED2_GPIO_Port, LED2_Pin, GPIO_OUT);
    GPIO_SetDir(LED1_GPIO_Port, LED1_Pin, GPIO_OUT);
    GPIO_SetPinLevel(LED2_GPIO_Port, LED2_Pin, GPIO_LEVEL_LOW);
    GPIO_SetPinLevel(LED1_GPIO_Port, LED1_Pin, GPIO_LEVEL_LOW);
    GPIO_SetDrivingAbility(LED2_GPIO_Port, LED2_Pin, GPIO_DRIVING_4MA);
    GPIO_SetDrivingAbility(LED1_GPIO_Port, LED1_Pin, GPIO_DRIVING_4MA);
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @param  file: The file name as string.
  * @param  line: The line in file as a number.
  * @retval None
  */
void Error_Handler(char *file, int line)
{
    /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to handle the driver error */
    while(1)
    {
    }
    /* USER CODE END Error_Handler_Debug */
}

/************************ (C) COPYRIGHT AutoChips *****END OF FILE****/




































使用特权

评论回复

相关帖子

沙发
hello1030|  楼主 | 2021-5-24 15:43 | 只看该作者

使用特权

评论回复
板凳
两只袜子| | 2021-6-9 10:44 | 只看该作者
消息队列使用很新颖的词汇

使用特权

评论回复
地板
自己造声卡| | 2021-6-9 12:14 | 只看该作者
这个讲解太细致了,感谢楼主的分享。

使用特权

评论回复
5
lidi911| | 2021-6-9 20:40 | 只看该作者
FIFO用好了,会提升代码效率。

使用特权

评论回复
6
usysm| | 2021-6-12 12:28 | 只看该作者
如何移植到freertos中  

使用特权

评论回复
7
typeof| | 2021-6-12 12:29 | 只看该作者
怎么知道队列消息的有效长度  

使用特权

评论回复
8
yujielun| | 2021-6-12 12:29 | 只看该作者
           

使用特权

评论回复
9
htmlme| | 2021-6-12 12:30 | 只看该作者
FreeRTOS 的一个重要的通信机制  

使用特权

评论回复
10
pklong| | 2021-6-12 12:30 | 只看该作者
基于FreeRTOS 的应用程序由一组独立的任务构成  

使用特权

评论回复
11
touser| | 2021-6-12 12:31 | 只看该作者
            

使用特权

评论回复
12
myiclife| | 2021-6-12 12:31 | 只看该作者
使用了FreeRTOS操作系   

使用特权

评论回复
13
uytyu| | 2021-6-12 12:32 | 只看该作者
刚入门FreeRTOS            

使用特权

评论回复
14
iyoum| | 2021-6-12 12:32 | 只看该作者
没有例程吗     

使用特权

评论回复
15
jkl21| | 2021-6-12 12:34 | 只看该作者
AC78013需要占用多大的内存

使用特权

评论回复
16
touser| | 2021-6-12 12:34 | 只看该作者
谢谢楼主分享的资料了。         

使用特权

评论回复
17
pklong| | 2021-6-12 12:34 | 只看该作者
FreeRTOSV10.4.0更新了哪些功能?

使用特权

评论回复
18
htmlme| | 2021-6-12 12:34 | 只看该作者
消息队列在实际项目中应用较多。  

使用特权

评论回复
19
yujielun| | 2021-6-12 12:34 | 只看该作者
谢谢楼主分享的。   

使用特权

评论回复
20
typeof| | 2021-6-12 12:34 | 只看该作者
使用队列怎么发送一个结构体  

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

24

帖子

0

粉丝