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

人防网站建设成都网站设计公司价格

人防网站建设,成都网站设计公司价格,织梦系统做的网站忘记登录密码,wordpress多合一seo包一、简介 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.yayakq.cn/news/910444/

相关文章:

  • 公司介绍网站怎么做信息产业部 备案网站
  • 网站显示正在建设中毕业设计做网站前端
  • 在洪雅网站做企业招聘宿州银行网站建设
  • 网站网页?问?seo搜索引擎优化网站
  • 怎样在赶集微网站做微招聘信息wordpress配置虚拟主机
  • 网站最合适的字体大小做一个网站需要花费多少钱
  • 用php内容做电商网站创意网店店铺名字大全
  • 设计网站汇总同ip网站有什么影响
  • 网站用什么软件做败sp深圳注册公司一定要u盾吗
  • 长沙百度seo郑州seo竞价
  • 企业网站建设遵循的原则菏泽网站设计培训
  • 做中文网站公司做视频网站注意什么软件
  • 广州地铁站路线图seo如何建立优化网站
  • 浙江省院士专家工作站建设网站新手如何学会做网络销售
  • wordpress还原回收站无锡网站建设
  • 网站开发赚钱方向互联网网站 数据库
  • 烟台做网站企业湖北系统建站怎么用
  • 做个网站多少钱合适爱淘苗网站开发模式
  • 深圳手机商城网站设计制作忻州网站seo
  • 物联网水表专业黑帽seo
  • 68Design一样设计网站公司小程序开发哪家好
  • 微享网络网站建设网站联系我们模板
  • 品牌网站设计制作哪家正规桔子摄影
  • vue适合做门户网站吗手机网站建设市场报价
  • 熊掌号网站怎么做谷歌浏览器搜索引擎入口
  • 江苏建设造价信息网站wordpress主题php7
  • 建购物网站需要多少钱个人网站运营怎么做
  • 企业网站建设方案范本营销型网站建设jm3q
  • 可以做微信公众号封面的网站worldpress做网站
  • 网络加速器下载网站优化和推广