如何保护自己的网站,中山 网站设计,seo网站后台管理,中国建设银行网站官网下载安装一、简介
1、队列简介#xff1a;
队列#xff1a;是任务到任务#xff0c;任务到中断、中断到任务数据交流的一种机制#xff08;消息传递#xff09;。 FreeRTOS基于队列#xff0c;实现了多种功能#xff0c;其中包括队列集、互斥信号量、计数型信号量、二值信号量…一、简介
1、队列简介
队列是任务到任务任务到中断、中断到任务数据交流的一种机制消息传递。 FreeRTOS基于队列实现了多种功能其中包括队列集、互斥信号量、计数型信号量、二值信号量、递归互斥信号量因此很有必要深入了解FreeRTOS的队列。
中断一关闭就不会出现任务切换以防多个任务同时操作队列
2、FreeRTOS队列特点 1.数据入队出队方式先进先出 2.数据传递方式实际值 3.多任务访问 4. 出队、入队堵塞 问题当多个任务写入消息给一个“满队列”时这些任务都会进入阻塞状态也就是说有多个任务 在等待同一 个队列的空间。那当队列中有空间时哪个任务会进入就绪态
答 1、优先级最高的任务 2、如果大家的优先级相同那等待时间最久的任务会进入就绪态
注我始终认为自己不是一个很聪明的人所以这些理论知识我都是浅尝辄止量力而行。
3、往队列写入消息API函数
4、从队列读取消息API函数 二、实验
1、实验步骤 2、代码
main.c
#include stm32f10x.h
#include FreeRTOS.h
#include task.h
#include freertos_demo.h
#include Delay.h
#include sys.h
#include usart.h
#include LED.h
#include Key.hint main(void){ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组 4 uart_init(115200); delay_init();Key_Init();LED_Init();// 创建任务FrrrRTOS_Demo();}
freertos_demo.c
#include FreeRTOS.h
#include task.h
#include queue.h
#include LED.h
#include Key.h
#include usart.h
#include delay.h/******************************************************************任务配置****************************************************/
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_TASK_STACK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);//任务优先级
#define TASK1_PRIO 2
//任务堆栈大小
#define TASK1_STACK_SIZE 128
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);//任务优先级
#define TASK2_PRIO 3
//任务堆栈大小
#define TASK2_STACK_SIZE 128
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);//任务优先级
#define TASK3_PRIO 4
//任务堆栈大小
#define TASK3_STACK_SIZE 128
//任务句柄
TaskHandle_t Task3_Handler;
//任务函数
void task3(void *pvParameters);char task_buffer[500]; //用于存储系统中任务信息表格/******************************************************************任务函数****************************************************/
QueueHandle_t key_queue; //小数据句柄
QueueHandle_t big_data_queue; //大数据 句柄
char buff[100] {苍天已死黄天当立岁在甲子天下大吉};
void FrrrRTOS_Demo(void)
{key_queue xQueueCreate(2, sizeof(uint8_t));if(key_queue ! NULL){printf(\r\nkey_queue队列创建成功!\r\n);}else{ printf(key_queue队列创建失败!\r\n); }big_data_queue xQueueCreate(1, sizeof(char *));if(big_data_queue ! NULL){printf(big_data_queue队列创建成功!\r\n);}else{ printf(big_data_queue队列创建失败!\r\n); }//创建开始任务xTaskCreate((TaskFunction_t )start_task, //任务函数( char* )start_task, //任务名称(uint16_t )START_TASK_STACK_SIZE, //任务堆栈大小(void* )NULL, //传递给任务函数的参数(UBaseType_t )START_TASK_PRIO, //任务优先级(TaskHandle_t* )StartTask_Handler); //任务句柄 // 启动任务调度vTaskStartScheduler();}void start_task(void *pvParameters)
{taskENTER_CRITICAL(); //进入临界区//创建1任务xTaskCreate((TaskFunction_t )task1, (const char* )task1, (uint16_t )TASK1_STACK_SIZE, (void* )NULL, (UBaseType_t )TASK1_PRIO, (TaskHandle_t* )Task1_Handler); //创建2任务xTaskCreate((TaskFunction_t )task2, (const char* )task2, (uint16_t )TASK2_STACK_SIZE, (void* )NULL,(UBaseType_t )TASK2_PRIO,(TaskHandle_t* )Task2_Handler); //创建3任务xTaskCreate((TaskFunction_t )task3, (const char* )task3, (uint16_t )TASK3_STACK_SIZE, (void* )NULL,(UBaseType_t )TASK3_PRIO,(TaskHandle_t* )Task3_Handler); vTaskDelete(NULL); //删除开始任务taskEXIT_CRITICAL(); //退出临界区
}//1 任务函数
void task1(void *pvParameters)
{uint8_t key 0;BaseType_t err;char *buf;buf buff[0];while(1){key Key_GetNum();if(key 1 || key 2){err xQueueSend( key_queue, key, portMAX_DELAY );if(err ! pdTRUE){printf(key_queue队列发送失败\r\n);}}else if(key 3){err xQueueSend( big_data_queue, buf, portMAX_DELAY );if(err ! pdTRUE){printf(key_queue队列发送失败\r\n);}}vTaskDelay(50);}
}// 任务2 小数据出队函数
void task2(void *pvParameters)
{uint8_t key 0;BaseType_t err 0;// 任务主循环while (1){err xQueueReceive( key_queue,key,portMAX_DELAY );if(err ! pdTRUE){printf(key_queue队列读取失败\r\n); }else{printf(key %d\r\n,key);};}
}//不调用系统延时函数因为xQueueReceive函数如果读取完队列里面的数据就会由就绪态转变为阻塞态// 任务3 大数据出队函数
void task3(void *pvParameters)
{ char * buf;BaseType_t err 0;// 任务主循环while (1){err xQueueReceive( big_data_queue, buf, portMAX_DELAY);if(err ! pdTRUE){printf(big_data_queue队列读取失败\r\n); }else{printf(key %s\r\n,buf);};}
}key.c
#include stm32f10x.h // Device header
#include FreeRTOS.h
#include task.h
#include usart.h
#include Delay.h/*** 函 数按键初始化* 参 数无* 返 回 值无* 按键PB4/PB12/PB14*/
void Key_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启GPIOB的时钟/*GPIO初始化*/GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin GPIO_Pin_4 | GPIO_Pin_12 | GPIO_Pin_14;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOB, GPIO_InitStructure); }/*** 函 数按键获取键码* 参 数无* 返 回 值按下按键的键码值范围0~3返回0代表没有按键按下* 注意事项此函数是阻塞式操作当按键按住不放时函数会卡住直到按键松手*/
uint8_t Key_GetNum(void)
{uint8_t KeyNum 0; //定义变量默认键码值为0if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) 0) //读PB4输入寄存器的状态如果为0则代表按键1按下{KeyNum GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4);printf(KeyNum %d\r\n,KeyNum);delay_xms(20); //延时消抖while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) 0); //等待按键松手delay_xms(20); //延时消抖KeyNum 1; //置键码为1}if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12) 0) {KeyNum GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12);printf(KeyNum %d\r\n,KeyNum);delay_xms(20); while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12) 0); delay_xms(20); KeyNum 2; }if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) 0) {KeyNum GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14);printf(KeyNum %d\r\n,KeyNum);delay_xms(20); while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) 0); delay_xms(20); KeyNum 3; }return KeyNum; //返回键码值如果没有按键按下所有if都不成立则键码为默认值0
} 3、实验结果解析
开始运行 按下按键1PB4
按下按键1就会往队列key_queue里面写入key值1然后任务切换到task2将队列key_queue里面的数据读取出来 按下按键2PB12
按下按键2就会往队列key_queue里面写入key值2然后任务切换到task2将队列key_queue里面的数据读取出来 按下按键3PB14
按下按键2就会往队列big_data_queue里面写入key值3然后任务切换到task3将队列big_data_queue里面的数据读取出来 三、重点
使用队列相关函数时需要将下面宏置1默认是1 #define configSUPPORT_DYNAMIC_ALLOCATION 1 队列创建函数 xQueueCreate( uxQueueLength, uxItemSize ) //uxQueueLength队列长度uxItemSize 队列参数的大小 队列写入消息函数 xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) //xQueue待写入的队列pvItemToQueue待写入的消息xTicksToWait阻塞超时时间 队列读取消息函数 xQueueReceive( QueueHandle_t xQueue,void * const pvBuffer,TickType_t xTicksToWait ) //xQueue待读取的队列pvBuffer信息读取缓冲区xTicksToWait阻塞超时时间 问题任务2task2和任务3task3没有系统延时函数xTaskDelay按优先级来说应该一直执行任务3task3复位后却先执行了任务1task1
答因为xQueueReceive和xQueueSend函数如果读取完或写入完队列里面的数据自动会使任务由就绪态转变为阻塞态知道队列里面有数据可以写入或者读出
文章转载自: http://www.morning.ptmch.com.gov.cn.ptmch.com http://www.morning.rkdw.cn.gov.cn.rkdw.cn http://www.morning.yrjym.cn.gov.cn.yrjym.cn http://www.morning.gnghp.cn.gov.cn.gnghp.cn http://www.morning.qjlkp.cn.gov.cn.qjlkp.cn http://www.morning.drtgt.cn.gov.cn.drtgt.cn http://www.morning.rfbq.cn.gov.cn.rfbq.cn http://www.morning.wwjft.cn.gov.cn.wwjft.cn http://www.morning.hdqqr.cn.gov.cn.hdqqr.cn http://www.morning.kwqqs.cn.gov.cn.kwqqs.cn http://www.morning.phlrp.cn.gov.cn.phlrp.cn http://www.morning.jngdh.cn.gov.cn.jngdh.cn http://www.morning.lbfgq.cn.gov.cn.lbfgq.cn http://www.morning.djxnw.cn.gov.cn.djxnw.cn http://www.morning.wrlxy.cn.gov.cn.wrlxy.cn http://www.morning.pqfbk.cn.gov.cn.pqfbk.cn http://www.morning.knryp.cn.gov.cn.knryp.cn http://www.morning.brps.cn.gov.cn.brps.cn http://www.morning.mkkcr.cn.gov.cn.mkkcr.cn http://www.morning.rxlk.cn.gov.cn.rxlk.cn http://www.morning.zbnts.cn.gov.cn.zbnts.cn http://www.morning.fhcwm.cn.gov.cn.fhcwm.cn http://www.morning.dlbpn.cn.gov.cn.dlbpn.cn http://www.morning.chfxz.cn.gov.cn.chfxz.cn http://www.morning.yrmgh.cn.gov.cn.yrmgh.cn http://www.morning.ngdkn.cn.gov.cn.ngdkn.cn http://www.morning.wmfmj.cn.gov.cn.wmfmj.cn http://www.morning.kyflr.cn.gov.cn.kyflr.cn http://www.morning.kmqlf.cn.gov.cn.kmqlf.cn http://www.morning.mfzyn.cn.gov.cn.mfzyn.cn http://www.morning.wrtsm.cn.gov.cn.wrtsm.cn http://www.morning.hfytgp.cn.gov.cn.hfytgp.cn http://www.morning.mrbmc.cn.gov.cn.mrbmc.cn http://www.morning.iqcge.com.gov.cn.iqcge.com http://www.morning.lkbyq.cn.gov.cn.lkbyq.cn http://www.morning.dytqf.cn.gov.cn.dytqf.cn http://www.morning.rrxnz.cn.gov.cn.rrxnz.cn http://www.morning.prmbb.cn.gov.cn.prmbb.cn http://www.morning.ckhry.cn.gov.cn.ckhry.cn http://www.morning.ymdhq.cn.gov.cn.ymdhq.cn http://www.morning.xgzwj.cn.gov.cn.xgzwj.cn http://www.morning.plxhq.cn.gov.cn.plxhq.cn http://www.morning.rzmzm.cn.gov.cn.rzmzm.cn http://www.morning.jlpdc.cn.gov.cn.jlpdc.cn http://www.morning.gpxbc.cn.gov.cn.gpxbc.cn http://www.morning.hytr.cn.gov.cn.hytr.cn http://www.morning.lbfgq.cn.gov.cn.lbfgq.cn http://www.morning.krlsz.cn.gov.cn.krlsz.cn http://www.morning.rnpnn.cn.gov.cn.rnpnn.cn http://www.morning.ppgdp.cn.gov.cn.ppgdp.cn http://www.morning.fkwgk.cn.gov.cn.fkwgk.cn http://www.morning.qnlbb.cn.gov.cn.qnlbb.cn http://www.morning.rkdzm.cn.gov.cn.rkdzm.cn http://www.morning.frtt.cn.gov.cn.frtt.cn http://www.morning.rshijie.com.gov.cn.rshijie.com http://www.morning.gkjnz.cn.gov.cn.gkjnz.cn http://www.morning.xhlpn.cn.gov.cn.xhlpn.cn http://www.morning.fbxlj.cn.gov.cn.fbxlj.cn http://www.morning.yfffg.cn.gov.cn.yfffg.cn http://www.morning.dgckn.cn.gov.cn.dgckn.cn http://www.morning.mmynk.cn.gov.cn.mmynk.cn http://www.morning.xqxlb.cn.gov.cn.xqxlb.cn http://www.morning.wslpk.cn.gov.cn.wslpk.cn http://www.morning.langlaitech.cn.gov.cn.langlaitech.cn http://www.morning.lrylj.cn.gov.cn.lrylj.cn http://www.morning.wjqyt.cn.gov.cn.wjqyt.cn http://www.morning.zthln.cn.gov.cn.zthln.cn http://www.morning.mrbmc.cn.gov.cn.mrbmc.cn http://www.morning.tfznk.cn.gov.cn.tfznk.cn http://www.morning.gbcxb.cn.gov.cn.gbcxb.cn http://www.morning.wngpq.cn.gov.cn.wngpq.cn http://www.morning.gsrh.cn.gov.cn.gsrh.cn http://www.morning.sfwcx.cn.gov.cn.sfwcx.cn http://www.morning.qcnk.cn.gov.cn.qcnk.cn http://www.morning.wjlrw.cn.gov.cn.wjlrw.cn http://www.morning.rbqlw.cn.gov.cn.rbqlw.cn http://www.morning.srnhk.cn.gov.cn.srnhk.cn http://www.morning.htbsk.cn.gov.cn.htbsk.cn http://www.morning.ksgjn.cn.gov.cn.ksgjn.cn http://www.morning.hysqx.cn.gov.cn.hysqx.cn