STM32F107移植FreeRTOS

准备

FreeRTOS是一个开源的实时操作系统,移植简单,使用方便。用户只需修改几个头文件的宏定义就可运行起来。首先去官网下载FreeRTOS源码http://www.freertos.org/,我下载的是V9.0的版本,9.0版本有些功能修改,具体可在官网上面找到。

移植

下载完成后,解压出来可以看到源码的文件结构,如下图:
STM32F107移植FreeRTOS_第1张图片

移植\Source文件夹

这里我们只需关注\FreeRTOS文件夹的东西,打开\FreeRTOS文件夹,我们要复制\Source文件夹到自己的工程中去,前提要准备一个工程模板
STM32F107移植FreeRTOS_第2张图片
我自己的工程模板如下图所示
STM32F107移植FreeRTOS_第3张图片

创建工程

FreeRTOS部分主要是\Source文件夹下面的文件
STM32F107移植FreeRTOS_第4张图片
芯片级相关的文件从此路径\FreeRTOS\FreeRTOSv9.0.0\FreeRTOS\Source\portable\RVDS\ARM_CM3找到2个文件,需要移植到工程中去
STM32F107移植FreeRTOS_第5张图片
内存分配方案对应CM3内核推荐使用heap4方案
STM32F107移植FreeRTOS_第6张图片
这是我自己移植完的工程
STM32F107移植FreeRTOS_第7张图片

移植和配置FreeRTOSConfig.h

在..\FreeRTOSv9.0.0\FreeRTOS\Demo\CORTEX_STM32F107_GCC_Rowley找到FreeRTOSConfig.h文件(我的板子是STM32F107芯片,F103的可选择\CORTEX_STM32F103_Keil文件夹的FreeRTOSConfig.h配置文件),移植到工程的\USER文件夹中。这个是配置文件,放哪都可以,只要不打乱自己的文件结构。
STM32F107移植FreeRTOS_第8张图片

具体配置见代码块,可以根据宏定义来打开或关闭相应的功能

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/*-----------------------------------------------------------
 * Application specific definitions.
 *
 * These definitions should be adjusted for your particular hardware and
 * application requirements.
 *
 * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
 * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
 *
 * See http://www.freertos.org/a00110.html.
 *----------------------------------------------------------*/

#define configUSE_PREEMPTION        1                               //使能抢占式调度器
#define configUSE_IDLE_HOOK         0                               //配置空闲任务的钩子函数
#define configUSE_TICK_HOOK         0                               //配置滴答定时器中断中执行的钩子函数
#define configCPU_CLOCK_HZ          ( ( unsigned long ) 72000000 )  //配置CPU主频
#define configTICK_RATE_HZ          ( ( TickType_t ) 1000 )         //配置系统节拍
#define configMAX_PRIORITIES        ( 5 )                           //配置可供用户使用的最大优先级数
#define configMINIMAL_STACK_SIZE    ( ( unsigned short ) 128 )      //配置空闲任务的堆栈大小
#define configTOTAL_HEAP_SIZE       ( ( size_t ) ( 30 * 1024 ) )    //定义堆大小
#define configMAX_TASK_NAME_LEN     ( 16 )                          //定义任务名最大字符数
#define configUSE_TRACE_FACILITY    0                               //使能此配置将添加额外的结构体成员和函数,以此来协助可视化和跟踪
#define configUSE_16_BIT_TICKS      0                               //对于32位架构处理器,此宏定义需设置为0
#define configIDLE_SHOULD_YIELD     1                               //用于使能与空闲任务同优先级的任务

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES       0                               //使能合作式调度相关函数
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )                       //配置可供用户使用的最大合作式任务优先级数

