懶得看 FreeRTOS 專案建置方法的人,我已幫大家建置好了 ,這裡提供 STM32F4 Free RTOS 8.0.0 的工程模板 (專案) 下載點:http://lolikitty.pixnet.net/blog/post/167858043


建置方法(教學影片):



建置方法(文字敘述):

階段一:準備好 STM32F4 基本開發環境
( 如果自己已經做好工程模板的話,請直接跳至 階段二 )
 
1. 先至 彥霖實驗筆記 下載 STM32F4 工程模板 
 
2. 測試工程模板是否有效 (可編譯成功、可將程式碼正確燒入IC 中)
將以下程式碼複製貼上至專案中,並編譯&燒錄,確定能夠正確運行正確後才進入 FreeTROS 移植
 

# include "stm32f4xx.h"

int t = 1000000;

void delay(int t2){
    int i = 0;
    for(; i < t2; i++);
}

int main(void){

    GPIO_InitTypeDef g;
    g.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;    // 指定 12,13,14,15 腳
    g.GPIO_Mode = GPIO_Mode_OUT;           // 設定針腳為輸出
    //g.GPIO_PuPd = GPIO_PuPd_UP;            // 使用上拉電阻
    //g.GPIO_PuPd = GPIO_PuPd_DOWN;      // 使用下拉電阻
    g.GPIO_Speed = GPIO_Speed_100MHz;  // 指定 GPIO 頻率為100 MHz

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);    // 啟用 GPIOD

    GPIO_Init(GPIOD, &g);    // 初始化 GPIO D

    while(1){
        GPIO_SetBits(GPIOD,GPIO_Pin_12);     // 設定12腳為高電位
        delay(t);    // 延遲
        GPIO_ResetBits(GPIOD,GPIO_Pin_12); // 設定 12 腳為低電位

        GPIO_SetBits(GPIOD,GPIO_Pin_13);
        delay(t);
        GPIO_ResetBits(GPIOD,GPIO_Pin_13);

        GPIO_SetBits(GPIOD,GPIO_Pin_14);
        delay(t);
        GPIO_ResetBits(GPIOD,GPIO_Pin_14);

        GPIO_SetBits(GPIOD,GPIO_Pin_15);
        delay(t);
        GPIO_ResetBits(GPIOD,GPIO_Pin_15);
    }
}

-------------------------------------------------------------------------------------------------

階段二:FreeRTOS 移植

1. 下載 FreeRTOS 8.0.0版,下載點: http://sourceforge.net/projects/freertos/files/FreeRTOS/

2. 將下載回來的 FreeRTOSV8.0.0_Release_Candidate_2.zip 解壓縮至 工程模板中

3. 將 
    (1)   <FreeRTOS>/Source/include
    (2)   <FreeRTOS>/Demo/CORTEX_M4F_STM32F407ZG-SK
    (3)   <FreeRTOS>/Source/portable/RVDS/ARM_CM4F
    中的 *.h 匯入至KEIL uVision

4. 將 *.c 檔案加入至專案中
    (1)   <FreeRTOS>/Source/(全部匯入)
    (2)   <FreeRTOS>/Source/portable/MemMang/heap_1.c
    (3)   <FreeRTOS>/Source/portable/RVDS/ARM_CM4F/port.c

5. 打開 <FreeRTOS>/Demo/CORTEX_M4F_STM32F407ZG-SK/FreeRTOSConfig.h
    並將 #include "stm32f4xx.h" 標頭檔加入到文件中,且將 
    #define  configCHECK_FOR_STACK_OVERFLOW  2 改成
    #define  configCHECK_FOR_STACK_OVERFLOW  0 ,存檔並關閉。
 
6. 打開 <FreeRTOS>/Source/portable/RVDS/ARM_CM4F/port.c 
    並將 #include "stm32f4xx.h" 標頭檔加入到文件中。
 
7. 將以下程式碼複製貼上至專案中,並燒入執行。


