完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1.前言
在嵌入式操作系统中队列是任务间数据交换的常用手段,队列是生产者消费者模型的重要组成部分。FreeRTOS的队列简单易用,下面结合一个具体例子说明FreeRTOS中的队列如何使用。 2.参考代码 参考代码中存在两个任务,任务A和任务B。任务A扮演生产者的角色,任务A不断地向队列中填充内容,填充的内容为一个int16_t类型的变量,填充完之后该变量累加;任务B扮演消费者的角色,任务B不断的从队列中提取内容,并通过串口打印。 /* Standard includes. */ #include #include /* Scheduler includes. */ #include "FreeRTOS.h" #include "task.h" #include "queue.h" /* Library includes. */ #include "stm32f10x.h" #define LED0_ON() GPIO_SetBits(GPIOB,GPIO_Pin_5); #define LED0_OFF() GPIO_ResetBits(GPIOB,GPIO_Pin_5); /* 队列句柄 */ xQueueHandle MsgQueue; static void prvSetupHardware( void ); void TaskA( void *pvParameters ); void TaskB( void *pvParameters ); void LedInit(void); void UART1Init( void ); int main( void ) { /* 初始化硬件平台 */ prvSetupHardware(); /* 建立队列 */ MsgQueue = xQueueCreate( 5 , sizeof( int16_t ) ); /* 建立任务 */ xTaskCreate( TaskA, ( signed portCHAR * ) "TaskA", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+3, NULL ); xTaskCreate( TaskB, ( signed portCHAR * ) "TaskB", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+4, NULL ); /* 启动OS */ vTaskStartScheduler(); return 0; } /*-----------------------------------------------------------*/ void TaskA( void *pvParameters ) { int16_t SendNum = 1; for( ;; ) { vTaskDelay( 2000/portTICK_RATE_MS ); /* 向队列中填充内容 */ xQueueSend( MsgQueue, ( void* )&SendNum, 0 ); SendNum++; } } void TaskB( void *pvParameters ) { int16_t ReceiveNum = 0; for( ;; ) { /* 从队列中获取内容 */ if( xQueueReceive( MsgQueue, &ReceiveNum, 100/portTICK_RATE_MS ) == pdPASS) { printf("ReceiveNum:%drn",ReceiveNum); } } } static void prvSetupHardware( void ) { LedInit(); UART1Init(); } void LedInit( void ) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); /*LED0 @ GPIOB.5*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init( GPIOB, &GPIO_InitStructure ); } void UART1Init( void ) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; /* 第1步:打开GPIO和USART时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE); /* 第2步:将USART1 Tx@PA9的GPIO配置为推挽复用模式 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* 第3步:将USART1 Rx@PA10的GPIO配置为浮空输入模式 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* 第4步:配置USART1参数 */ USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); /* 第5步:使能 USART1, 配置完毕 */ USART_Cmd(USART1, ENABLE); } int fputc(int ch, FILE *f) { /* 写一个字节到USART1 */ USART_SendData(USART1, (uint8_t) ch); /* 等待发送结束 */ while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) {} return ch; } 程序运行结果 3.若干说明 xQueueHandle MsgQueue; 声明一个队列句柄,队列句柄可以理解成一个队列的标记,不同的队列具有不同的标记 MsgQueue = xQueueCreate( 5 , sizeof( int16_t ) ); 创建队列,即在内容中开辟固定大小的区域。FreeRTOS中需指定队列的深度和每个元素的字节长度,如果队列的深度为1那么便和uCOS的消息邮箱用法相似。 xQueueSend( MsgQueue, ( void* )&SendNum, 0 ); 向队列中填充内容,第二参数需要取出地址并进行类型转换,第三个参数设置等待时间,在队列满的情况下再往队列中填充内容的话便会阻塞任务,直到等待时间溢出;若此处填充的内容为0的话,则立即返回插入队列结果(成功或失败) xQueueReceive( MsgQueue, &ReceiveNum, 100/portTICK_RATE_MS ) 从队列中取出内容,第二个参数需要取出地址,第三个参数为等待最大时间,若在等待的时间内队列中没有数据则返回阻塞任务。 4.总结 FreeRTOS的队列简单易用,虽然和uCOS的实现细节存在差别但是使用的方法相同,在嵌入式操作系统的学习中主要是掌握队列的使用方法和场景,做到触类旁通。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1780 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1081 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
728 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1679 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
731浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
596浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
556浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 20:15 , Processed in 0.763240 second(s), Total 77, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号