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

西部数码 空间做2个网站2345浏览器电脑版首页

西部数码 空间做2个网站,2345浏览器电脑版首页,wordpress给帖子打分,jianux wordpress事件组 在 FreeRTOS 中#xff0c;事件组#xff08;Event Group#xff09;是一种用于任务间通信的机制#xff0c;用于在多个任务之间同步和传递事件。 事件组主要包含一下两个概念#xff1a; 事件标志位#xff08;Event Flags#xff09;#xff1a;每个事件标志…事件组 在 FreeRTOS 中事件组Event Group是一种用于任务间通信的机制用于在多个任务之间同步和传递事件。 事件组主要包含一下两个概念 事件标志位Event Flags每个事件标志位代表一个独立的事件状态。事件组控制块Event Group Control BlockEGCB事件组的信息结构体维护了事件标志位的状态等信息。 通过调用 FreeRTOS 提供的 API 函数任务可以进行如下操作 设置指定的事件标志位为已发生。查询事件标志位是否已经被设置。等待多个事件标志位中的任意一个或全部都被设置。 对于等待事件标志位的任务可以选择在等待时阻塞自己等待事件的发生也可以在等待时设置超时时间如果超时仍然没有事件发生则任务会自动解除阻塞并返回相应值。 事件组由 EventGroupHandle_t 类型的变量引用。 如果 configUSE_16_BIT_TICKS 如果 configUSE_16_BIT_TICKS 设置为 0则为 24。configUSE_16_BIT_TICKS 的值取决于 任务内部实现中用于线程本地存储的数据类型。 事件组中的所有事件位都 存储在 EventBits_t 类型的单个无符号整数变量中。 事件位 0 存储在位 0 中 事件位 1 存储在位1 中依此类推。 下图表示一个 24 位事件组 使用 3 个位来保存前面描述的 3 个示例事件。 在图片中仅设置了 事件位 2。 第一个餐厅的厨师(作为事件标志位) 回到我们厨子和吃货的世界中本次出场的只有厨子另外还有一些服务员服务员负责给厨子配菜这时候厨子做一个汉堡需要等待三样东西分别是面包、肉饼、蔬菜做蔬菜的服务员等肉饼做好后再做蔬菜做肉饼的则要等待做面包的而做面包的需要等待厨子的号令一切是那么的竟然有序。 代码共享位置https://wokwi.com/projects/362876432326851585 #define START_FLAG (1 0) #define BREAD_FLAG (1 1) #define MEAT_FLAG (1 2) #define VEGETABLE_FLAG (1 3) EventGroupHandle_t xEventHamburg NULL; // 做汉堡的事件组 // 面包服务员 void waiter_bread_task(void *param_t){EventBits_t uxBits;uxBits xEventGroupWaitBits(xEventHamburg, // 事件组句柄START_FLAG, // 等待开始事件pdTRUE, // 读取后清空标志位pdTRUE, // ADN关系1个值无所谓portMAX_DELAY);printf([BRED] 等到开始事件 : %X\n, uxBits);vTaskDelay(pdMS_TO_TICKS(random(500,2000)));uxBits xEventGroupSetBits(xEventHamburg, BREAD_FLAG); // 设置面包标志位printf([BRED] 面包已就绪 : %X\n, uxBits);vTaskDelete(NULL); } // 肉饼服务员 void waiter_meat_task(void *param_t){EventBits_t uxBits;uxBits xEventGroupWaitBits(xEventHamburg, // 事件组句柄BREAD_FLAG, // 等待面包事件pdFALSE, // 读取后不清空pdTRUE, // ADN关系1个值无所谓portMAX_DELAY);printf([MEAT] 等到面包做好 : %X\n, uxBits);vTaskDelay(pdMS_TO_TICKS(random(500,2000)));uxBits xEventGroupSetBits(xEventHamburg, MEAT_FLAG); // 设置肉饼标志位printf([MEAT] 肉饼已就绪 : %X\n, uxBits);vTaskDelete(NULL); } // 蔬菜服务员 void waiter_vegetable_task(void *param_t){EventBits_t uxBits;uxBits xEventGroupWaitBits(xEventHamburg, // 事件组句柄MEAT_FLAG, // 等待开始事件pdFALSE, // 读取后不清空pdTRUE, // ADN关系1个值无所谓portMAX_DELAY);printf([VEGE] 等到肉饼做好 : %X\n, uxBits);vTaskDelay(pdMS_TO_TICKS(random(500,2000)));uxBits xEventGroupSetBits(xEventHamburg, VEGETABLE_FLAG); // 设置蔬菜标志位printf([VEGE] 蔬菜已就绪 : %X\n, uxBits);vTaskDelete(NULL); } // 厨师线程 void chef_task(void *param_t){pinMode(4, INPUT_PULLUP);while(1){if(digitalRead(4) LOW){// 开始做汉堡EventBits_t uxBits; // 设置事件标志位的返回值uxBits xEventGroupSetBits(xEventHamburg, START_FLAG); // 这个返回值有可能会清空标志位具体读文档printf([CHEF] 开始做汉堡 %X\n, uxBits);uxBits xEventGroupWaitBits(xEventHamburg, // 事件句柄BREAD_FLAG | MEAT_FLAG | VEGETABLE_FLAG, // 等待代表面包、肉饼、蔬菜的标志位pdFALSE, // 是否清空对应标志位pdTRUE, // 等待的Bits判断关系 True为 AND, False为 ORportMAX_DELAY); // 等待超时时间printf([CHEF] 汉堡做完了 %X\n, uxBits);// 重置事件组xEventGroupClearBits(xEventHamburg, START_FLAG | BREAD_FLAG | MEAT_FLAG | VEGETABLE_FLAG);uxBits xEventGroupGetBits(xEventHamburg);printf([CHEF] 汉堡做好了我下班了 : %X\n, uxBits);vTaskDelete(NULL);}vTaskDelay(100);} } void setup() {Serial.begin(115200);xEventHamburg xEventGroupCreate(); //初始化事件组// 启动各个线程xTaskCreate(chef_task, Chef, 1024*2, NULL, 1, NULL);xTaskCreate(waiter_bread_task, Bread, 1024*2, NULL, 1, NULL);xTaskCreate(waiter_meat_task, Meat, 1024*2, NULL, 1, NULL);xTaskCreate(waiter_vegetable_task, Vegetable, 1024*2, NULL, 1, NULL); } void loop() {delay(100); }代码中首先在setup中通过 xEventGroupCreate 创建了一个事件组。 chef_task 中不断判断是否按下了按钮当按钮被按下时首先设置事件组的第一位为1表示开始信号此时的3个字节数据为此时事件组值为1 设置完之后就开始等待第2 3 4位的数据这里我们用的都是 xEventGroupWaitBits 等待该函数一共有5个参数函数原型如下 EventBits_t xEventGroupWaitBits(const EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToWaitFor,const BaseType_t xClearOnExit,const BaseType_t xWaitForAllBits,TickType_t xTicksToWait );xEventGroup 事件组句柄 uxBitsToWaitFor : 指定事件组中要测试的一个或多个事件位的按位值可以用 | 运算指定多个例如等待第0位则为1等待第二位则为2等待第三位则为4等待第四位则为8如果等待第1位和第三位则为1|35。 xClearOnExit 是否清除时间位设置为 pdTRUE 那么在作为 uxBitsToWaitFor 参数传递的值中设置的任何位 会在 xEventGroupWaitBits() 返回某个值之前在事件组中清除掉 前提是 xEventGroupWaitBits() 因超时以外的原因而返回值。 xWaitForAllBits 用于创建逻辑与测试 必须设置所有位或逻辑或测试必须设置一个 或多个位如下所示如果 xWaitForAllBits 设置为 pdTRUE 那么当在作为 uxBitsToWaitFor 参数传递的值中设置的所有位 均已在事件组中设置好或指定的阻塞时间已过期则 xEventGroupWaitBits() 会返回相应值。如果 xWaitForAllBits 设置为 pdFALSE那么当在作为 uxBitsToWaitFor 参数传递的值中设置的任何位已在事件组中设置好 或指定的阻塞时间已过期则 xEventGroupWaitBits() 会返回相应值。 xTicksToWait 超时时间。 这里我们等待选择不清空并且使用同时等待第2、3、4位事件都到达。 xEventGroupSetBits 函数有个返回值是当前事件组的值但需要注意的是因为执行完该函数后系统调度器会对任务进行一次调度看是否有任务等到了某个事件如果有事件被触发根据任务优先级会先执行另外的事件在返回。 因为在 waiter_bread_task 任务中等待该标志位的时候选择了清空标志位所以这时候获得的返回值为0其实我们已经设置了 START_FLAG 标志位可以通过修改 waiter_bread_task 任务中 xEventGroupWaitBits 函数的 xClearOnExit 测试。 待三个事件都到达时使用 xEventGroupClearBits 清空我们使用过的前四位。 waiter_bread_task 任务中首先等待 START_FLAG 时间到达也就是第一位置1这里的等待函数 xClearOnExit 参数位 pdTRUE表示当收到这个信号后将立刻清空。 此时任务组数据如下此时事件组值为0 然后通过 xEventGroupSetBits 函数设置第二位为1此时事件组值为2 waiter_meat_task 任务启动后一直等待 BREAD_FLAG 事件到达当事件到达后通过 xEventGroupSetBits(xEventHamburg, BREAD_FLAG) 设置事件组为6 waiter_vegetable_task 任务启动后一直等待 MEAT_FLAG 事件到达 当事件到达后通过 xEventGroupSetBits(xEventHamburg, VEGETABLE_FLAG) 设置事件组为14也就是E 最后回到 chef_task 任务中等待三个值凑齐继续往下执行通过 xEventGroupClearBits(xEventHamburg, START_FLAG | BREAD_FLAG | MEAT_FLAG | VEGETABLE_FLAG) 清空事件组此时事件组值再次归零。 标志位的应用方向 事件标志为用于按顺序执行的业务逻辑举一个智慧物流的例子机械臂为一辆自动行驶的电动车装载上货物电动车开到指定的厂房中间需要经过一个电动门。机械臂收到指令后触发装货的信号等装完货之后机械臂又触发小车的移动信号等小车移动到门口的时候又触发电动门开闸的信号然后等电动门开启完毕后再给小车一个移动的信号以此类推直到小车运到下一个厂房机械臂将货物卸下。 这里边用到了多个信号量协同但是他们之间是有顺序关系的。 二号餐厅的厨师(改进的标志位) 在一号餐厅中所有服务员必须等上一名服务员完成工作后才会做自己的工作但本质上面包、肉饼和蔬菜的准备并不是顺序关系而是并行关系三个线程完全可以独立运行他们只需要共同等待一个开始信号信号到达后各自做自己的工作而厨师的任务与他们三个是并行的所以厨师还是需要等待另外三个人工作完成后才能开动。 所以我们需要对第一个餐厅的代码进行一次修改 代码共享位置https://wokwi.com/projects/362946353284773889 #define START_FLAG (1 0) #define BREAD_FLAG (1 1) #define MEAT_FLAG (1 2) #define VEGETABLE_FLAG (1 3) EventGroupHandle_t xEventHamburg NULL; // 做汉堡的事件组 // 面包服务员 void waiter_bread_task(void *param_t){EventBits_t uxBits;uxBits xEventGroupWaitBits(xEventHamburg, // 事件组句柄START_FLAG, // 等待开始事件pdFALSE, // 读取后不清空标志位pdTRUE, // ADN关系1个值无所谓portMAX_DELAY);printf([BRED] 等到开始事件 : %X\n, uxBits);vTaskDelay(pdMS_TO_TICKS(random(500,2000)));uxBits xEventGroupSetBits(xEventHamburg, BREAD_FLAG); // 设置面包标志位printf([BRED] 面包已就绪 : %X\n, uxBits);vTaskDelete(NULL); } // 肉饼服务员 void waiter_meat_task(void *param_t){EventBits_t uxBits;uxBits xEventGroupWaitBits(xEventHamburg, // 事件组句柄START_FLAG, // 等待开始事件pdFALSE, // 读取后不清空标志位pdTRUE, // ADN关系1个值无所谓portMAX_DELAY);printf([MEAT] 等到开始事件 : %X\n, uxBits);vTaskDelay(pdMS_TO_TICKS(random(500,2000)));uxBits xEventGroupSetBits(xEventHamburg, MEAT_FLAG); // 设置肉饼标志位printf([MEAT] 肉饼已就绪 : %X\n, uxBits);vTaskDelete(NULL); } // 蔬菜服务员 void waiter_vegetable_task(void *param_t){EventBits_t uxBits;uxBits xEventGroupWaitBits(xEventHamburg, // 事件组句柄START_FLAG, // 等待开始事件pdFALSE, // 读取后不清空标志位pdTRUE, // ADN关系1个值无所谓portMAX_DELAY);printf([VEGE] 等到开始事件 : %X\n, uxBits);vTaskDelay(pdMS_TO_TICKS(random(500,2000)));uxBits xEventGroupSetBits(xEventHamburg, VEGETABLE_FLAG); // 设置蔬菜标志位printf([VEGE] 蔬菜已就绪 : %X\n, uxBits);vTaskDelete(NULL); } // 厨师线程 void chef_task(void *param_t){pinMode(4, INPUT_PULLUP);while(1){if(digitalRead(4) LOW){// 开始做汉堡EventBits_t uxBits; // 设置事件标志位的返回值uxBits xEventGroupSetBits(xEventHamburg, START_FLAG); // 这个返回值有可能会清空标志位具体读文档printf([CHEF] 开始做汉堡 %X\n, uxBits);uxBits xEventGroupWaitBits(xEventHamburg, // 事件句柄BREAD_FLAG | MEAT_FLAG | VEGETABLE_FLAG, // 等待代表面包、肉饼、蔬菜的标志位pdFALSE, // 是否清空对应标志位pdTRUE, // 等待的Bits判断关系 True为 AND, False为 ORportMAX_DELAY); // 等待超时时间printf([CHEF] 汉堡做完了 %X\n, uxBits);// 重置事件组xEventGroupClearBits(xEventHamburg, START_FLAG | BREAD_FLAG | MEAT_FLAG | VEGETABLE_FLAG);uxBits xEventGroupGetBits(xEventHamburg);printf([CHEF] 汉堡做好了我下班了 : %X\n, uxBits);vTaskDelete(NULL);}vTaskDelay(100);} } void setup() {Serial.begin(115200);xEventHamburg xEventGroupCreate(); //初始化事件组// 启动各个线程xTaskCreate(chef_task, Chef, 1024*2, NULL, 1, NULL);xTaskCreate(waiter_bread_task, Bread, 1024*2, NULL, 1, NULL);xTaskCreate(waiter_meat_task, Meat, 1024*2, NULL, 1, NULL);xTaskCreate(waiter_vegetable_task, Vegetable, 1024*2, NULL, 1, NULL); } void loop() {delay(100); }这个例程基本和第一个例程是一样的只是我们等待的标志位发生了改变让所有的服务员都等待 START_FLAG 的信号而所有人都不得清空这个信号如果一旦有一个人清空了那后面有人就会丢失这个信号。 此类表示为的应用方向 还是以智慧物流为例我们现在的需求是用一辆车运送三个物资到另外的仓库中当我们下达指令之后调取物资的机械手并不是顺序运行的而是各自运行寻找物资待物资全部装车后车才会启动。这时候就由运货车或调度台发送一个“运送”指令电动车就为等待三个机械臂分别寻找和装在三种物资到车上待所有物资都齐全之后电动车发车。 三号餐厅的厨师同步 当这三种配料都准备齐的时候厨子才开始制作汉堡而这时候所有的服务员都已经下班走了厨师就不爽了凭什么你们做完都走了我还在工作 所以三号餐厅的厨师给老板提了个建议说要有些服务员的工作太轻松了下班太早不利于同事间的团结所以我建议我们必须等到所有人的工作完成之后大家一起下班。 黑心老板也采纳了这个建议于是同步就出现了 代码共享地址https://wokwi.com/projects/362947317933844481 #define BURG_FLAG (1 0) #define BREAD_FLAG (1 1) #define MEAT_FLAG (1 2) #define VEGETABLE_FLAG (1 3) EventGroupHandle_t xEventHamburg NULL; // 做汉堡的事件组 // 面包服务员 void waiter_bread_task(void *param_t){EventBits_t uxBits;printf([BRED] 骂骂咧咧的开始烤面包...\n);vTaskDelay(pdMS_TO_TICKS(random(1000,5000)));printf([BRED] 面包烤好了我打算设置标志位\n);uxBits xEventGroupSync(xEventHamburg, // 事件句柄BREAD_FLAG, // 要设置的标志位BURG_FLAG | BREAD_FLAG | MEAT_FLAG | VEGETABLE_FLAG, // 同步等待的标志位portMAX_DELAY); // 超时时间printf([BRED] 面包已就绪 : %X\n, uxBits);vTaskDelete(NULL); } // 肉饼服务员 void waiter_meat_task(void *param_t){EventBits_t uxBits;printf([MEAT] 叽叽歪歪的开始煎肉饼...\n);vTaskDelay(pdMS_TO_TICKS(random(1000,5000)));printf([MEAT] 肉饼煎好了我打算设置标志位\n);uxBits xEventGroupSync(xEventHamburg, // 事件句柄MEAT_FLAG, // 要设置的标志位BURG_FLAG | BREAD_FLAG | MEAT_FLAG | VEGETABLE_FLAG, // 同步等待的标志位portMAX_DELAY); // 超时时间printf([MEAT] 肉饼已就绪 : %X\n, uxBits);vTaskDelete(NULL); } // 蔬菜服务员 void waiter_vegetable_task(void *param_t){EventBits_t uxBits;printf([VEGE] 哼哼吱吱的做开始洗蔬菜...\n);vTaskDelay(pdMS_TO_TICKS(random(1000,5000)));printf([VEGE] 蔬菜洗好了我打算设置标志位\n);uxBits xEventGroupSync(xEventHamburg, // 事件句柄VEGETABLE_FLAG, // 要设置的标志位BURG_FLAG | BREAD_FLAG | MEAT_FLAG | VEGETABLE_FLAG, // 同步等待的标志位portMAX_DELAY); // 超时时间printf([VEGE] 蔬菜已就绪 : %X\n, uxBits);vTaskDelete(NULL); } // 厨师线程 void chef_task(void *param_t){pinMode(4, INPUT_PULLUP);EventBits_t uxBits;while(1){if(digitalRead(4) LOW){// 开始做汉堡printf([CHEF] 美滋滋的做开始磨洋工...\n);uxBits xEventGroupSync(xEventHamburg, // 事件句柄BURG_FLAG, // 要设置的标志位BURG_FLAG | BREAD_FLAG | MEAT_FLAG | VEGETABLE_FLAG, // 同步等待的标志位portMAX_DELAY); // 超时时间printf([CHEF] 汉堡做好了大家可以下班了 : %X\n, uxBits);vTaskDelete(NULL);}vTaskDelay(100);} } void setup() {Serial.begin(115200);xEventHamburg xEventGroupCreate(); //初始化事件组// 启动各个线程xTaskCreate(chef_task, Chef, 1024*2, NULL, 1, NULL);xTaskCreate(waiter_bread_task, Bread, 1024*2, NULL, 1, NULL);xTaskCreate(waiter_meat_task, Meat, 1024*2, NULL, 1, NULL);xTaskCreate(waiter_vegetable_task, Vegetable, 1024*2, NULL, 1, NULL); } void loop() {delay(100); }在上面的代码中我们把原来的 START_FLAG 改成了 BURG_FLAG 表示汉堡就绪的标志位所有线程启动后就开始忙碌自己的工作了当忙完之后就把自己的标志位设置成1同时等待其他四位同时的标志位只有 chef_task 的线程是等待我们操作按钮的。 如果我们启动后不按按钮那另外三个线程依然会把自己的事情做完然后开始等待厨子 但如果启动后马上按动按钮那么厨子是会提前把自己的汉堡做完同时等待另外几个同事的所以这里的例子在实际生活中可能有些不合理。 例程中我们用到了一个新的函数同步函数 EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToSet,const EventBits_t uxBitsToWaitFor,TickType_t xTicksToWait );该函数的作用是 将指定标志位设置为1同时等待其他标志位到达后继续执行。 xEventGroup 事件句柄; uxBitsToSet 在确定且可能等待uxBitsToWait参数指定的所有位 设置完成之前 要设置事件组中的一个或多个位。 uxBitsToWaitFor指定事件组中要测试的一个或多个事件位 的按位值。 xTicksToWait等待时间。 需要注意的是uxBitsToSet 参数可以是一个位也可以是是多个位使用或运算符|拼接但 uxBitsToSet 的值并不一定非得包含在 uxBitsToWaitFor 中。 同步事件组的应用方向 以动车组为例动车组和普通火车的区别在于每节车厢都是一个独立的系统都各自提供动力运行所以才叫动车组所以动车组在运行的时候必须等待所有列车就绪的信号才能发车这样才能最大的节省能量提高效率。 动车组在开车前先要装在每节车厢的乘客然后各自关门当1号车厢的门关闭后发出一个同步信号并等待其他车厢就绪陆续所有车厢的门关闭之后大家一同出发。 需要注意的是每节车厢关门就绪的时间是不同的但最终所有车厢是需要在同一时间发车的所有车厢是并行的如果再用标志位的方式就无法实现了或者实现起来很啰嗦所以就用到了 同步 的概念。 关于事件组的所有API可以参考https://www.freertos.org/zh-cn-cmn-s/event-groups-API.html
http://www.zqtcl.cn/news/32020/

