关于如何搭建stm32的gnu eclipse环境,请参考前述博文。
本文主要描述如何在gnu eclipse环境上移植freertos的步骤,具体原理请参考网文。本文移植两种芯片stm32f103及smt32f030。
下面是freertos的源代码结构。
soure文件中是freertos源代码,demo是各种芯片与工具的demo工程,比如stm32的mdk工程,但是没有gnu eclipse环境工程,这里就是要基于一个demo工程移植freertos到gnu arm eclipse工程中。
1、建立一个gnu arm eclipse的模板工程,我们使用stm32f030c8芯片。
2、在eclipse下建立目录结构如图所示:
3、分别拷贝src下面及src/portable/MemMangg/heap_2到目录中。
Source/croutine.c
Source/event_groups.c
Source/list.c
Source/queue.c
Source/stream_buffer.c
Source/tasks.c
Source/timers.c
Source/portable/MemMangg/heap_2.c
Source/portable/GCC/ARM_CM0/port.c
到system/src/freertos下面:
4、拷贝头文件:
Source/portable/GCC/ARM_CM0/portmacro.h
Source/include/*.h
Demo/CORTEX_M0_STM32F0518_IAR/FreeRTOSConfig.h
如下所示:
5、修改部分代码:
FreeRTOSConfig.h中将#define configCPU_CLOCK_HZ 定义改成系统晶振频率。
main函数中增加定义:
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
vParTestInitialise();
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */
}
6、定义一个闪灯任务并启动:
void ledBlink()
{
blink_led_init();
while(1)
{
vTaskDelay(1000);
blink_led_on();
vTaskDelay(1000);
blink_led_off();
}
}
int
main(int argc, char* argv[])
{
// Send a greeting to the trace device (skipped on Release).
xTaskCreate(ledBlink,"blink",configMINIMAL_STACK_SIZE,NULL,100,NULL);
vTaskStartScheduler();
// Infinite loop
while (1)
{
}
// Infinite loop, never return.
}
至此,基本过程已经完成。f103更加简单。