006-ESP32学习开发(SDK)-关于操作系统-任务
2023-03-20 15:39:59 时间
说明
esp32是跑的freertos, 如果没有学过操作系统的朋友把此节当做esp32的内部api使用就可以.
创建任务,每隔一段时间打印 Hello world
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
//任务函数
static void function(void *pvParameters)
{
while(1)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);//延时约1S
printf("Hello world!
");
fflush(stdout);//手动调用刷新缓存,让printf输出数据
}
}
void app_main(void)
{
//创建任务
//第一个function是任务函数; 第二个"function"是给任务取个名字
//第三个2048是保存任务数据的栈区大小; 第四个传递给任务的参数写的NULL
//第五个任务的优先等级是10; 第六个记录任务的变量写的NULL
xTaskCreate(function, "function", 2048, NULL, 10, NULL);
}
各个细节说明
1.首先如果没有学过rtos的把这个当做创建定时器就可以了
2.下面的是必须写的
注:那个vTaskDelay函数有时候可以用别的替代,到时候遇到之后再说.
写了下面的程序以后,就会不停的执行while(1)里面的程序.
3.可以修改延时时间
4.可以再创建个任务
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
//任务函数
static void function(void *pvParameters)
{
while(1)
{
vTaskDelay(500 / portTICK_PERIOD_MS);//延时约500ms
printf("Hello world!
");
fflush(stdout);//手动调用刷新缓存,让printf输出数据
}
}
//任务函数
static void function_1(void *pvParameters)
{
while(1)
{
vTaskDelay(500 / portTICK_PERIOD_MS);//延时约500ms
printf("1111111111!
");
fflush(stdout);//手动调用刷新缓存,让printf输出数据
}
}
void app_main(void)
{
//创建任务
//第一个function是任务函数; 第二个"function"是给任务取个名字
//第三个2048是保存任务数据的栈区大小; 第四个传递给任务的参数写的NULL
//第五个任务的优先等级是10; 第六个记录任务的变量写的NULL
xTaskCreate(function, "function", 2048, NULL, 10, NULL);
xTaskCreate(function_1, "function_1", 2048, NULL, 11, NULL);
}
5.可以看到两个字符串几乎是每隔500ms同时打印
6.关于栈区大小
任务在运行的时候,每个任务是来回切换运行的,操作系统在切换别的任务运行的时候,会把当前任务运行的寄存器,变量的值存储到内存(ram)里面.
当再次回到这个任务运行的时候,从内存把寄存器,变量的值读取出来,这样子的话就可以接着上次运行了.
保存数据大小我设置的是2048.
7.获取这个任务自启动以后剩余的最小栈区空间
uxTaskGetStackHighWaterMark( NULL );
中文是乱码....不用理会,咱可以看出剩下的栈空间是568
8.难道使用了 2048-568 = 1480 ????
一个啥也没有的任务不可能使用这么多的,其实返回的是这个任务运行的时候使用的最大空间.
但是网络是都是说这个函数是剩下的栈空间呢? 如何解释?
其实是栈的生长方向的问题!
首先呢保存数据就是使用的数组保存的,数组有首地址和尾地址.
假设存储数据的时候是从首地址开始存储的,假设存储了568个数据,那么数据最大存储在568这个地址
那么就剩余1480个空间没有使用.那么返回的时候返回剩下的就是1480;
如果存储数据的时候是从数组的尾地址开始存储的,假设存储568个数据,其实数据是存储到 2047,2046,...,1479,1480 这些地址上
最终存储的地址是1480,但是呢从数组的首地址开始计算的话就会认为存储了1480个数据
那么便会计算出剩余568,正好和上面的相反.所以才返回568.
9.大家伙可以把这个地方改为 566 和 569测试
大家伙会发现设置为566的时候,任务启动不起来,程序总是在重启. 设置569是可以的.
所以呢函数 uxTaskGetStackHighWaterMark( NULL ); 在这个里面其实是获取的使用的最大空间
10.一般呢把空间设置为实际使用空间的1.5倍或者2倍就可以 568*2=1136
停止(挂起)任务 vTaskSuspend(任务句柄)
function1运行约3秒后,停止function任务的运行
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
//任务句柄,用来对任务做其它操作
TaskHandle_t TaskHandle_t_function;
//任务函数
static void function(void *pvParameters)
{
while(1)
{
vTaskDelay(500 / portTICK_PERIOD_MS);//延时约500ms
printf("222222!
");
fflush(stdout);//手动调用刷新缓存,让printf输出数据
}
}
//任务函数
static void function_1(void *pvParameters)
{while(1)
{
vTaskDelay(3000 / portTICK_PERIOD_MS);//延时约3000ms
vTaskSuspend(TaskHandle_t_function);//停止function任务运行(挂起function任务)
}
}
void app_main(void)
{
//第一个function是任务函数; 第二个"function"是给任务取个名字
//第三个2048是保存任务数据的栈区大小; 第四个传递给任务的参数写的NULL
//第五个任务的优先等级是10; 第六个记录任务的变量写的NULL
xTaskCreate(function, "function", 1136, NULL, 10, &TaskHandle_t_function);
xTaskCreate(function_1, "function_1", 2048, NULL, 11, NULL);
}
启动被停止(挂起)的任务 vTaskResume(任务句柄)
删除任务 vTaskDelete()
相关文章
- 一篇运维老司机的大数据平台监控宝典(2)-联通大数据集群平台监控体系详解
- 一篇运维老司机的大数据平台监控宝典(1)-联通大数据集群平台监控体系进程详解
- 空中换引擎 博时基金数字化转型经验谈
- 如何高效地学习编程语言
- 作为一名阿里巴巴数据分析大牛,送给学弟学妹的经验积分
- 为什么要学习R语言
- Hadoop大数据分析平台的介绍性讨论
- 最全面的Spring学习笔记
- 16个用于数据科学和机器学习的顶级平台
- 给有抱负的数据科学家的六条建议
- 如何做一枚合格的数据产品经理
- 除Kaggle外,还有哪些顶级数据科学竞赛平台
- 一个鲜为人知却可以保护隐私的训练方法:联合学习
- 干货 :送你12个关于数据科学学习的关键提示(附链接)
- 大数据行业有多少种工作岗位,各自的技能需求是什么?
- 中国移动研究院常耀斌:商用大数据平台的研发之路
- 这些数据科学家必备的技能,你拥有哪些?
- 自学成才的开发者有何优势和劣势?
- Gartner报告:正处于数据科学与机器学习工具 “大爆炸”的时代
- Ready Computing借助InterSystems IRIS医疗版为医疗机构提供具有高度互操作性和可扩展性的解决方案