--- tags: Develop, MCU --- # Ti RTOS Note ![](https://i.imgur.com/vzfSKGC.png) # 目錄 [TOC] # Bare Metal vs RTOS ![](https://i.imgur.com/mnQpCjs.png) - 是在「沒有作業系統」的狀況下去開發程式。 - 在此模式下會去開發BIOS/UEFI/Bootloader這類 **「需和硬體溝通」** 的程式。 # 兩種方法 ## POSIX API - 全名為 Portable Operating System Interface for Unix。 - 對抗M$所開發的一套API,被Unix, Linux及各RTOS所採用。 - 可讓開發者基於此基礎,設計出User Mode的RTOS。 - 優點:方便移植到其他不同的MCU,**免費且開源**。 - 缺點:面向底層,Code比較多。 ## TI-RTOS Kernel (SYS/BIOS) - 為Ti開發,針對自家MCU做相對應的優化,基於POSIX設計。 - 特點:使用起來跟FreeRTOS同樣簡單(User Mode),可共用於 Ti 自家的MCU。 - 保留並開放POSIX API,供開發者使用。 # 初始化 ## POSIX API ### Include ```c /* POSIX Header files */ #include <pthread.h> /* RTOS header files */ #include <ti/sysbios/BIOS.h> /* Example/Board Header files */ #include "Board.h" ``` ### Global Define & Declare ```c /* Stack size in bytes */ #define THREADSTACKSIZE 1024 ``` ### Main ```c pthread_t thread; // pthread 結構體 pthread_attr_t attrs; // pthread 參數 struct sched_param priParam; // 儲存每個Task的優先權 int retc; // 回傳值,用來確認POSIX呼叫成功與否 /* (Ti Driver) Call driver init functions */ Board_init(); /* (POSIX) Initialize the attributes structure with default values */ pthread_attr_init(&attrs); /* (POSIX) Set priority, detach state, and stack size attributes */ priParam.sched_priority = 1; retc = pthread_attr_setschedparam(&attrs, &priParam); retc |= pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED); retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE); if (!retc) while (1); // failed to set attributes /* (POSIX) Create Task */ retc = pthread_create(&thread, &attrs, mainThread, NULL); if (!retc) while (1); // pthread_create() failed /* * (Ti RTOS Kernel) Start Kernel => Run Task * In FreeRTOS: vTaskStartScheduler() */ BIOS_start(); ``` ### Task Function ```c void *mainThread(void *arg0) { // Do Something... } ``` ## TI-RTOS Kernel (SYS/BIOS) ### Include ```c /* XDC Module Headers */ #include <xdc/std.h> /* BIOS Module Headers */ #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> #include <ti/sysbios/knl/Clock.h> /* Example/Board Header files */ #include "Board.h" ``` ### Global Define & Declare ```c #define STACK_SIZE 512 // Task 堆疊大小 (用bytes表示) Task_Struct workTask; // Task 結構體 #pragma DATA_ALIGN(workTaskStack, 8) // 對齊變數型別與記憶體使用量 static uint8_t workTasStack [STACK_SIZE]; // Task 堆疊 ``` ### Main ```c /* (Ti RTOS Kernel) Initialize Task Parameter */ Task_Params workTaskParams; Task_Params_init(&workTaskParams); /* (Ti RTOS Kernel) Setup Task Parameter And Register Task */ workTaskParams.stackSize = STACK_SIZE; workTaskParams.priority = 1; workTaskParams.stack = &workTaskStack; Task_construct(&workTask, TaskFunction, &workTaskParams, NULL); /* * (Ti RTOS Kernel) Start Kernel => Run Task * In FreeRTOS: vTaskStartScheduler() */ BIOS_start(); ``` ### Task Function ```c void TaskFunction(UArg arg0, UArg arg1) { // Do Something... } ``` # CPU等待 - 在RTOS的Task,`sleep`函數將會失去功用。需改用`Task_sleep`函數。 ```c Task_sleep(200 * (1000 / Clock_tickPeriod)); // Wait 200ms ``` - Clock_tickPeriod:系統時鐘的運作週期。可以在`xxx.cfg`中設定。 ```js /* ================ Clock configuration ================ */ var Clock = xdc.useModule('ti.sysbios.knl.Clock'); /* * When using Power and calibrateRCOSC is set to true, this should be set to 10. * The timer used by the Clock module supports TickMode_DYNAMIC. This enables us * to set the tick period to 10 us without generating the overhead of additional * interrupts. * * Note: The calibrateRCOSC parameter is set within the Power configuration * structure in the "Board.c" file. */ Clock.tickPeriod = 10; ``` # 資源 ![](https://i.imgur.com/3cBErXD.png) - [Ti Accamdemy](https://dev.ti.com/tirex/explore/node?node=AIcL0-Z-6OJYQ1PZXxV6Mw__eCfARaV__LATEST) - [IT幫幫忙 - POSIX API](https://ithelp.ithome.com.tw/articles/10280830?sc=rss.iron)