52832带softdevice工程移植freertos
基于BLE应用加上freertos的应用,官方只提供了一个例子,针对自己的应用使用freertos具体需要添加哪些文件执行哪些步骤没有很明确的参考说明,so特此整理一份。
本篇硬件基于nrf52832-DK开发板。SDK基于V15.3版本。
添加freertos需要文件
在MDK工程中创建文件夹freertos,添加freertos的c文件:
添加的port.c port_cmsis.c port_cmsis_systick.c要根据使用的编译器和用的是nrf51还是nrf52来添加正确目录下的文件。
添加.\components\softdevice\common\nrf_sdh_freertos.c文件
添加头文件
基于官方提供的例子,拷贝\examples\ble_peripheral\ble_app_hrs_freertos\中的config文件夹到ble_app_blinky_freertos目录下。并添加到MDK的工程中去。
添加freertos相关的其他头文件目录,新添加的如下:
替换掉一些文件
删除掉mdk工程中的app_timer.c 并添加app_timer_freertos.c文件
修改配置
修改sdk_config.h文件中:NRF_SDH_DISPATCH_MODEL 2
该配置的意思是修改softdevice底层事件到应用层的方式,模式2代表是application主动获取。
在freertos的主动获取的实现就是在我们前面添加的nrf_sdh_freertos.c文件中如果用mode0 中断方式通知到应用层,就不需要添加nrf_sdh_freertos.c文件,但是我测试的时候发现会出现蓝牙断开的情况)
在main函数中做如下修改:
屏蔽掉advertising_start(NULL); (该函数添加了 void *参数为了消除编译警告) 再添加两行代码,启动freertos的调度器。
1 2 3 |
//advertising_start(NULL); nrf_sdh_freertos_init(advertising_start, NULL); vTaskStartScheduler(); |
编译修改错误
这时候就可以编译了,但是并没有成功,会提示缺少vApplicationIdleHook函数的定义。这个是空闲任务的钩子钩子函数,需要我们自己定义,在main.c中添加如下定义:
1 2 3 4 |
void vApplicationIdleHook() { } |
再次编译,OK!
烧录验证
先给52832烧录好softdevice,然后烧录应用程序。
打开手机app:Nordic_Blinky 测试已经可以正常搜索到蓝牙信号,连接上以后控制led亮灭可以正常。
但是发现按下button1手机app上反应的却很慢。这个和之前不加freertos之前的效果差很多。
从按键反应慢发现一个问题
再深入进去看button_init的初始化代码,发现用到的app_timer,于是编写app_timer测试之后,发现定时100ms的定时器却需要大概3秒的时间。所以最终发现问题出现在APP_TIMER_TICKS()计算上。
跟踪到宏定义,发现在在添加定义FREERTOS后计算出来才是准确的值。所以在MDK中添加:
编译再次运行程序,按键通知到app已经可以快速响应。
打印LOG的问题:
当打开rtt打印log的时候发现打印不了,参考了官方提供的移植好的例子,还需要进行如下操作:
创建log打印处理的任务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
static TaskHandle_t m_logger_thread; static void logger_thread(void * arg) { UNUSED_PARAMETER(arg); while (1) { NRF_LOG_FLUSH(); vTaskSuspend(NULL); // Suspend myself } } //并在main函数中调用: if (pdPASS != xTaskCreate(logger_thread, "LOGGER", 256, NULL, 1, &m_logger_thread)) { APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); } //修改空闲任务钩子函数: void vApplicationIdleHook() { vTaskResume(m_logger_thread); } |