天天看點

S3C2416裸機開發系列十五_GCC下uCOS的移植(2)S3C2416裸機開發系列十五

S3C2416裸機開發系列十五

GCC下uCOS的移植(2)

象棋小子    1048272975

4. uCOS配置

uCOS是可裁減實時作業系統,可以根據實際的應用對核心未使用到的功能進行裁減,以進一步節省系統寶貴的硬體資源,通常可用的uCOS-II核心代碼在6K~26K,這在uCOS-II配置檔案os_cfg.h中進行配置,這個配置檔案在源碼目錄為os_cfg_r.h,從目錄中拷貝添加到uCOS/uCOS-II/Cfg目錄中,并重命名為os_cfg.h。

#ifndef OS_CFG_H

#define OS_CFG_H

#define OS_CFG_APP_HOOKS_EN   1u  

#define OS_CFG_ARG_CHK_EN        1u  

#define OS_CFG_CALLED_FROM_ISR_CHK_EN   1u  

#define OS_CFG_DBG_EN                  1u  

#define OS_CFG_ISR_POST_DEFERRED_EN    0u  

#define OS_CFG_OBJ_TYPE_CHK_EN                 1u  

#define OS_CFG_TS_EN                    1u  

#define OS_CFG_PEND_MULTI_EN            1u  

#define OS_CFG_PRIO_MAX                32u  

#define OS_CFG_SCHED_LOCK_TIME_MEAS_EN 1u  

#define OS_CFG_SCHED_ROUND_ROBIN_EN      1u  

#define OS_CFG_STK_SIZE_MIN              64u  

#define OS_CFG_FLAG_EN                  1u  

#define OS_CFG_FLAG_DEL_EN              0u  

#define OS_CFG_FLAG_MODE_CLR_EN      0u  

#define OS_CFG_FLAG_PEND_ABORT_EN   0u  

#define OS_CFG_MEM_EN                  1u  

#define OS_CFG_MUTEX_EN                 1u  

#define OS_CFG_MUTEX_DEL_EN             0u  

#define OS_CFG_MUTEX_PEND_ABORT_EN     0u  

#define OS_CFG_Q_EN                      1u  

#define OS_CFG_Q_DEL_EN                    0u  

#define OS_CFG_Q_FLUSH_EN                 0u  

#define OS_CFG_Q_PEND_ABORT_EN         1u  

#define OS_CFG_SEM_EN                         1u  

#define OS_CFG_SEM_DEL_EN                    0u  

#define OS_CFG_SEM_PEND_ABORT_EN       1u  

#define OS_CFG_SEM_SET_EN                     1u  

#define OS_CFG_STAT_TASK_EN             1u  

#define OS_CFG_STAT_TASK_STK_CHK_EN    1u  

#define OS_CFG_TASK_CHANGE_PRIO_EN      1u  

#define OS_CFG_TASK_DEL_EN              0u  

#define OS_CFG_TASK_Q_EN                  1u  

#define OS_CFG_TASK_Q_PEND_ABORT_EN    0u  

#define OS_CFG_TASK_PROFILE_EN          1u  

#define OS_CFG_TASK_REG_TBL_SIZE        1u  

#define OS_CFG_TASK_SEM_PEND_ABORT_EN  1u  

#define OS_CFG_TASK_SUSPEND_EN          1u  

#define OS_CFG_TIME_DLY_HMSM_EN           1u  

#define OS_CFG_TIME_DLY_RESUME_EN      0u  

#define OS_CFG_TLS_TBL_SIZE    0u  

#define  OS_CFG_TMR_EN            1u  

#define OS_CFG_TMR_DEL_EN   0u  

#endif

5. 使用者代碼

使用者需要提供一個周期性定時中斷作為uCOS-II的運作Tick,每個Tick需調用OSTimeTick()來讓核心管理時鐘節拍,在s3c2416用定時器4産生這個系統Tick。在main()函數中需調用OSInit()初始化核心,建立任務後,再調用OSStart()把cpu管理權交給核心。核心即可正确地管理使用者的任務。

#include "s3c2416.h"

#include "Exception.h"

#include "ucos_ii.h"

// IO port for controling LEDs

#define LED2    (13) // GPE13 LED2

#define LED3    (11) // GPE11 LED3

#define LED4    (13) // GPL13 LED4

#define LED5    (12) // GPE12 LED5

#define LED6    (2)  // GPG2  LED6

OS_STK TaskStartStk[TASK_START_STK_SIZE];

OS_STK  Task1Stk[TASK1_STK_SIZE];

OS_STK  Task2Stk[TASK2_STK_SIZE];

OS_STK  Task3Stk[TASK3_STK_SIZE];

static void Timer4_IRQ(void)

{

    OSTimeTick(); // uCOS時鐘節拍管理

    rSRCPND1 |= (0x01 <<INT_TIMER4);       // write 1 to clear

    rINTPND1 |= (0x01 <<INT_TIMER4);       // write 1 to clear

}

void Timer4_Start()

{

    rTCON |= (0x1 << 20); // 定時器開啟

}

void Timer4_Stop()

{

    rTCON &= ~(0x1 << 20);// 定時器停止

}

void Timer4_Init()

