---
tags: Develop, MCU
---
# Ti RTOS Note

# 目錄
[TOC]
# Bare Metal vs RTOS

- 是在「沒有作業系統」的狀況下去開發程式。
- 在此模式下會去開發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;
```
# 資源

- [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)