1. 程式人生 > >nu-lb-nuc140 RTX 流程 分析(二)

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

1
#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

(OS_TASKCNT-OS_PRIVCNT+1)+2]
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_STKSIZE
4);
size = ( (OS_PRIVCNT<<16) | (OS_STKSIZE4)) >> 2 ;
size = (64
4)>>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

(稍後補充)