TencentOs tiny操作系統簡單分析

獲取源碼

下載地址:https://github.com/Tencent/TencentOS-tiny.git


任務分析

本篇基於stm32f4,從任務說起。

M4屬於armv7m架構,所以可以查看arch/arm/armv7m/cortex-m4文件下彙編等相關內容。

1.任務怎樣創建來的?

編寫一個函數,定義為:tos_task_create(),裡面需要包含參數:要執行的函數、任務的名稱、棧數組、棧的大小、當前任務的優先級等。在tos_task_create()也添加一個任務結構體,存放的就是任務本身所有的屬性值,這點跟freertos,LiteOS做法都不同。可見,AliOS與TencentOS tiny代碼文化真的很相像,也許是阿里的工程師跑到了騰訊,騰訊的工程師跳槽到了阿里,:-)。


2.任務的私有信息需要怎麼存放?

定義一個函數,命名為:cpu_task_stk_init(),裡面參數需要包括棧數組的基地址,然後是棧大小,再個就是參數與執行的函數。然後就是在棧裡面存放寄存器:xPSR、PC、LR、R12、R3、R2、R1、R0,(佔位),R11, R10, R9, R8, R7, R6, R5 and R4等的初始化,要注意返回到PSP模式需要存放一個值。

所以知道前面介紹過的LiteOS,freertos,AliOS基本上在這裡也是一個套路。

可以看到,AliOS與TencentOS tiny在這個地方的實現基本上一模一樣。


3.任務怎麼切換?

對於系統運行,要執行第一個任務,可以調用函數:tos_knl_start(),也就是調用__KNL__ void cpu_sched_start(void),也就是調用port_sched_start(),這個函數是使用匯編編寫的,它將PENSV與SYSTICK設置為最低優先級,然後是開始任務的切換。任務切換絕對屬TencentOS tiny做的最複雜。

之後則是多個任務之間進行調度。

在普通任務中,可以調用函數tos_task_delay(),最終它需要調用到tos_task_yield(),也就是void knl_sched(void);也就是cpu_context_switch(),也就是port_context_switch(),這個函數是一個彙編函數,其實是觸發PENDSV中斷。

對於週期調用的void SysTick_Handler(void)中斷,它會調用到void tos_knl_irq_leave(void);然後會調用到cpu_irq_context_switch(),最終會調用到port_irq_context_switch(),它也是一個彙編函數,也是觸發的PENDSV中斷。也可以發現,這個函數與port_context_switch()內容完全一樣。

所以,也沒什麼新奇的,跟前面講的LiteOS和freertos與AliOS-Things套路還是一樣的。

4.訪問同一個資源(變量)如何處理?

TencentOS tiny與AliOS和LiteOS處理一樣,都是簡單粗暴的操作PRIMASK,這就沒有什麼好說的了。而在中斷中,TencentOS tiny是增加一個變量k_irq_nest_cnt,處理臨界資源的時候,並不關中斷,這跟freertos的任務allsuspend有點像,不過TencentOS tiny在中斷中這麼做效率如何,就需要它好好測試一番了。


本篇也持續更新。。。


分享到:


相關文章: