当前位置: 首页 > news >正文

商洛网站开发公司国际新闻头条最新消息

商洛网站开发公司,国际新闻头条最新消息,做网站公司logo,三水网站制作公司一、简介 1、队列简介: 队列:是任务到任务,任务到中断、中断到任务数据交流的一种机制(消息传递)。 FreeRTOS基于队列,实现了多种功能,其中包括队列集、互斥信号量、计数型信号量、二值信号量…

一、简介

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.h"int 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、实验结果解析

开始运行:

按下按键1(PB4):

按下按键1,就会往队列key_queue里面写入key值(1),然后任务切换到task2将队列key_queue里面的数据读取出来;;

按下按键2(PB12):

按下按键2,就会往队列key_queue里面写入key值(2),然后任务切换到task2将队列key_queue里面的数据读取出来;

按下按键3(PB14) :

按下按键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:阻塞超时时间

问题:任务2(task2)和任务3(task3)没有系统延时函数(xTaskDelay()),按优先级来说应该一直执行任务3(task3),复位后却先执行了任务1(task1)?

答:因为xQueueReceive()和xQueueSend()函数,如果读取完或写入完队列里面的数据,自动会使任务由就绪态转变为阻塞态,知道队列里面有数据可以写入或者读出;

http://www.hkea.cn/news/187863/

相关文章:

  • 做网站去哪个平台资源优化排名网站
  • 备案的网站名称可以改吗百度青岛代理公司
  • 专做进口批发的网站关键词优化多少钱
  • 做网站有了空间在备案吗百度权重高的网站有哪些
  • 做空间的网站著名的网络营销案例
  • 做网站客户尾款老不给怎么办百度推广年费多少钱
  • 想要将网站信息插到文本链接怎么做百度关键词搜索
  • 江苏网站备案要多久seo域名综合查询
  • 大型网站建设机构津seo快速排名
  • 建设证件查询官方网站宁波做网站的公司
  • 那些网站招聘在家里做的客服网店推广策略
  • 湘西 网站 建设 公司sem代运营托管公司
  • 用css为wordpress排版西安seo外包服务
  • vs2005做网站百度推广官方网站登录入口
  • 乐从网站建设公司北京seo优化推广
  • 如何在网上接做网站的小项目市场监督管理局电话
  • 淘宝购物站优化
  • 石家庄最新疫情轨迹河南网站优化公司哪家好
  • 网站色彩搭配服务器ip域名解析
  • 哪个网站专业做安防如何注册域名网站
  • 穆棱市住房和城乡建设局网站关键词词库
  • 成都网站建设市场什么是网络营销的核心
  • 深圳找人做网站廊坊优化外包
  • 衡阳市城市建设投资有限公司网站湖南企业seo优化报价
  • css做网站常用百度权重优化软件
  • 合合肥网站建设制作网站用什么软件
  • 杭州网站设计公司推荐网络推广与优化
  • 移动惠生活app下载网址荆门网站seo
  • 做网站很赚钱吗关键词自助优化
  • wordpress小工具里的用户中心南京谷歌优化