嵌入式實時作業系統small RTOS51原理及應用 ----筆記 第五章 如何任務切換
嵌入式實時作業系統small RTOS51原理及應用 ----筆記 第五章 如何任務切換
5.3 何時進行任務切換
參考書籍<MCS-51微控制器原理與應用.pdf>
TMOD = (TMOD & 0XF0) | 0X01;
TL0 = 0x0;
TH0 = 0x0;
TR0 = 1;
ET0 = 1;
OSStart 解析
extern idata uint8 STACK[1]; /* 堆疊起始位置,在OS_CPU_A定義 */
#define IDATA_RAM_SIZE 0x100 /* idata大小 */
0x100 = 256
uint8 idata * data OSTsakStackBotton[OS_MAX_TASKS + 2];/* 任務堆疊底部位置 */
sfr SP = 0x81;
p++等價於:先處理p,然後在執行p++;舉個列子(虛擬碼)
片內 RAM 的定址範圍:普通型128B(00H~7FH)、增強型256B(00H~FFH)。
D:0088H PUBLIC TCON
B:00A8H.1 PUBLIC ET0
D:008CH PUBLIC TH0
D:008AH PUBLIC TL0
C:03F4H PUBLIC TaskA
B:0088H.4 PUBLIC TR0
C:03FEH PUBLIC TaskB
C:0408H PUBLIC TaskC
D:00C8H PUBLIC T2CON
D:00D0H PUBLIC PSW
idata ----- RAM 區的高128B,必須採用間接定址
C:0424H PUBLIC OSIdle
D:0081H PUBLIC SP
http://www.keil.com/dd/chip/2980.htm
KEIL之除錯檢視ROM或RAM
則右下角出現Memory1的頁面,默認出現的是ROM的檢視介面,在Address一欄輸入十六進位制的地址即可檢視ROM裡面的數值。
點選Memory Windows按鍵右邊黑三角選擇Memory2,則在右下角出現Memory2的標籤頁面,在Address一欄輸入D:20H,代表檢視RAM中20H中的數值。
Ctrl+F5或點選除錯按鈕進入除錯介面:
彙編程式碼解析:
MOV A,#OS_MAX_TASKS
XRL A,OSTaskID ----- 異或 相同為0 ,相異為1
JNZ OSIntCtxSw_0 ------ 若累加器的值不為0,則跳到rel所對應的目的地址
;是則不需要儲存所有暫存器
;SP=SP-13-4 ;4:兩層函式呼叫堆疊,13:暫存器數目
MOV A,#(-17)
ADD A,SP
MOV SP,A
;跳轉到OSCtxSw,同時通知CPU中斷處理完成
MOV A, #LOW OSCtxSw
PUSH ACC
MOV A, #HIGH OSCtxSw
PUSH ACC
RETI
;需要儲存所有暫存器
OSIntCtxSw_0:
;SP=SP-4 ;4:兩層函式呼叫堆疊
MOV A,#0FCH ;將立即數0FCH 存放到累加器中
ADD A,SP ;
MOV SP,A
;設定標誌:任務再次恢復執行時需要恢復所有暫存器
MOV DPTR,#OSMapTbl
MOV A,OSTaskID
#if OS_MAX_TASKS < 9
MOVC A,@A+DPTR
CPL A
ANL A,OSFastSwap
MOV OSFastSwap,A
#else
CLR C
SUBB A,#8
JC OSIntCtxSw_1
MOVC A,@A+DPTR
CPL A
ANL A,OSFastSwap
MOV OSFastSwap,A
SJMP OSIntCtxSw_2
OSIntCtxSw_1:
MOV A,OSTaskID
MOVC A,@A+DPTR
CPL A
ANL A,OSFastSwap+1
MOV OSFastSwap+1,A
OSIntCtxSw_2:
#endif
;跳轉到堆疊處理,同時通知CPU中斷處理完成
MOV A, #LOW C_OSCtxSw
PUSH ACC
MOV A, #HIGH C_OSCtxSw
PUSH ACC
RETI
;****************************************************************************************
END
彙編語法
MOV dst src
MOV 目的 源
邏輯異或(XRL):
HIGH
和
LOW
稱為位元組分離操作符,它接收一個數或地址表示式,
HIGH取其高位位元組,LOW取其低位位元組
MOVC A,@A+DPTR
將累加器的值加上資料指標暫存器的值,
為指定程式儲存器地址的內容讀入到累加
器中
CPL bit
將直接位地址的內容取反
CPL C
將位累加器C的值取反
#if OS_MAX_TASKS < 9
uint8 data OSFastSwap = 0xff; /* 任務是否可以快速切換 */
#else
uint16 data OSFastSwap = 0xffff;
#endif
搭建使用 RTX51-Tiny 的 C51 Keil 專案環境
https://blog.csdn.net/Airbnb/article/details/41692353?utm_source=blogxgwz4
-
51棧向上增長,ARM和MIPS向下增長
-
51暫存器是直接定址,記憶體是間接定址。暫存器的0x80-0xff和記憶體的0x80-0xff一致,但物理單元不同。
-
const定義的變數還是在data memory。如果要定義到ROM必須要用code
MCS-51 TM
code Program memory (64 KBytes); accessed by opcode MOVC @A+DPTR.
http://www.keil.com/support/man/docs/c51/c51_le_memtypes.htm
Easy51RTOS入門級初略分析
http://www.keil.com/support/man/docs/tr51/tr51_reentrant.htm
Reentrant Functions
The C51 Compiler provides support for reentrant functions. Reentrant functions store parameters and local variables on a reentrant stack. This protects them from recursive or simultaneous calls. RTX51 Tiny does not contain any management for the C51 reentrant stack. So, if you use reentrant functions in your application, you must ensure that these functions do not call any RTX51 Tiny system functions and that reentrant functions are not interrupted by round-robin task switching.
C functions, which use only registers for parameter and automatic variables, are inherently reentrant and may be called without any restrictions from RTX51 Tiny.
Non-reentrant C functions may not be called from more than one task or interrupt procedure. Non-reentrant C51 functions store their parameters and automatic variables (local data) in static memory segments which may be overwritten when the function is called from multiple tasks simultaneously or recursively.
You may invoke non-reentrant functions from multiple tasks if you ensure that they are not called recursively (simultaneously). Usually this means that round-robin task scheduling must be disabled and that your non-reentrant functions may not call any RTX51 Tiny system functions.
Note
You should disable Round-Robin Task Switching if you wish to invoke reentrant or non-reentrant function from more than one task or interrupt.
(以後補充)