1.源码下载
· 在移植之前,我们首先要获取到FreeRTOS的官方的源码包
直接在官网下载freertos源码包。
下载后打开文件夹 可以看到:
进入FreeRTOS文件夹
然后在打开Source
2.移植
在你的原有项目中,新建一个FreeRTOS文件夹
然后将源码文件\FreeRTOSv202212.01\FreeRTOS\Source中的几个.c文件复制到freeRTOS文件夹中
然后新建include和portable文件夹
然后我们回到源码文件夹,点开Source,确定好你用的是哪个IDe,我用的是IAR
所以进入SOurce后,点开portable,找到IAR
然后去网上搜芯片型号,可知,lpc54608的架构是arm cortex M4,所以打开ARM_CM4F文件夹,将整个文件夹复制到工程FreeRTOS/portable中(我的项目中在freeRTOS中还新建了个IAR文件夹,然后将ARM_CM4F放入了portable/IAR中,其实没有必要 )
然后回到源码路径:source/portable中,找到memmang
也复制到工程FreeRTOS/portable中(其实只要ARM_CM4F和mengmang就行)
然后将源码文件中的include全部复制到FreeRTOS文件夹中
移植成功
3.工程修改
右键option,添加以下group:FreeRTOS,然后将FreeRTOS中整个include文件夹添加到inc文件中,FreeRTOS中的的七个.c文件加入,然后选择MemMang中的heap_4.c和ARM_CM4F中的三个文件加入
然后添加头文件路径,主要是FreeRTos中的include,然后ARM_CM4F,不放心的话,新建的几个文件夹都可以加进去。
如果这时候点击编译会发现,其报错SysTick_Handler出现重定义,这是因为,原来代码文件中含有SysTick_Handler,而FreeRTOS的port.c中也需要用的,一般只要把原工程文件的SysTick_Handler主注释掉留下port中的就行。
但是我原来程序中,有用到SysTick_Handler,直接注释会导致功能不完整,所以可以新建一个函数,因为原工程中的SysTick_Handler位于system_LPC54608.c,所以打开工程,注释掉SysTick_Handler,将其改为Original_SysTick_Handler。
cpp
void Original_SysTick_Handler(void)
{
if(!Delay_Enable) // 如果延时未启用
{
TimeMS++; // 计时增加
}
else
{
TimeTick++; // 延时计数增加
}
}
//void SysTick_Handler(void)
//{
// if(!Delay_Enable) // 如果延时未启用
// {
// TimeMS++; // 计时增加
// }
// else
// {
// TimeTick++; // 延时计数增加
// }
//}
然后回到port.c,注释掉原来的,修改为
cpp
//void xPortSysTickHandler( void )
//{
// /* The SysTick runs at the lowest interrupt priority, so when this interrupt
// * executes all interrupts must be unmasked. There is therefore no need to
// * save and then restore the interrupt mask value as its value is already
// * known. */
// portDISABLE_INTERRUPTS();
// {
// /* Increment the RTOS tick. */
// if( xTaskIncrementTick() != pdFALSE )
// {
// /* A context switch is required. Context switching is performed in
// * the PendSV interrupt. Pend the PendSV interrupt. */
// portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
// }
// }
// portENABLE_INTERRUPTS();
//}
void xPortSysTickHandler(void)
{
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
* executes all interrupts must be unmasked. There is therefore no need to
* save and then restore the interrupt mask value as its value is already
* known. */
portDISABLE_INTERRUPTS();
{
/* Increment the RTOS tick. */
if(xTaskIncrementTick() != pdFALSE)
{
/* A context switch is required. Context switching is performed in
* the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
/* 调用原来的 SysTick 处理函数 */
Original_SysTick_Handler();
}
portENABLE_INTERRUPTS();
}
实现FreeRTOS'的滴答执行时调用原来的滴答定时器处理函数
编译成功!测试后也没有发现问题