雷竞技注册
项目

介绍nRF51上的FreeRTOS

2015年9月24日通过特拉维斯Fagerness

本文演示了将FreeRTOS与一个软件设备一起移植到nRF51,这样您就可以使用具有BLE功能的RTOS。

本文演示了将FreeRTOS与一个软件设备一起移植到nRF51,这样您就可以使用具有BLE功能的RTOS。

概述

这是一系列文章的一部分NRF51.。nRF51是一个Cortex M0和BLE无线芯片一体的系统芯片。本文演示了如何使用实时操作系统的BLE功能。

以前的文章:
BLE使用nRF51: ARM-GCC构建环境
BLE using nRF51:创建BLE外设

要求

FreeRTOS

FreeRTOS是一种用于小型微控制器的操作系统。RTOS代表“实时操作系统”。实时是什么意思?许多嵌入式设备需要对它们正在操作的数据作出某种以毫秒为量级的响应。因此,Windows和Linux等操作系统的响应速度不够快,因为它们允许其他应用程序有时间运行。这可能会导致不确定性行为,这在嵌入式系统中是不可取的。大多数RTOS实现以某种方式提供了以下功能:

功能 描述
任务 任务(有时称为进程或线程)是在其自己的上下文中执行的代码。它不依赖于其他任务或操作系统。这允许多个任务并行运行。
调度程序 调度程序决定哪个任务可以在给定时间运行。它还维护每个任务的上下文和内存。
信号 信号量是一种共享资源并在任务之间进行通信的方法。
计时器 定时器是在给定间隔或单个事件时连续地调用函数的方式。

大多数ROS中有许多功能,例如内置USB驱动程序和内存管理。

在NRF51上运行

下载以下项目,开始在nRF51上使用FreeRTOS。此项目假定您已经设置了建立环境

freertos_nrf51.zip

Freertos已移植到许多不同的处理器。幸运的是,其中一个是Cortex-M0,它是NRF51内的CPU。从上面的链接下载FreeRtos并将其提取到已知位置。记下这个位置,因为它是在Makefile中需要的。必须修改Cortex-M0的端口,因为它依赖于Systick运行RTOS。NRF51没有CPU中实现的Systick,因此您必须使用SoftDevice计时器。RTOS通常需要计时器递增“滴答”,这只是保留时间和计划任务的方式。1毫秒的刻度是常见的,并且是下面的代码将是什么。我在以下代码中修改了计时器函数:
[freertos dir] \ source \ portable \ gcc \ arm_cm0 \ port.c

在这个文件中搜索以下函数:
void prvSetupTimerInterrupt(无效)

把它改成:

void prvsetuptimerInterrupt(void){/ *配置Systick以在所请求的速率下中断。* / *(portnvic_systick_load)=(configcpu_clock_hz / configtick_rate_hz) -  1UL;*(portnvic_systick_ctrl)= portnvic_systick_clk |portnvic_systick_int |portnvic_systick_enable;}

提到下面。此代码使用SoftDevice提供的应用程序定时器。SoftDevice有点像RTO,因为它具有控制蓝牙的定时器和各种功能。

void prvsetuptimerInterrupt(void){app_timer_init(0,1,4,false);app_timer_create(&freertos_timer,app_timer_mode_repeated,xportsystickhandler);app_timer_start(freertos_timer,app_timer_ticks(1,0),null);}

将以下头文件和变量添加到文件的顶部:

/ *端口包括* / #include“nrf.h”#include“app_timer.h”静态app_timer_id_t freertos_timer;

配置FreeRTOS

配置头

该文件FreeRTOSConfig.h有几个定义配置操作系统。这些选项配置要使用的内存,使用的特殊功能以及许多其他选项。此应用程序的重要性是堆栈大小,use_preemption和tick_rate_hz。定时器设置为1ms,因此刻度率必须为1000Hz。预先撤销意味着任务不会被分配相同的运行时间。我们希望BLE任务具有最优先级的优先级,因此消息已正确处理。如果在另一个任务中运行时间关键算法来处理数据,这可能会更改。内存取决于系统约束。您可以使用某些内置功能监视堆栈深度,但由于我们在此示例中没有使用任何内存,因此堆栈大小为70字是充足的。

#define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 1 #define configTICK_RATE_HZ ((TickType_t) 1000) #define configMINIMAL_STACK_SIZE ((unsigned short) 70)
钩子

