FreeRTOS入门(如何移植&任务创建与删除)

目录

一、FreeRTOS介绍

二、FreeRTOS实现了什么功能

三、使用CubeMX快速移植FreeRTOS

四、任务的创建

1.什么是任务?

2.任务创建与删除的相关函数

五、基于官方源码的示例

六、基于CubeMX移植RTOS的示例

七、任务删除(补充) 

八、总结


一、FreeRTOS介绍

RTOS的全称是Real time operating system,中文就是实时操作系统。这里的RTOS不是指某一个确定的系统,而是指一类操作系统。比如:uc/OS,FreeRTOS,RTX, RT-Thread等这些都是RTOS类操作系统。

我们之所以选择FreeRTOS有以下几点原因;

·FreeRTOS是免费的;

·很多半导体厂商产品的SDK(Software Development Kit)软件开发工具包,就使用FreeRTOS   作为其操作系统,尤其是WIFI、蓝牙这些带有协议栈的芯片或模块。

·简单,因为FreeRTOS的文件数量很少。


二、FreeRTOS实现了什么功能

假设一个母亲在家带孩子,她需要完成给孩子喂饭和回同事信息两个任务;

裸机开发:

·回同事信息,导致孩子没吃上饭

·喂孩子吃饭,导致同事觉得被忽略

FreeRTOS:

一只手给同事回消息,一只手给孩子喂饭,虽然不能真正的同时运行,但喂一口饭后回一个信息在我们看来好像是同时运行的,这就是FreeRTOS所实现的功能:严格来说 FreeRTOS 并不是实时操作系统,因为它是分时复用的。 系统将时间分割成很多时间片,然后轮流执行各个任务。 每个任务都是独立运行的,互不影响,由于切换的频率很快,就感觉像是同时运行的一样。


三、使用CubeMX快速移植FreeRTOS

1. 在 SYS 选项里,将 Debug 设为 Serial Wire ,并且将 Timebase Source 设为 TIM2 (其它定时器也行)。

Timebase Source 为什么不能设置为 SysTick ? 裸机的时钟源默认是 SysTick,但是开启 FreeRTOS 后,FreeRTOS会占用 SysTick (用来生成1ms 定时,用于任务调度),所以需要为其他总线提供另外的时钟源。 

2. 将 RCC 里的 HSE 设置为 Crystal/Ceramic Resonator 。 

3. 选择 FREERTOS 选项,并将 Interface 改为 CMSIS_V1 。 

FreeRTOS 版本问题:V2 的内核版本更高,功能更多,在大多数情况下 V1 版本的内核完全够用。 

FreeRTOS 各配置选项卡的解释:

Events:事件相关的创建

Task and Queues: 任务与队列的创建

Timers and Semaphores: 定时器和信号量的创建

Mutexes: 互斥量的创建

FreeRTOS Heap Usage: 用于查看堆使用情况

Config parameters: 内核参数设置,用户根据自己的实际应用来裁剪定制FreeRTOS 内核

Include parameters: FreeRTOS 部分函数的使能

User Constants: 相关宏的定义,可以自建一些常量在工程中使用

Advanced settings:高级设置


四、任务的创建

1.什么是任务?

任务可以理解为进程/线程,创建一个任务,就会在内存开辟一个空间。

比如:给孩子喂饭,回同事信息,都可以视为任务

Windows 系统中的 MarkText 、谷歌浏览器、记事本,都是任务。

任务通常都含有 while(1) 死循环。

在FreeRTOS中,任务就是一个函数,原型如下:

下面是一个示例:

2.任务创建与删除的相关函数

任务动态创建与静态创建的区别: 动态创建任务的堆栈由系统分配,而静态创建任务的堆栈由用户自己传递。 通常情况下使用动态方式创建任务。 

xTaskCreate 函数原型:

参数说明:


五、基于官方源码的示例

任务1的代码:

void vTask1( void *pvParameters )
{
    const char *pcTaskName = "T1 run\r\n";
    volatile uint32_t ul; /* volatile用来避免被优化掉 */
    
    /* 任务函数的主体一般都是无限循环 */
    for( ;; )
    {
        /* 打印任务1的信息 */
        printf( pcTaskName );
        
        /* 延迟一会(比较简单粗暴) */
        for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )
        {
        }
    }
}

任务2打印"T2 run\r\n";

main函数:

int main( void )
{
    prvSetupHardware();
    
    xTaskCreate(vTask1, "Task 1", 1000, NULL, 1, NULL);
    xTaskCreate(vTask2, "Task 2", 1000, NULL, 1, NULL);
    
    /* 启动调度器 */
    vTaskStartScheduler();
    
    /* 如果程序运行到了这里就表示出错了, 一般是内存不足 */
    return 0;
}

运行结果如下:

 注意:                                                                     
·task 2先运行!                                                           
·要分析xTaskCreate的代码才能知道原因:更高优先级的、或者后面创建的任务先运行。

任务运行图: 

·在t1:Task2进入运行态,一直运行直到t2

·在t2:Task1进入运行态,一直运行直到t3;在t3,Task2重新进入运行态


六、基于CubeMX移植RTOS的示例

用CubeMX生成FreeRTOS的代码后,转到freertos.c

这里CubeMX自动帮我们封装好了xTaskCreate和调度函数vTaskStartScheduler();在CubeMX中被封装成osKernelStart();这里任务函数的osDelay是自动生成好的;

上图是在CubeMX里配置相关参数封装的xTaskCreate函数;

在CubeMX的FreeRTOS选项选择Tasks and Queues选项卡,点击Add可以自定义任务:

在任务函数里编写想要实现的功能就可以直接编译下载。


七、任务删除(补充) 

删除任务时使用下面这个函数

void vTaskDelete( TaskHandle_t xTaskToDelete );

参数说明:

 怎么删除任务?举个不好的例子:

·自杀: vTaskDelete(NULL) 
·被杀:别的任务执行 vTaskDelete(pvTaskCode) ,pvTaskCode是自己的句柄
·杀人:执行 vTaskDelete(pvTaskCode) ,pvTaskCode是别的任务的句柄

注意:对于自杀的任务,由空闲函数来释放他的内存,对于被杀的任务,由凶手来释放他的内存!!!所以如果编写程序时用了自杀的方式来删除任务,一定要让空闲任务运行(优先级为0),以免内存不足,创建任务失败!!!


八、总结

本文章概述了FreeRTOS的基本概念和功能以及内部实现的方式,还给了两个基于不同源码的示例,用CubeMX生成代码更加方便,但学习官方源码能更好的理解底层逻辑,后续我会继续更新我的FreeRTOS学习笔记。

  • 14
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sakabu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值