开源硬件
Arduino
客制化键盘
Arduino_寄存器
二进制运算
寄存器+二进制运算
LCD-逐字显示
密码依次录入
等待输入
WiFi Duck(无线击键注入攻击平台)
WiFi Duc-New
WiFi Duc-Old
蓝牙无线烧录
ESP8266
ESP-NOW
ESP8266看门狗
ESP8266-休眠模式
ESP01/01S使用说明
WIFI_SD
ESP8266-Web服务器
ESP8266-WIFI自动认证
ESP32
ESP32 ADC2
ESP32_PWM
ESP32_CAM
ESP32 小坦克
ESP32_限电保护
Arduino IDE 添加 ESP32
ESP32-iPhone BLE攻击
STM32
STM32F103-虚拟键盘
STC
STC8G1K08(A)
树莓派-触摸屏
Arduino IDE
Arduino_自制库
Arduino库收集
常见排序算法
冒泡排序
选择排序
插入排序
希尔排序
归并排序
快速排序
计数排序
预处理
millis(运行时长)
Arduino IDE 2.X-修改数据位置
Mixly
Mixly安装教程
Mixly 模块介绍
Mixly-添加ESP32CAM支持
Mixly-库定制工具
模块
4G模块连接物联网
GPS模块
语音模块(JQ8900)
安信可VB语音识别
28BYJ-48(5V步进)
FreeRTOS
FreeRTOS-多任务基础
FreeRTOS-任务共享全局变量
FreeRTOS-多核多任务
FreeRTOS-MUTEX
FreeRTOS-常规程序改多任务
FreeRTOS-定时器
LaserGRBL(激光雕刻)
LaserGRBL-GRBL
GRBL-CNC Shield v4
MicroPython
Scratch
Wokwi(在线仿真)
html转无符号数组
待做开源项目
本文档使用 MrDoc 发布
-
+
首页
FreeRTOS-任务共享全局变量
## 全局变量传输数据 `可以有多个读任务,但只能有一个写任务` `变量类型必须等于CPU和内存的通道尺寸` > 如 ESP32 是32位的单片机,一次操作最多操作32个bit > 变量必须定义为32个bit=4byte(int/long是4个字节) ```c++ // 养成良好习惯,被多进程和中断调用的变量使用 volatile 修饰符(易挥发性,防止程序给优化掉) volatile uint32_t inventory = 100; //总库存 volatile uint32_t retailCount = 0; //线下销售量 // uint32_t,u表示等于正数,32表示32个bit // 计算销售 void retailTask(void *pvParam) { while (1) { //随机延迟 for (int i; i < random(10, 100); i++) vTaskDelay(pdMS_TO_TICKS(i)); if (inventory > 0) { inventory--; //总库存 retailCount++; //销售量 } }; vTaskDelay(10); //老板要求慢一些,客户升级后,可以再加快速度 } // 显示销售 void showTask(void *pvParam) { while (1) { printf("库存 : %d", inventory); printf(" 零售 : %d\n", retailCount); if (inventory == 0 ) { printf("\n-----销售总结-----\n"); printf(" 总销售额: %d\n\n", retailCount); } // pdMS_TO_TICKS(),ms转tick vTaskDelay(pdMS_TO_TICKS(100)); } } void setup() { Serial.begin(115200); // 创建两个任务,分别对应计算销售和显示库存 xTaskCreate(retailTask, "计算销售",1024 * 4,NULL,1,NULL); xTaskCreate(showTask, "显示库存",1024 * 4,NULL,1,NULL); } void loop() { } ``` ### 全局变量错误案例 `这个实例就是同时有两个写操作而造成的` ```c++ // 养成良好习惯,被多进程和中断调用的变量使用 volatile 修饰符(易挥发性,防止程序给优化掉) volatile uint16_t inventory = 100; //总库存 volatile uint32_t retailCount = 0; //线下销售量 volatile uint32_t onlineCount = 0; //线上销售量 // 计算线下销售,两个计算销售的基本一致 void retailTask(void *pvParam) { while (1) { uint32_t inv = inventory; //获取当前库存 //转存变量会造成变量不能及时同步从而造成超售,这里是为了模拟如果同时写操作多了,直接操作全局变量也可能会出现超售 for (int i; i < random(10, 100); i++) vTaskDelay(pdMS_TO_TICKS(i)); if (inventory > 0) { inventory = inv - 1; //计算库存 retailCount++; //计算线下销售 } }; vTaskDelay(10); //老板要求慢一些,客户升级后,可以再加快速度 } // 计算线上销售,两个计算销售的基本一致 void onlineTask(void *pvParam) { while (1) { uint32_t inv = inventory; //获取当前库存 for (int i; i < random(10, 100); i++) vTaskDelay(pdMS_TO_TICKS(i)); if (inventory > 0) { inventory = inv - 1; //计算库存 onlineCount++; //计算线上销售 } }; vTaskDelay(10); //老板要求慢一些,客户升级后,可以再加快速度 } // 显示销售 void showTask(void *pvParam) { while (1) { printf("库存 : %d", inventory); printf(" 线下零售 : %d 线上零售 : %d\n", retailCount,onlineCount); if (inventory == 0 ) { printf("\n-----销售总结-----\n"); printf(" 总销售额: %d\n", retailCount+onlineCount); printf(" 超售: %d\n\n", 100-retailCount-onlineCount); } // pdMS_TO_TICKS(),ms转tick vTaskDelay(pdMS_TO_TICKS(100)); } } void setup() { Serial.begin(115200); xMutexInventory = xSemaphoreCreateMutex(); //创建MUTEX // 创建任务 xTaskCreate(retailTask, "计算线下销售",1024 * 4,NULL,1,NULL); xTaskCreate(onlineTask, "计算线上销售",1024 * 4,NULL,1,NULL); xTaskCreate(showTask, "显示库存",1024 * 4,NULL,1,NULL); } void loop() { } ``` 这个程序运行会出现超售现象 主要原因是在计算时同时有多个写操作,实际只有一个成功了 对于这种超售现象,写数量少的可以直接在全局变量上操作,不要用转存变量来操作 **相关内容视频** [任务共享全局变量](https://www.bilibili.com/video/BV1vB4y1D7Cj)|[任务使用全局变量](https://wokwi.com/projects/332775429610930771)|[全局变量多写错误案例](https://wokwi.com/projects/332774646706340434)
造物者W
2022年6月17日 08:56
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码