• 【基于FreeRTOS的STM32F103系统】编写FreeRTOS程序


    系列文章目录

    【基于FreeRTOS的STM32F103系统】简介及官方文件移植

    【基于FreeRTOS的STM32F103系统】编写FreeRTOS程序

    【基于FreeRTOS的STM32F103系统】内存管理及任务调度

    【基于FreeRTOS的STM32F103系统】队列 

    【基于FreeRTOS的STM32F103系统】Heap_4内存管理机制程序详解

    【基于FreeRTOS的STM32F103系统】移动底盘程序优化 


    前言

    前面简单介绍了FreeRTOS和如何将它简单的移植到STM32F1上,这篇介绍移植完成后,我们如何创建任务,并利用FreeRTOS的多任务机制优化我们的程序。

    一、创建任务

    创建任务时使用的函数如下:

    1. BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //函数指针,任务函数
    2. const char * const pcName, //任务的名字
    3. const configSTACK_DEPTH_TYPE usStackDepth,//栈大小,单位为word,10表示40字节
    4. void * const pvParameters, //调用任务函数时传入的参数
    5. UBaseType_t uxPriority, //优先级
    6. TaskHandle_t * const pxCreatedTask );//任务句柄,以后使用它来操作这个任务

    参数说明:

    • pvTaskCode:函数指针,可以简单地认为任务就是一个C函数。它稍微特殊一点:永远不退出,或者退出时要调用"vTaskDelete(NULL)"
    • pcName:任务的名字,FreeRTOS内部不使用它,仅仅起调试作用。长度为:confifigMAX_TASK_NAME_LEN
    • usStackDepth:每个任务都有自己的栈,这里指定栈大小。
      单位是 word ,比如传入 100 ,表示栈大小为 100 word ,也就是 400 字节。
      最大值为 uint16_t 的最大值。
      怎么确定栈的大小,并不容易,很多时候是估计。
      精确的办法是看反汇编码。
    • pvParameters:传入参数,调用 pvTaskCode 函数指针时用到: pvTaskCode(pvParameters)
    • uxPriorit:优先级范围:0~(confifigMAX_PRIORITIES – 1) 数值越小优先级越低, 如果传入过大的值,xTaskCreate会把它调整为(confifigMAX_PRIORITIES – 1)
    • pxCreatedTask: 用来保存 xTaskCreate 的输出结果: task handle 以后如果想操作这个任务,比如修改它的优先级,就需要这个 handle 如果不想使用该 handle ,可以传入 NULL
    • 返回值:
      成功: pdPASS
      失败: errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY( 失败原因只有内存
      不足 )
      注意:文档里都说失败时返回值是 pdFAIL ,这不对。
      pdFAIL 0 errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY -1

    实例:

    1. void Task1Function(void * param)
    2. {
    3. while (1)
    4. {
    5. printf("1");
    6. }
    7. }
    8. void Task2Function(void * param)
    9. {
    10. while (1)
    11. {
    12. printf("2");
    13. }
    14. }
    15. xTaskCreate(Task1Function, "Task1", 100, NULL, 1, &xHandleTask1);
    16. xTaskCreate(Task2Function, "Task2", 100, NULL, 1, NULL);

    开启任务调度:

    vTaskStartScheduler();          //开启任务调度

    结果:

    二、删除任务

    删除任务使用的函数如下:

    void vTaskDelete( TaskHandle_t xTaskToDelete );

    参数说明:

    • xTaskToDelete:任务句柄,使用 xTaskCreate 创建任务时可以得到一个句柄,也可传入NULL ,这表示删除自己。
    • 句柄的实质就是这个任务结构体的指针,在FreeRTOS中任务的创建利用面向对象的思想,创建的一个个任务都是结构体,删除任务的实质就类似于C语言中的free释放内存

    实例:

    1. void vTask1( void *pvParameters )
    2. {
    3. const TickType_t xDelay100ms = pdMS_TO_TICKS( 100UL );
    4. BaseType_t ret;
    5. /* 任务函数的主体一般都是无限循环 */
    6. for( ;; )
    7. {
    8. /* 打印任务的信息 */
    9. printf("Task1 is running\r\n");
    10. ret = xTaskCreate( vTask2, "Task 2", 1000, NULL, 2, &xTask2Handle );
    11. if (ret != pdPASS) printf("Create Task2 Failed\r\n");
    12. // 如果不休眠的话, Idle任务无法得到执行
    13. // Idel任务会清理任务2使用的内存
    14. // 如果不休眠则Idle任务无法执行, 最后内存耗尽
    15. vTaskDelay( xDelay100ms );
    16. }

    三、任务状态

    • 当前正在进行的任务,是running状态;其他所有任务都处于not running状态
    • "not running"状态还可以细分为:
      ready :就绪,随时可以运行
      blocked :阻塞,该任务在等待某一事件发生
      suspended :挂起,该任务暂停休息

     当创建任务并开始任务调度后,所有任务都处于Ready就绪状态,系统随机挑选一个任务Running,正在执行的任务可以使用vTaskSuspend函数使自己进入挂起状态(传入参数NULL或自己的句柄),也可以使其他任务进入挂起状态(传入参数为需要挂起任务的句柄),进入暂停状态后,需要在别的任务执行过程中调用vTaskResume函数该任务才会重新进入Ready状态;

    在任务执行过程中,需要等待某个函数或事件的发生,则进入挂起状态(Baocked),当等待的事件(可能是中断或某个任务)发生后该任务才会恢复Ready状态。


    总结

    关于任务简单写这些,后面进行内存管理、堆栈、队列等的介绍

  • 相关阅读:
    基于神经网络的图像识别,人工神经元网络的特点
    2006-2020年各省研发投入强度
    【深度学习】YOLOv5替换自有VOC数据集
    git提交错了?别慌,直接删除提交记录
    flutter代码中使用Android/ios原生生命周期
    计算机毕业设计 基于SpringBoot高校竞赛管理系统的设计与实现 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试
    【MATLAB】布朗运动动画仿真
    【架构方法论(一)】架构的定义与架构要解决的问题
    Spring创建Bean实例的方式
    ChatGPT 火爆全球,我们能抓住的下一个风口在哪?
  • 原文地址:https://blog.csdn.net/qq_52785580/article/details/126803471