nRF52832添加FreeRTOS(附源码)

目录

1.添加FreeRTOS相关文件到工程

1.1新建工程分组FreeRTOS,并添加相关文件

1.2 添加其他分组文件

2.移除工程分组nRF_Libraries中文件

3.添加头文件路径

4.修改文件

4.1修改sdk_config.h

4.2修改freeRTOSConfig.h

4.3 在工程配置里面添加宏 FREERTOS

4.4修改蓝牙广播初始化

5.编写代码测试

5.1编写测试代码

5.2测试效果

6.注意事项

6.1开启LOG打印功能

6.1.1修改sdk_config.h

6.1.2修改FreeRTOSConfig.h

6.1.3需要添加以下函数,并在main函数中调用创建log任务

6.1.4LOG打印效果演示

6.2内存不足

7.源码下载


1.添加FreeRTOS相关文件到工程

1.1新建工程分组FreeRTOS,并添加相关文件

添加\external\freertos\source目录下的所有.c文件

接着,依次添加以下文件:

\external\freertos\source\portable\MemMang\heap_1.c

\external\freertos\portable\ARM\nrf52\port.c

\external\freertos\portable\CMSIS\nrf52\port_cmsis.c

\external\freertos\portable\CMSIS\nrf52\port_cmsis_systick.c

1.2 添加其他分组文件

向 nRF_Libraries 中添加 

\components\libraries\timer\app_timer_freertos.c

\components\libraries\hardfault\nrf52\handler\hardfault_handler_keil.c 

向 nRF_SoftDevice 中添加

 \components\softdevice\common\nrf_sdh_freertos.c

2.移除工程分组nRF_Libraries中文件

app_scheduler.c 
app_timer2.c
drv_rtc.c
nrf_sortlist.c

3.添加头文件路径

..\..\..\external\freertos\source\include
..\..\..\external\freertos\config
..\..\..\external\freertos\portable\ARM\nrf52
..\..\..\external\freertos\portable\CMSIS\nrf52

4.修改文件

4.1修改sdk_config.h

将宏NRF_SDH_DISPATCH_MODEL 由0改为2

4.2修改freeRTOSConfig.h

configUSE_TIMERS 宏由 0 改为 1 

4.3 在工程配置里面添加宏 FREERTOS

4.4修改蓝牙广播初始化

将 advertising_start 函数替换成 nrf_sdh_freertos_init() 函数,并将advertising_start 作为参数,否则无法连接蓝牙。

5.编写代码测试

5.1编写测试代码

编写以下代码,并在 main 函数中调用 freertos_demo();

#include "FreeRTOS.h"
#include "task.h"
/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO 1                   /* 任务优先级 */
#define START_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            StartTask_Handler;  /* 任务句柄 */
void start_task(void *pvParameters);        /* 任务函数 */

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO      2                   /* 任务优先级 */
#define TASK1_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            Task1Task_Handler;  /* 任务句柄 */
void task1(void *pvParameters);             /* 任务函数 */

/* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO      3                   /* 任务优先级 */
#define TASK2_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            Task2Task_Handler;  /* 任务句柄 */
void task2(void *pvParameters);             /* 任务函数 */

/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{
    xTaskCreate((TaskFunction_t )start_task,            /* 任务函数 */
                (const char*    )"start_task",          /* 任务名称 */
                (uint16_t       )START_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )START_TASK_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&StartTask_Handler);   /* 任务句柄 */
    vTaskStartScheduler();
}

/**
 * @brief       start_task
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           /* 进入临界区 */
    /* 创建任务1 */
    xTaskCreate((TaskFunction_t )task1,
                (const char*    )"task1",
                (uint16_t       )TASK1_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK1_PRIO,
                (TaskHandle_t*  )&Task1Task_Handler);
    /* 创建任务2 */
    xTaskCreate((TaskFunction_t )task2,
                (const char*    )"task2",
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler);
    vTaskDelete(StartTask_Handler); /* 删除开始任务 */
    taskEXIT_CRITICAL();            /* 退出临界区 */
}

/**
 * @brief       task1
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void task1(void *pvParameters)
{
    uint32_t task1_num = 0;
    
    while(1)
    {
        task1_num++;
        printf("task1_num: %d\n", task1_num);
        vTaskDelay(1000);                                                 /* 延时1000ticks */
    }
}

/**
 * @brief       task2
 * @param       pvParameters : 传入参数(未用到)
 * @retval      无
 */
void task2(void *pvParameters)
{
    float task2_num = 0.0;
    
    while(1)
    {
        task2_num += 0.01f;                         /* 更新数值 */
        printf("task2_num : %0.4f\r\n", task2_num);  /* 打印数值 */
        vTaskDelay(1000);                           /* 延时1000ticks */
    }
}

5.2测试效果

可见 任务1 和 任务2 依次运行

6.注意事项

6.1开启LOG打印功能

6.1.1修改sdk_config.h

开启以下宏定义:

#define NRF_LOG_BACKEND_RTT_ENABLED 1
#define NRF_LOG_ENABLED 1
#define NRF_LOG_DEFERRED 1

注意:必须将宏定义 NRF_LOG_DEFERRED 置1,开启延迟日志记录,否则会卡死。

6.1.2修改FreeRTOSConfig.h

将 configUSE_IDLE_HOOK 置1,使能空闲任务钩子函数。

6.1.3需要添加以下函数,并在main函数中调用创建log任务

#if NRF_LOG_ENABLED
static TaskHandle_t m_logger_thread; /**< Definition of Logger thread. */

/**@brief Thread for handling the logger.
 *
 * @details This thread is responsible for processing log entries if logs are deferred.
 *          Thread flushes all log entries and suspends. It is resumed by idle task hook.
 *
 * @param[in]   arg   Pointer used for passing some arbitrary information (context) from the
 *                    osThreadCreate() call to the thread.
 */
static void logger_thread(void * arg)
{
    UNUSED_PARAMETER(arg);

    while (1)
    {
        NRF_LOG_FLUSH();
        vTaskSuspend(NULL); // Suspend myself
    }
}
#endif //NRF_LOG_ENABLED

#if NRF_LOG_ENABLED && NRF_LOG_DEFERRED
//修改空闲任务钩子函数:
void vApplicationIdleHook()
{
    vTaskResume(m_logger_thread);
}
#endif

//以下代码放在初始化中
#if NRF_LOG_ENABLED
    // Start execution.
    if (pdPASS != xTaskCreate(logger_thread, "LOGGER", 256, NULL, 1, &m_logger_thread))
    {
        APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
    }
#endif

6.1.4LOG打印效果演示

6.2内存不足

检查FreeRTOSConf.h中任务总堆栈大小 configTOTAL_HEAP_SIZE 和 最大优先级数量 configMAX_PRIORITIES 的值是否足够。

7.源码下载

通过网盘分享的文件:实验15:蓝牙串口透传-移植FreeRTOS.rar
链接: 百度网盘 请输入提取码

参考:nRF52832开发笔记-简化版移植FreeRTOS(基于nus例程)_nrf52832 rtos-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值