//#define configUSE_MUTEXES             1                           //使能互斥信号量
//#define configUSE_COUNTING_SEMAPHORES     0                       //使能计数信号量
//#define configUSE_ALTERNATIVE_API         0                       //
//#define configCHECK_FOR_STACK_OVERFLOW    2                       //栈溢出检测方式为2
//#define configUSE_RECURSIVE_MUTEXES       1                       //使能递归互斥信号量
//#define configQUEUE_REGISTRY_SIZE     0                           //通过此定义来设置可以注册的信号量和消息队列的个数
//#define configGENERATE_RUN_TIME_STATS 1                           //配置任务运行状态参数统计

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */

#define INCLUDE_vTaskPrioritySet        1
#define INCLUDE_uxTaskPriorityGet       1
#define INCLUDE_vTaskDelete             1
#define INCLUDE_vTaskCleanUpResources   0
#define INCLUDE_vTaskSuspend            1
#define INCLUDE_vTaskDelayUntil         1
#define INCLUDE_vTaskDelay              1

/* This demo makes use of one or more example stats formatting functions.  These
format the raw data provided by the uxTaskGetSystemState() function in to human
readable ASCII form.  See the notes in the implementation of vTaskList() within 
FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS    1                   //需配合configUSE_TRACE_FACILITY == 1 才起作用

/* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255
(lowest) to 0 (1?) (highest). */
#define configKERNEL_INTERRUPT_PRIORITY         255
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    191 /* equivalent to 0xb0, or priority 11. */


/* This is the value being used as per the ST library which permits 16
priority values, 0 to 15.  This must correspond to the
configKERNEL_INTERRUPT_PRIORITY setting.  Here 15 corresponds to the lowest
NVIC value of 255. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15
//添加以下3个宏定义,FreeRTOS通过这3个中断实现任务调度。另外还需屏蔽stm32f10x_it.c中的空函数定义
#define vPortSVCHandler     SVC_Handler 
#define xPortPendSVHandler  PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
/*-----------------------------------------------------------
 * Macros required to setup the timer for the run time stats.
 *-----------------------------------------------------------*/
/* The run time stats time base just uses the existing high frequency timer
test clock.  All these macros do is clear and return the high frequency
interrupt count respectively. */
//需要用户定义的钩子函数
//extern unsigned long ulRunTimeStatsClock;
//#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() ulRunTimeStatsClock = 0
//#define portGET_RUN_TIME_COUNTER_VALUE() ulRunTimeStatsClock


#endif /* FREERTOS_CONFIG_H */

编写应用任务

我将应用任务都写在app.c文件中,置写了2个超简单的任务,用于测试。一个LED灯闪烁,另一个是串口打印任务。

#include "app.h"

static TaskHandle_t xHandleTaskLED=NULL;
static TaskHandle_t xHandleTaskUART=NULL;

static void vTaskLED(void* pvParameters)
{
    while(1)
    {
        bsp_LED_Toggle(LED1_PORT,LED1_Pin);
        bsp_LED_Toggle(LED2_PORT,LED2_Pin);
        vTaskDelay(1000);
    }
}

static void vTaskUart(void* pvParameters)
{
    uint8_t testBuffer[]={"UART4 Test..."};
    while(1)
    {
        bsp_UART_SendChar('U');
        vTaskDelay(100);
    }
}
void AppTaskCreate(void)
{
    xTaskCreate(vTaskLED,"vTaskLED",100,NULL,4,xHandleTaskLED);

    xTaskCreate(vTaskUart,"vTaskUART",100,NULL,3,xHandleTaskUART);
}

启动FreeRTOS

int main(void)
{
    __set_PRIMASK(1);//禁止全局中断
    bsp_Init();//bsp 初始化
    AppTaskCreate();//应用任务创建
    vTaskStartScheduler();//启动任务调度器

    while(1)
    {
    }

    return 0;
}

总结

FreeRTOS整个移植过程是比较的简单的,具体使用还得多看它的用户手册,现在官网也可以免费下载了。这只是移植能运行成功阶段,功能使用还得不断摸索,再接再厉!

你可能感兴趣的:(STM32)