zoukankan      html  css  js  c++  java
  • 006-ESP32学习开发(SDK)-关于操作系统-任务,任务堆栈空间,任务的挂起,恢复,删除

    <p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/LearnESP32" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>

    说明

    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()

  • 相关阅读:
    VS2008正式版序列号
    清空SQL Server数据库中所有的用户表
    [原创]JavaScript调用Button的服务器端事件
    动态加载枚举 到 DropdownList
    [转载]静态构造函数
    SQL 事务 [两种]
    Jpg文件格式[参考]
    Delegate Event
    javascript 操作cookie类
    [共享]一个文件上传的控件,绝对是精品源码
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/15089797.html
Copyright © 2011-2022 走看看