注意: 需要修改文件,建议从 nRF5_SDK_xxxxx\external\freertos 中将freertos的源码拷贝到工程目录中,然后添加工程目录中的源码。这样不修改SDK中的源码。
添加对应目录的源码路径到工程目录
如图: 需要移除 drv_rtc.c 和 app_timer2.c 文件,新增加 app_timer_freertos.c
__asm void xPortPendSVHandler( void )
{extern uxCriticalNesting;extern pxCurrentTCB;extern vTaskSwitchContext;PRESERVE8mrs r0, pspisb/* Get the location of the current TCB. */ldr r3, =pxCurrentTCBldr r2, [r3]/* Is the task using the FPU context? If so, push high vfp registers. */#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)tst r14, #0x10it eqvstmdbeq r0!, {s16-s31}#endif/* Save the core registers. */stmdb r0!, {r4-r11, r14}/* Save the new top of stack into the first member of the TCB. */str r0, [r2]stmdb sp!, {r3}mov r0, #(configMAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))msr basepri, r0dsbisbbl vTaskSwitchContextmov r0, #0msr basepri, r0ldmia sp!, {r3}/* The first item in pxCurrentTCB is the task top of stack. */ldr r1, [r3]ldr r0, [r1]/* Pop the core registers. */ldmia r0!, {r4-r11, r14}/* Is the task using the FPU context? If so, pop the high vfp registerstoo. */#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)tst r14, #0x10it eqvldmiaeq r0!, {s16-s31}#endifmsr psp, r0isbbx r14ALIGN
}
修改为只是
FPU->FPCCR |= FPU_FPCCR_ASPEN_Msk | FPU_FPCCR_LSPEN_Msk;
更改为
#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)/* Lazy save always. */FPU->FPCCR |= FPU_FPCCR_ASPEN_Msk | FPU_FPCCR_LSPEN_Msk;#endif //#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
BaseType_t xPortStartScheduler( void )
{/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );/* This port is designed for nRF52, this is Cortex-M4 r0p1. */configASSERT( SCB->CPUID == portCORTEX_M4_r0p1_ID );#if ( configASSERT_DEFINED == 1 ){volatile uint32_t ulOriginalPriority;volatile uint8_t * const pucFirstUserPriorityRegister = &NVIC->IP[0];volatile uint8_t ucMaxPriorityValue;/* Determine the maximum priority from which ISR safe FreeRTOS APIfunctions can be called. ISR safe functions are those that end in"FromISR". FreeRTOS maintains separate thread and ISR API functions toensure interrupt entry is as fast and simple as possible.Save the interrupt priority value that is about to be clobbered. */ulOriginalPriority = *pucFirstUserPriorityRegister;/* Determine the number of priority bits available. First write to allpossible bits. */*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;/* Read the value back to see how many bits stuck. */ucMaxPriorityValue = *pucFirstUserPriorityRegister;/* Use the same mask on the maximum system call priority. */ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;/* Calculate the maximum acceptable priority group value for the numberof bits read back. */ulMaxPRIGROUPValue = SCB_AIRCR_PRIGROUP_Msk >> SCB_AIRCR_PRIGROUP_Pos;while ( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ){ulMaxPRIGROUPValue--;ucMaxPriorityValue <<= ( uint8_t ) 0x01;}/* Remove any bits that are more than actually existing. */ulMaxPRIGROUPValue &= SCB_AIRCR_PRIGROUP_Msk >> SCB_AIRCR_PRIGROUP_Pos;/* Restore the clobbered interrupt priority register to its originalvalue. */*pucFirstUserPriorityRegister = ulOriginalPriority;}#endif /* conifgASSERT_DEFINED *//* Make PendSV the lowest priority interrupts. */NVIC_SetPriority(PendSV_IRQn, configKERNEL_INTERRUPT_PRIORITY);/* Start the timer that generates the tick ISR. Interrupts are disabledhere already. */vPortSetupTimerInterrupt();/* Initialise the critical nesting count ready for the first task. */uxCriticalNesting = 0;/* Ensure the VFP is enabled - it should be anyway. */vPortEnableVFP();#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)/* Lazy save always. */FPU->FPCCR |= FPU_FPCCR_ASPEN_Msk | FPU_FPCCR_LSPEN_Msk;#endif //#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)/* Finally this port requires SEVONPEND to be active */SCB->SCR |= SCB_SCR_SEVONPEND_Msk;/* Start the first task. */vPortStartFirstTask();/* Should never get here as the tasks will now be executing! Call the taskexit error function to prevent compiler warnings about a static functionnot being called in the case that the application writer overrides thisfunctionality by defining configTASK_RETURN_ADDRESS. */prvTaskExitError();/* Should not get here! */return 0;
}
#include "FreeRTOS.h"
#include "list.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"
#include "event_groups.h"#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/**@brief A function which is hooked to idle task.* @note Idle hook must be enabled in FreeRTOS configuration (configUSE_IDLE_HOOK).*/
void vApplicationIdleHook( void )
{
#if NRF_LOG_ENABLEDvTaskResume(m_logger_thread);
#endif
}int main(void)
{ret_code_t err_code;log_init();/* Initialize clock driver for better time accuracy in FREERTOS */err_code = nrf_drv_clock_init();APP_ERROR_CHECK(err_code);//clock_initialization(); //clock_init();// Do not start any interrupt that uses system functions before system initialisation.// The best solution is to start the OS before any other initalisation.#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);}#endifNRF_LOG_INFO("nrf5281x freertos example");uint32_t heap_mem = xPortGetFreeHeapSize();NRF_LOG_INFO("Scheduler start[%dB/%d.%02dK]/[%dB/%d.%02dK].", heap_mem, heap_mem/1024, (heap_mem%1024)*100/1024, \configTOTAL_HEAP_SIZE, configTOTAL_HEAP_SIZE/1024, (configTOTAL_HEAP_SIZE%1024)*100/1024);// Start FreeRTOS scheduler.vTaskStartScheduler();for (;;){APP_ERROR_HANDLER(NRF_ERROR_FORBIDDEN);}
}