面向RoboMaster的FreeRTOS使用的快速入门教程

我们战队使用的是自己组的板子,在这个新赛季我们想尝试一下DJI官方的C板。在使用C板的过程中,我们发现DJI的任务控制使用的是FreeRTOS这个单片机操作系统。而我们使用的是裸机开发。仅是Freertos这个形式上的不同。让我很难将FreeRTOS上的代码,移植到裸机开发上。随着越来越多的RoboMaster战队,使用DJI C板,使用FreeRTOS进行开发。如果我们战队很难融入开源这个大环境的话,将会错失很多交流的机会。

什么是FreeRTOS?

FreeRTOS 是单片机的一种操作系统。操作系统这个东西我们很熟悉,就像是手机的操作系统有 安卓,ios。电脑的操作系统有Windows,Mac。

FreerRTOS是单片机的一种操作系统。FreeRTOS提供了许多方法用以实现多线程(threads)、多作业(task)、互斥锁(mutex)、信号量(semaphore)、和软件计时器(software timer)。

是什么其实不重要,重要的是怎么使用。

我们所使用的FreeRTOS—— CMSIS-RTOS

我们使用的是由STM32CubeMx 自动生成的 FreeRTOS。

ST公司,在原来的FreeRTOS上又进行了一层封装,这层就是CMSIS-RTOS 。CMSIS-RTOS是keil公司对不同RTOS的一种封装结构,可以使不同的RTOS具有相同的接口,以方便今后程序的移植。

如何使用FreeRTOS(使用STM32CubeMX 生成)

利用STM32CubeMX生成

这里我假定你已经对STM32CubeMx具有一定的了解(比如会移植时钟树,会用CubeMX生成代码)。

现在在你已经把前面所有常规的配置设置好之后,下面开始配置FreeRTOS。

首先打开Middleware标签,选中其中的FREERTOS选项,进入FREERTOS的配置页面。

在Mode页面下,选择Interface 的版本,这里选择 CMSIS_V1。CMSIS是由 keil 提供的一套特殊的函数接口,他对freeRTOS的功能函数进行了封装,使其变得更加易用,在使用freeRTOS是,不需要再去直接调用 freeRTOS 的函数,只需要调用 CMSIS 为我们提供的函数即可。

通过以上方式就可以完成freeRTOS的开启,在生成代码之后,freeRTOS会自动被移植到工程中。接着在Configuration页面下进行freeRTOS的配置。

在页面中,可以配置 freeRTOS 的一些重要的属性,包括是否支持抢占机制,freeRTOS 的 系统时钟速率,最大优先级数量,最小任务栈尺寸,最大任务名称长度等。

名称

功能

USE_PREEMPTION

是否支持抢占机制,支持则设为 Enable

TICK_RATE_HZ

系统时钟速率,时钟按照该速率为freeRTOS中各个任务执行计时,设置为1000Hz,则每个任务的最小调度时间为ms

MAX_PRIORITIES

最大优先级数量,默认为7

MINMAL_STACK_SIZE

最小任务堆栈大小,每当创建一个任务时,都需要为该任务分配一定大小的栈空间,任务需要使用的变量等都存储在该栈空间中。默认的最小值为128个字。

MAX_TASK_NAME_LEN

最大任务名称长度,在创建任务时,需要给每个任务起名作为标识,这个名称可以用一个字符串标识,本参数规定了字符串长度的上限值,默认为16

CubeMX 中创建任务

经过上面的步骤,我们已经开启了FreeRTOS,现在我们要在FreeRTOS里创建任务。

首先在FreeRTOS的配置页面中的configuration 下 选中 Tasks and Queues 标签页,存在一个已经创建的默认任务为“default Task”,点击进入配置选项修改为如下图所示。

名称

功能

Task Name

任务名称

Priority

任务创建时的优先级

Stack Size(Words)

任务栈的大小,默认单位为字

Entry Function

任务函数的入口

Code Generation Option

任务函数代码生成方式,设置为Default 则会产生一个普通的任务函数,

As weak:产生一个用__weak 修饰符修饰的任务函数(弱函数)

As external: 产生一个外部引用的任务函数,用户需要自己实现该函数;

Default: 产生一个默认格式的任务函数,用户需要在该函数实现功能。

(Parameter Allocation 这两行我们这里不做修改)

如果需要增加一个任务,点击Add,就可以创建一个新的任务。(下图我已经新建好了)

设置完毕之后点击OK,就可以看到列表中多出了自己创建的任务。

之后点击生成代码,打开keil。我们可以在freertos.c 中找到修改的默认任务函数。

由于选择通过__weak修饰符创建一个弱函数,可以再在别处实现该任务函数。程序执行时会自动寻找到这个另外实现的任务函数。

由于新建了任务“LED_GREEN”,并且设置为 As external,故而需要在别处实现任务函数,程序执行时会自动寻找到实现的任务函数。

在程序中创建任务(在 keil 中创建任务)

事实上,我们大多数情况下都是在程序中创建任务的。因为每次利用CubeMX创建任务都是在重新生成一次代码,很是麻烦。所以我们可以直接在keil中创建任务。

打开 freertos.c 文件,在MX_FREERTOS_Init 中,找到创建两个进程的代码,分别是 LED_RED 和 LED_GREEN。可以看到要创建任务,需要调用 osThreadDef 和 osThreadCreate 。

首先要介绍osThreadDef,实际上这不是一个函数,而是一个由CMSIS提供的宏定义,用于对要创建的任务进行设置。

名称

osThreadDef

功能

对要创建的任务进行设置

参数1

name ,要创建任务的名称

参数2

thread,要创建的任务代码的入口名称

参数3

Priority,要创建的任务的优先级

参数4

Instances,任务下可以创建的线程的数量

参数5

stacksz,任务栈大小

接着通过CMSIS 提供的 osThreadCreate 函数来创建任务

函数名称

osThreadCreate

函数功能

创建一个任务

返回值

osThreadId,任务 ID,ID 是一个任务的重要标识,当在创建完任务后需要执 行修改这个任务的优先级,或者销毁该任务时,就需要调用任务 ID,需要提 前声明一个类型为 osThreadId 的变量在此处存储返回值。

参数1

const osThreadDef_t *thread_def,我们通过 osThreadDef 所设置的任务参 数,采用强制转换+任务名的方式进行输入,比如在 osThreadDef 中设置任 务名为 LED_RED,则在此处输入 osThread(LED_RED)

参数2

void *argument,任务需要的初始化参数,一般填为NULL

在创建任务之前,我还需要做两件事情,

1. 先声明任务的入口函数(希望你可以分清声明 和 定义 二者之间的区别)

2.定义一个任务ID。

之后再在MX_FREERTOS_Init 中利用 osThreadDef 和 osThreadCreate 创建任务。

在程序中创建的任务,我们入口函数一般都是

As external: 产生一个外部引用的任务函数,用户需要自己实现该函数;

参考文档:

RoboMaster开发板C型嵌入式软件教程文档

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值