相关文章:

  • 九江网站建设排行榜网络商城营业执照经营范围
  • 个人网站对应网站网址系统建设方案怎么写
  • 商场网站模板万江区网站仿做
  • 做网赌网站怎么推广拉人可视化网站设计工具
  • 大尺度做爰网站个人网站制作 教程
  • 揭阳网站制作专业深圳免费网站建设服务
  • 网站如何做分布式周口网站制作哪家好
  • 北京网站建设模板案例中国建设银行网站个人
  • 银行网站建设中工信部网站备案号
  • 我的世界做壁纸的网站seo优化服务是什么
  • 怎么做卖车网站不提供花架子网站 我
  • 开发一个网站程序员常用的工具有哪些
  • 中国做网站公司排名网站建设与推广王钊
  • 建设工程八大员考试网站互联网专属保险什么意思
  • 电子商务的建站流程wordpress后台加载慢
  • 网站建设方案是什么意思创意合肥网站建设
  • 镇江外贸网站建设创意产品设计作品图片
  • 中国企业网站设计案例软件技术专业升本可以升哪些专业
  • 怎么仿制网站wordpress 安装不了
  • 专业点的网站制作公司沈阳人流需要多少钱大概多少钱
  • 潍坊网站定制模板建站电脑版传奇网站
  • 怎样保存网站资料做证据wordpress portfolio 缩略图
  • 泉州app网站开发价格wordpress付费文章
  • 河北燕郊网站制作如何查询网站的主机
  • 常德网站建大连装修公司排名前十名
  • 深圳建设交易网站网站的关键词库怎么做的那么多
  • 3322做网站网站建设的多少钱
  • 深圳做英文网站的公司上海施工单位
  • 网站布局怎么设计泰安网站建设企业
  • 网站添加百度商桥如何在云服务器上搭建网站