// 本範例使用 STM32F407VGT6
// 
// 執行結果:
// PD13 每 1000 毫秒 點亮/熄滅 LED 一次
// PD15 每   500 毫秒 點亮/熄滅 LED 一次

#include "FreeRTOS.h"
#include "task.h"

#include "stm32f4xx.h"


// Task priorities: Higher numbers are higher priority.
#define mainTIME_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
#define mainTIME2_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainMEMS_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainDEBUG_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )

xTaskHandle hTimeTask;
xTaskHandle hTimeTask2;
xTaskHandle hMemsTask;
xTaskHandle hDebugTask;

portTASK_FUNCTION_PROTO( vTimeTask, pvParameters );
portTASK_FUNCTION_PROTO( vTimeTask2, pvParameters );
portTASK_FUNCTION_PROTO( vMemsTask, pvParameters );
portTASK_FUNCTION_PROTO( vDebugTask, pvParameters );

uint64_t u64Ticks=0; // Counts OS ticks (default = 1000Hz).
uint64_t u64IdleTicks=0; // Value of u64IdleTicksCnt is copied once per sec.
uint64_t u64IdleTicksCnt=0; // Counts when the OS has no task to execute.
uint16_t u16PWM1=0;

// 任務一
// ----------------------------------------------------------------------------

void myTask1(){

    portTickType xLastWakeTime = xTaskGetTickCount();

    while(1){
        GPIO_ToggleBits(GPIOD,GPIO_Pin_13);
        vTaskDelayUntil( &xLastWakeTime, ( 1000 / portTICK_RATE_MS ) );
    }
}

// 任務二
// ----------------------------------------------------------------------------
void
 myTask2(){

    portTickType xLastWakeTime = xTaskGetTickCount();

    while(1){
        GPIO_ToggleBits(GPIOD,GPIO_Pin_15);
        vTaskDelayUntil( &xLastWakeTime, ( 500 / portTICK_RATE_MS ) );
    }
}

// 初始化 GPIO
// ----------------------------------------------------------------------------
void
 GPIOInit(){
    GPIO_InitTypeDef g;
    g.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; // 指定 12,13,14,15 腳
    g.GPIO_Mode = GPIO_Mode_OUT; // 設定針腳為輸出
    g.GPIO_Speed = GPIO_Speed_100MHz; // 指定 GPIO 頻率為100 MHz
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); // 啟用 GPIOD
    GPIO_Init(GPIOD, &g); // 初始化 GPIO D
}

int main(void){
    GPIOInit(); // 初始化 GPIO

    // 創建任務一,執行 myTask1 () 涵式。 
    xTaskCreate( myTask1, (signed char *) "TIME", configMINIMAL_STACK_SIZE, 
    NULL, mainTIME_TASK_PRIORITY, &hTimeTask );

     // 創建任務二,執行 myTask2 () 涵式。
    xTaskCreate( myTask2, (signed char *) "TIME", configMINIMAL_STACK_SIZE, 
    NULL, mainTIME_TASK_PRIORITY, &hTimeTask );

    vTaskStartScheduler(); // 開始任務調度

    // Will only get here if there was insufficient memory to create
    // the idle task.
    while(1);
}

// This FreeRTOS callback function gets called once per tick (default = 1000Hz).
// ---------------------------------------------------------------------------- 
void vApplicationTickHook( void ) {
    ++u64Ticks;
}

// This FreeRTOS call-back function gets when no other task is ready to execute.
// On a completely unloaded system this is getting called at over 2.5MHz!
// ---------------------------------------------------------------------------- 
void vApplicationIdleHook( void ) {
    ++u64IdleTicksCnt;
}

// A required FreeRTOS function.
// ---------------------------------------------------------------------------- 
void vApplicationMallocFailedHook( void ) {
    configASSERT( 0 ); // Latch on any failure / error.
}

 

arrow
arrow
    全站熱搜

    黃彥霖 發表在 痞客邦 留言(15) 人氣()