钩子是回调函数RTOS调用某些事件发生时。这可能是一个故障分配内存或调度程序是空闲的。在大多数嵌入式系统中,在空闲状态期间睡眠是很重要的,因此可以访问调度程序执行此操作时很重要。在Freertos中,您必须指定要在配置标题中使用的钩子。以下是freertos_hooks.c的钩子,这只是可用的小的子集。

#include“freertos.h”#include“task.h”void vapplicationmallocfailedhook(void){taskdisable_interrupts();为了( ;; );void VapplicationIdlehook(void){} void VapplicationStackoverflowhook(taskHandle_t pxtask,char * pctaskname){(void)pctaskname;(void)pxtask;taskDisable_interrupts();为了( ;; );void VapplicationTickhook(void){#if maincheck_interrupt_stack == 1 externed long _pvheapstart [];configassert(memcmp((void *)_pvheapstart,ucexpectedinterruptstackvalues,sizeof(ucexpectedinterruptstackvalues))== 0u);#endif / * maincheck_interrupt_stack * /}

创建任务

在项目文件main.c see中,下面的行创建了两个不同的任务。一个任务处理BLE功能。它还在每个循环迭代期间闪烁绿色LED。第二个任务只是每100ms闪烁一次蓝色LED,但是它可以被修改来做更有用的任务,比如读取传感器和数据处理。可以将这些数据提供给BLE任务并报告。

#define ble_task_priority(tskidle_priority + 2)#define blinky_task_priority(tskidle_priority + 1)静态void task_blinky(void * pvparameters);静态void task_ble_process(void * pvparameters);XTaskCreate(task_ble_process,“ble task”,configminimal_stack_size,null,ble_task_priority,null);XTaskCreate(task_blinky,“blinky任务”,configminimal_stack_size,null,blinky_task_priority,null);vtaskstartscheduler();

函数xTaskCreate实际上是创建任务的。它是通过传递要运行的函数、用于调试的友好名称、要为堆栈使用多少内存以及优先级来设置的。调度程序使用优先级来确定如果两个任务碰巧同时准备好了,应该运行哪个任务。每个任务必须将控制权交还给调度程序,否则其他任务将无法运行。在本例中,这是通过将任务延迟一定数量的毫秒来实现的,这相当于一个典型的操作系统睡眠函数。当任务被延迟时,其他任务被允许运行。LED任务延迟100ms来切换灯光。

静态void task_blinky(void * pvParameters){whis(1){nrf_gpio_pin_toggle(LED_RGB_BLUE);vtaskdelay(100);}}

BLE任务运行与BLE外围示例相同的代码。这次它使用vTaskDelay ()而不是nrf_delay_ms ()。如果您要使用忙碌等待函数,如nrf_delay_ms(),则其他任务将无法运行。

静态void task_ble_process(void * pvparameters){uint8_t i = 0;uint32_t err_code;虽然(1){nrf_gpio_pin_toggle(LED_RGB_GREEN);vtaskdelay(500);for(i = 0; i 

使用GCC构建FreeRTOS

相同的makefile是从上一个BLE外围物品中使用的。Freertos拥有相当多的源文件,如果所有这些都被添加到Makefile,则会增加构建时间。您可以通过添加各自的C文件添加您计划使用的功能。以下部分添加到C源文件部分。更改变量FREERTOS_PATH到您提取FreeRTOS源代码的地方。

#freertos c files freertos_path = c:/ projects / freertos c_source_files + = freertos_hooks.c c_source_files + = nrf51_port.c c_source_files + = $(freertos_path)/source/croutine.c c_source_files + = $(freertos_path)/source/event_groups.cc_source_files + = $(freertos_path)/source/list.c c_source_files + = $(freertos_path)/source/squeue.c c_source_files + = $(freertos_path)/source/tasks.c c_source_files + = $(freertos_path)/源/计时器.c c_source_files + = $(freertos_path)/source/portable/memmang/heap_4.c

以下是添加的标题包括:

INC_PATHS + = -i $(freertos_path)/ source / client inc_paths + = -i $(freertos_path)/ source / portable / gcc \ arm_cm0

现在在控制台中键入“make”,然后“make flash”,您应该在NRF51加密狗上看到以下内容。纯绿色意味着加密狗的调试功能通过USB连接,实际上并不是应用程序的一部分。蓝光闪烁非常快,绿灯慢慢闪烁。您还可以使用相同的方法连接到设备

接下来是什么?

既然已经有了构建系统、操作系统和通信功能,nRF加密狗就有了很多功能。这个平台可以用作远程数据收集器,可以在发送数据之前对传入数据进行信号处理。使用RTOS,任何需要同时运行多个东西的项目都容易得多。玩得开心!

为自己提供这个项目!BOM。