{

// 定時器4時鐘頻率為PCLK(66.66666M)/(0+1)/16=4.166MHZ

    rTCFG1 &= ~(0xf << 16);

    rTCFG1 |= (0x3 << 16);  // Timer4 16分頻

    rTCFG0 &= ~(0xff << 8);

    rTCFG0 |= (0 << 8); // PCLK預分頻為1

    rTCNTB4 = 4166; // System Tick設1ms

    rTCON |= (0x1 << 21); // 更新計數值

    rTCON &= ~(0x1 << 21);// 清除

    rTCON |= (0x1 << 22); // 自動重裝載

    IRQ_Register(INT_TIMER4,Timer4_IRQ); // 注冊Timer4中斷函數

    rINTMOD1 &= ~(1 <<INT_TIMER4); // Timer4 IRQ 模式

    rINTMSK1 &= ~(1 <<INT_TIMER4); // Timer4開中斷

}

void Gpio_LED2(unsigned char On)

{

    if (!On) {

        rGPEDAT &=~(1<<LED2);

    } else {

        rGPEDAT |= (1<<LED2);

    }

}

void Gpio_LED3(unsigned char On)

{

    if (!On) {

        rGPEDAT &=~(1<<LED3);

    } else {

        rGPEDAT |= (1<<LED3);

    }

}

void Gpio_LED4(unsigned char On)

{

    if (!On) {

        rGPLDAT &=~(1<<LED4);

    } else {

        rGPLDAT |= (1<<LED4);

    }

}

void Gpio_LED5(unsigned char On)

{

    if (!On) {

        rGPEDAT &=~(1<<LED5);

    } else {

        rGPEDAT |= (1<<LED5);

    }

}

void Gpio_Init()

{

    // GPE11,12,13 LED3,LED5,LED2output   

    rGPECON &=~((0x03<<(LED3<<1)) | (0x03<<(LED5<<1))

                |(0x03<<(LED2<<1)));

    rGPECON |= ((0x01<<(LED3<<1))| (0x01<<(LED5<<1))

                |(0x01<<(LED2<<1)));

    // GPL13 LED4 output   

    rGPLCON &= ~(0x03 <<(LED4<<1));

    rGPLCON |= (0x01 <<(LED4<<1));

}

void Task3(void *pdata)

{

    (void)pdata;

    while (1) {

        Gpio_LED5(1);

        OSTimeDly(2000); // LED5 2000ms閃爍

        Gpio_LED5(0);

        OSTimeDly(2000); // LED52000ms閃爍    

    }

}

void  Task2(void *pdata)

{

    (void)pdata;

    while (1) {

        Gpio_LED4(1);

        OSTimeDly(1500); // LED41500ms閃爍

        Gpio_LED4(0);

        OSTimeDly(1500); // LED41500ms閃爍    

    }

}

void  Task1(void *pdata)

{

    (void)pdata;

    while (1) {

        Gpio_LED3(1);

        OSTimeDly(1000); // LED31000ms閃爍

        Gpio_LED3(0);

        OSTimeDly(1000); // LED31000ms閃爍    

    }

}

void  TaskStart(void *pdata)

{

    (void)pdata;

    Gpio_Init();

    Timer4_Init();

    Timer4_Start();

    OSTaskCreate(Task1, (void *)0,&Task1Stk[TASK1_STK_SIZE - 1], Task1Prio);

    OSTaskCreate(Task2, (void *)0,&Task2Stk[TASK2_STK_SIZE - 1], Task2Prio);

    OSTaskCreate(Task3, (void *)0,&Task3Stk[TASK3_STK_SIZE - 1], Task3Prio);

    while (1) {

        Gpio_LED2(1);

        OSTimeDly(500); // LED2 500ms閃爍

        Gpio_LED2(0);

        OSTimeDly(500); // LED2 500ms閃爍

    }

}

int  main (void)

{  

    OSInit(); // 初始化uCOS

    OSTaskCreate(TaskStart, (void *)0,&TaskStartStk[TASK_START_STK_SIZE-1], TaskStartPrio);

   OSStart();// 開始uCOS排程

    return 0;

}

uCOS-II通過app_cfg.h檔案來配置任務的棧、優先級等,app_cfg.h的内容如下:

#ifndef APP_CFG_MODULE_PRESENT

#define APP_CFG_MODULE_PRESENT

// 任務TaskStart的棧及優先級配置設定

#define  TASK_START_STK_SIZE      256u

#define  TaskStartPrio      10

// 任務Task1的棧及優先級配置設定

#define  TASK1_STK_SIZE         256u

#define  Task1Prio          11

// 任務Task2的棧及優先級配置設定

#define  TASK2_STK_SIZE         256u

#define  Task2Prio          12

// 任務Task3的棧及優先級配置設定

#define  TASK3_STK_SIZE         256u

#define  Task3Prio          13

// 定時器優先級配置

#define OS_TASK_TMR_PRIO       (OS_LOWEST_PRIO - 2)

#endif

uCOS-II+uCGUI效果圖:

S3C2416裸機開發系列十五_GCC下uCOS的移植(2)S3C2416裸機開發系列十五
S3C2416裸機開發系列十五_GCC下uCOS的移植(2)S3C2416裸機開發系列十五

6. 附錄

本篇uCOS接口部分的移植對于ARM7、ARM9都是适用的,不同型号的cpu隻需加入定時器産生系統Tick,通過調用OSTimeTick()來讓核心管理時鐘節拍。總的來說,熟悉一款作業系統的工作原理,了解其任務排程、信号量同步、臨界區通路等概念,對學習其它作業系統、多線程程式設計等均是有很較大的幫助的。

uCOS_GCC,GCC下uCOS-II的移植工程,可直接make

http://pan.baidu.com/s/1o6NTaVw

uCOS_MDK,MDK下uCOS-II的移植工程

http://pan.baidu.com/s/1jGjzE0A