原始工程使用f1c100s/f1c200s 裸机程序,参见 https://whycan.com/t_11525.html

工程构建:make
操作系统:windows

FreeRTOS没有ARM9的例子,ARM7和ARM9内核很相似,主要参考ARM7_LPC2000 移植。

FreeRTOS源码下载:
哇酷下载:RTOS-KernelV11.1.0.zip
github下载:https://github.com/FreeRTOS/FreeRTOS-Kernel/releases

一、文件目录结构搭建

1.解压重命名为FreeRTOS ,新建文件夹port

2.复制 FreeRTOS/portable/GCC/ARM7_LPC2000 下 port.c portISR.c portmacro.h 到 port目录下

3.复制FreeRTOS/portable/MemMang 到FreeRTOS/MemMang

4.复制 FreeRTOS/examples/template_configuration/FreeRTOSConfig.h 到 include目录下

\5. 删除examples portable 文件夹。完成后的目录结构如下

移植过程:

添加FreeRTOS 中断,修改工程文件 vectors.S,定义宏 USE_FREERTOS , 修改 _software_interrupt 和 _irq 两个中断,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*任务切换*/ 
_software_interrupt:
#if defined (USE_FREERTOS)
.word vPortYieldProcessor
#else
.word software_interrupt
#endif

/*系统嘀嗒心跳*/
_irq:
#if defined (USE_FREERTOS)
.word vFreeRTOS_ISR
#else
.word irq
#endif

port.c 和 portISR.c ,添加定时器初始化和定时器中断切换任务功能

port.c 添加头文件

1
2
#include "f1c100s_timer.h"
#include "f1c100s_intc.h"

定时器time0初始化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
* Setup the timer 0 to generate the tick interrupts at the required frequency.
*/
static void prvSetupTimerInterrupt(void)
{
extern void vTickISR(void);

tim_init(TIM0, TIM_MODE_CONT, TIM_SRC_HOSC, TIM_PSC_1);
tim_set_period(TIM0, 24000000UL/1000UL);//1ms中断
tim_int_enable(TIM0);
intc_set_irq_handler(IRQ_TIMER0, vTickISR);
intc_enable_irq(IRQ_TIMER0);
tim_start(TIM0);
}

portISR.c 接管所有的中断,添加上下文切换保存和恢复,添加naked属性,禁用编译器上下文管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*__attribute__((naked)) 很关键 不加调度
*使用naked属性可以告诉编译器不生成函数的prologue和epilogue代码,
*这样任务切换函数可以自行管理寄存器的入栈和恢复,从而简化上下文管理*/
void vFreeRTOS_ISR(void) __attribute__((naked));
void vFreeRTOS_ISR(void)
{
extern void irq_handler(void);
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
/* irq all*/
irq_handler();
/* Restore the context of the new task. */
portRESTORE_CONTEXT();
}

portISR.c 系统嘀嗒中断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef write32
#define write32(x, y) (*((volatile uint32_t *)(x)) = y)
#endif
#include "task.h"
void vTickISR(void)
{
/* Increment the RTOS tick count, then look for the highest priority
* task that is ready to run. */
if (xTaskIncrementTick() != pdFALSE)
{
vTaskSwitchContext();
}
/* Ready for the next interrupt. */
write32((0x01C20C00) + 0x04, (1 << 0));
}

portISR.c 添加 堆栈溢出 回调

1
2
3
4
5
6
#include "stdio.h"
void vApplicationStackOverflowHook(TaskHandle_t xTask,
char *pcTaskName)
{
printf("statck over flow:%s",pcTaskName);
}

FreeRTOSConfig.h 修改heap大小 和 位宽

1
2
#define configTOTAL_HEAP_SIZE                        512*1024
#define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_32_BITS

makefile 添加 CFLAGS+=-DUSE_FREERTOS
至此移植完成。

gcc和xfel:
usb下载工具 xfel 和USB驱动下载: xfel-v1.3.2
gcc:arm-none-eab-gcc-10.3
make rm工具在工程目录下

完整移植好的FreeRTOS 11.1工程下载:F1C200S_FreeRTOS.zip

编译: arm-none-eabi-gcc 和xfel添加到环境变量 ,打开cmd命令行 ,进入 F1C200S_FreeRTOS 目录下

1
2
make all
make download

花了五块验证程序可以用,只是FreeRTOS部分移到自己工程后,切换上下文有点问题。
修改汇编里面的中断后成功启动,感谢楼主


相关链接(侵删)

  1. F1C100SF1C200S 移植FreeRTOS全过程 GCC 版本

=================我是分割线=================

欢迎到公众号来唠嗑: