nu-lb-nuc140 RTX 流程 分析(二)
0 參考資料
http://www.stmcu.org.cn/module/forum/thread-605101-1-1.html
【安富萊】【RTX作業系統教程】第18章 記憶體管理
1 巨集定義
__TARGET_ARCH_6S_M
__USE_EXCLUSIVE_ACCESS 定義了
__TARGET_ARCH_7_M
__TARGET_ARCH_7E_M
DBG_MSG 沒有定義
#if (__TARGET_ARCH_6S_M || __TARGET_ARCH_7_M || __TARGET_ARCH_7E_M)
#define CM 1
#elif (__TARGET_ARCH_7_R)
#define CR
#else
#define ARM 1
#endif
2 名詞解釋
Round Robin 輪詢排程
concurrent 同時發生的
TCB - 執行緒控制塊(Thread Control Block,TCB)
systemvariables – 系統變數
3 mp_stk 結構
#define OS_STKSIZE 64 // 系統分配給每個任務的棧的大小
#define OS_TASKCNT 7 //同時執行的最大任務數目
#define OS_PRIVCNT 0 // 使用者自己 提供指定棧的記憶體空間,不用使用者提供的任務的數量
unsigned long long mp_stk[((OS_STKSIZE4)+7)/8
unsigned long long mp_stk[((644)+7)/8(7-0+1)+2]
unsigned long long mp_stk[32*8+2]
佔用的空間大小為:258 x 64/8 = 258 x 8 bytes = 2064 bytes
每個任務的堆疊 佔用的 位元組數目為 64 int 型 ,64x4 = 256位元組
U32 const mp_stk_size = sizeof(mp_stk);
#define BOX_ALIGN_8 0x80000000
#define OS_STKCHECK 1 // 檢查棧是否overflow
U32 const os_stackinfo = (OS_STKCHECK<<24)| (OS_PRIVCNT<<16) | (OS_STKSIZE*4);
rt_init_box (&mp_stk, mp_stk_size, BOX_ALIGN_8 | (U16)(os_stackinfo));
int _init_box (void *box_mem, U32 box_size, U32 blk_size)
os_stackinfo = 256位元組
4 rt_sys_init 函式解析
__task void init (void) {
t_phaseA = os_tsk_create (phaseA, 1); /* start task phaseA */
......
os_evt_set (0x0001, t_phaseA); /* send signal event to task phaseA */
os_tsk_delete_self ();
}
os_sys_init(init);
#define os_sys_init(tsk) os_set_env(); \
_os_sys_init((U32)rt_sys_init,tsk,0,NULL)
void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk)
void rt_sys_init (init, 0, NULL)
5 解析_init_box 函式
除錯 rt_sys_init 中的rt_init_box (&mp_stk, mp_stk_size, BOX_ALIGN_8 | (U16)(os_stackinfo));
這個結構體的大小為:
sizeof_bm = (sizeof (struct OS_BM) + 7) & ~7;
sizeof_bm = 16
p_BM->free = 0x2000 0210
p_BM->end = 0x2000 0A10
p_BM->blk_size = 0x0000 0100
next_block = 0x2000 0210 – task1
next_block = 0x2000 0310 – task2
next_block = 0x2000 0410 – task3
next_block = 0x2000 0510 – task4
next_block = 0x2000 0610 – task5
next_block = 0x2000 0710 – task6
next_block = 0x2000 0810 – task7
next_block = 0x2000 0910
next_block = 0x2000 0A10
6 解析rt_alloc_box函式
p_TCB->stack = rt_alloc_box (mp_stk);
void *rt_alloc_box (void *box_mem)
void *rt_alloc_box (void *box_mem) {
/* Allocate a memory block and return start address. */
void **free;
int irq_dis;
irq_dis = __disable_irq ();
free = ((P_BM) box_mem)->free; // block1的地址
if (free) { // 如果為0 表示到末尾了
((P_BM) box_mem)->free = *free; //block1的開頭存放的是block2的地址
}
if (!irq_dis) __enable_irq ();
return (free); // 返回block1的地址
}
7 解析rt_init_context
struct OS_TCB os_idle_TCB;
rt_init_context (&os_idle_TCB, 0, os_idle_demon);
8解析 rt_init_stack
void rt_init_stack (P_TCB p_TCB, FUNCP task_body)
U32 size ;
#define OS_STKSIZE 64
U32 const os_stackinfo = (OS_STKCHECK<<24)| (OS_PRIVCNT<<16) | (OS_STKSIZE4);
size = (U16)os_stackinfo >> 2;
(U16)os_stackinfo = (OS_PRIVCNT<<16) | (OS_STKSIZE4);
size = ( (OS_PRIVCNT<<16) | (OS_STKSIZE4)) >> 2 ;
size = (644)>>2
size = 256>>2 = 256 /4 = 64
#define MAGIC_WORD 0xE25A2EA5
#define INITIAL_xPSR 0x01000000
9解析 rt_sys_init
10 解析 rt_tsk_create
void rt_sys_init (init, 0, NULL)
rt_tsk_create (first_task, prio_stksz, stk, NULL);
OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv)
task = init
prio_stksz = 0
stk = NULL
argv = NULL
11 解析 mp_tcb
#define OS_TCB_SIZE 56
#define OS_TASKCNT 7
#define _declare_box(pool,size,cnt) U32 pool[(((size)+3)/4)(cnt) + 3]
extern U32 mp_tcb[];
/ Memory pool for TCB allocation */
_declare_box (mp_tcb, OS_TCB_SIZE, OS_TASKCNT);
U16 const mp_tcb_size = sizeof(mp_tcb);
U32 mp_tcb[(((OS_TCB_SIZE)+3)/4)(OS_TASKCNT) + 3]
U32 mp_tcb[(((56)+3)/4)(7) + 3]
U32 mp_tcb[14*7 + 3]
U32 mp_tcb[101]
mp_tcb 的地址範圍為:
0x2000 006c 到 0x2000 0200
_init_box 中:sizeof_bm = 12 = 0x0000 000C
end = 0x2000 01C8
blk_size = 0x38 = 56
box_size = 404 = 0x194
P_BM->free = 0x2000 0078
P_BM->end = 0x2000 0200
P_BM->blk_size = 0x0000 0038
block1 = 0x2000 00B0
block2 = 0x2000 00E8
block3 = 0x2000 0120
block4 = 0x2000 0158
block5 = 0x2000 0190
block6 =0x2000 01C8
12 os_tsk
typedef struct OS_TCB {
/* General part: identical for all implementations. */
U8 cb_type; /* Control Block Type */
U8 state; /* Task state */
U8 prio; /* Execution priority */
U8 task_id; /* Task ID value for optimized TCB access */
struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */
struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */
struct OS_TCB *p_dlnk; /* Link pointer for delay list */
struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */
U16 delta_time; /* Time until time out */
U16 interval_time; /* Time interval for periodic waits */
U16 events; /* Event flags */
U16 waits; /* Wait flags */
void **msg; /* Direct message passing when task waits */
struct OS_MUCB *p_mlnk; /* Link pointer for mutex owner list */
U8 prio_base; /* Base priority */
U8 ret_val; /* Return value upon completion of a wait */
/* Hardware dependant part: specific for CM processor */
U8 ret_upd; /* Updated return value */
U16 priv_stack; /* Private stack size, 0= system assigned */
U32 tsk_stack; /* Current task Stack pointer (R13) */
U32 *stack; /* Pointer to Task Stack memory block */
/* Task entry point used for uVision debugger */
FUNCP ptask; /* Task entry address */
} *P_TCB;
typedef struct OS_TSK {
P_TCB run; /* Current running task */
P_TCB new; /* Scheduled task to run */
} *P_TSK;
struct OS_TSK os_tsk;
os_tsk 0x20000058 Data 8 rt_task.o(.data)
0x20000060 - 8 = 0x20000058
R1 = 0x20000AE0 ----> run
R2 = 0x20000078 -----> new
R3 = 0x20000058
R0 = 0x00000001
PUSH {R2,R3} ---- > 儲存到堆疊中
#define TCB_RETUPD 38 /* ‘ret_upd’ offset */
os_idle_TCB 0x20000ae0 Data 56 rt_task.o(.bss)
struct OS_TCB os_idle_TCB;
init函式的地址為:0x0000 0DE1 ------F0C
(稍後補充)