Hooks:
OS_CTX_SW_HOOK{
}
空的, 每次context switch發生就會呼叫一次, 讓user寫入事件用
進入第三章...
critical sections:
application本身在user mode下不能直接call enable interrupt and disable interrupt, 必須透過system call, 但在kernel下可以
可以用semaphore()或enable/disable interrupt來保護
semaphore(): 用約二三十行來保護資料
若只保護1行資料, 感覺上很大費周章
DI, EI: 只用兩行
效能較高(降低overhead)
但若保護的程式碼很長, 會使DI, EI的時間變久, 會讓有些interrput都無法執行
OS_ENTER_CRITICAL(); /*在此執行OS_TIME_DELAY();*/ OS_EXIT_CRITICAL();
這樣通常會讓系統crash掉, 唯讀x86不會, 因為context switch時會讓interrput再度打開
實做critical section的三種方法:
1.OS_CRITICAL_METHOD=1
最簡單的方法, 無使用到save & restore
func1(){
DI;
func2();
.../*離開critical section*/
EI;
}
func2(){
DI;
...
EI;
/*離開critical section*/
}
這樣會出問題, 所以call function時要先注意function內有無DI, EI
2.OS_CRITICAL_METHOD=2
PSW(processor status word)用於save & restore stacks
使用stack來實做nested interrput enable/disable interrupt
3.OS_CRITICAL_METHOD=3
PSW相較於method2不局限於存在stack, 而可以存在memory中
OSTaskChangePrio()
可改變task priority=task ID, 但更改可能造成某些程式不能跑(扯到task ID)
OSTaskDel(xxx)
xxx=OS_PRIO_SELF代表刪除自己
xxx=task ID 代表刪除task IDxxx的task
(task無法用returne關掉)
OSTimeDly(), OSTimeDlyHMSM(), OSFlagPend(), OSSemPend(), OSMboxPend(), OSQPend
均會使task進入到waiting Q中
OSTimeTick()會使task回到ready Q中
全部task都進入waiting Q怎麼辦?
ans: idle task永遠在ready Q
doubley linked的好處: delete方便
*OSTCBCur;//目前正在執行的task
*OSTCBFreeList;//指向TCB開頭
*OSTCBHighRdy;//priority最高的task
*OSTCBList;//all task均可由此list找到
*OSTCBPrioTbl[];//找TCB用
OSTCBTbl[];//預先配置好的TCB
*OSTCBCur;與*OSTCBHighRdy;只有在context switch時才會不一樣
2009年3月17日 星期二
03/16
小考:
void Task(void *pdata){
INT8U x;
INT8U y;
INT8U err;
for(;;){
OSSemPend(RandomSem, 0, &err);
x=random(80);
y=random(16);
OSSemPost(RandomSem);
PC_DispChar(x, y+5, *(char*)pdata, DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
OSTimeDly(1);
}
}
橘色部份是讓10個task在執行時隨機印出他 們的名子
此段程式碼用Semaphore去保護
若给為用OS_ENTER_CRITICAL(); OS_EXIT_CRITICAL();去保護
也就是disable interrupt, enable interrupt去保護, 可不可以?
ans:
可以, 但同時也禁止interrupt的執行
若用Semaphore去保護, 執行到critical section, 突然有interrupt進來要修改critical section中被保護的資料, 就保護不了.
這兩種方法各有優缺點, 到底要用哪種, 取決於該段保護的資料有可能被誰存取.
在此段程式碼中, 因為只有可能被task存取, 很少有機會被interrput存取, 所以用Semaphore去保護
開始上課...
idle task是priority最低的task, 功能是一直做加法(無意義的事...)
可以用來判斷CPU的使用率, ex: 加法做20次/毫秒=>CPU使用率0%, 加法做0次/毫秒=>CPU使用率100%
TaskStart():
AckMbox=OSMboxCreate((void*)0);
TxMbox=OSMboxCreate((void*)0);
用於建立MSN的IPC(inter process communication), 因為在建立TCP時就事先allocate了, 所以速度快
PC_DOSReturn();
修改pc值, 使強制回到main function
Task1(): 統計Stack空間
Task2(): 一直印 '', '/', '-', '\'
Task3(): 一直印 '', '/', '-', '\', 且將 '?' 填入dymmy[i] (很明顯的, stack使用率高於Task2())
char dymmy[500];
INT16U i;
此兩行資料誰放在stack最上方, 所造成的CPU使用率不同. 若發現比較高, 則把此兩行對掉即可改變stack方式使CPU使用率降低
Task4(): priority=4
Task5(): priority=5(永比task4高)
兩個task互相傳MSN(task4:" #*(&%@!... ", task5: "恩"....)
task4會在OSMboxPend(AckMbox, 0, &err)等待task5的回應, 且task5的OSTimeDlyHMSM(0, 0, 1, 0)會等待1秒, 所以priority高的task5不會一直執行
linux 2.6, linux 2.4 and uC/OS-II 之stack的比較:
linux2.6:
stack大小為4k or 8k
user mode下有的stack, kernel mode下也有一模一樣的stack
interrupt service routines(kernel mode)有的stack, kernel service routine(kernel mode )也有相對應的stack
優: 各自有各自的stack比較安全, 省記憶體空間
缺: 執行上比較慢
linux 2.4:
stack大小一定為8k, 因為要預留4k給ISR使用
將對於linux2.6不同的地方在於 interrupt service routines沒有stack, 而與kernel service routines下的stack共用
優: 速度上比linux2.6還要快一點
缺: 記憶體空間比linux2.6浪費
uC/OS-II:
stack大小一定為8k
只有kernel mode, 沒有user mode
kernel mode, kernel service rouutines and interrupt service routines 都使用同一個stack
優: 執行速度上是最快的
缺: 記憶體空間使用上是最浪費的
void Task(void *pdata){
INT8U x;
INT8U y;
INT8U err;
for(;;){
OSSemPend(RandomSem, 0, &err);
x=random(80);
y=random(16);
OSSemPost(RandomSem);
PC_DispChar(x, y+5, *(char*)pdata, DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);
OSTimeDly(1);
}
}
橘色部份是讓10個task在執行時隨機印出他 們的名子
此段程式碼用Semaphore去保護
若给為用OS_ENTER_CRITICAL(); OS_EXIT_CRITICAL();去保護
也就是disable interrupt, enable interrupt去保護, 可不可以?
ans:
可以, 但同時也禁止interrupt的執行
若用Semaphore去保護, 執行到critical section, 突然有interrupt進來要修改critical section中被保護的資料, 就保護不了.
這兩種方法各有優缺點, 到底要用哪種, 取決於該段保護的資料有可能被誰存取.
在此段程式碼中, 因為只有可能被task存取, 很少有機會被interrput存取, 所以用Semaphore去保護
開始上課...
idle task是priority最低的task, 功能是一直做加法(無意義的事...)
可以用來判斷CPU的使用率, ex: 加法做20次/毫秒=>CPU使用率0%, 加法做0次/毫秒=>CPU使用率100%
TaskStart():
AckMbox=OSMboxCreate((void*)0);
TxMbox=OSMboxCreate((void*)0);
用於建立MSN的IPC(inter process communication), 因為在建立TCP時就事先allocate了, 所以速度快
PC_DOSReturn();
修改pc值, 使強制回到main function
Task1(): 統計Stack空間
Task2(): 一直印 '', '/', '-', '\'
Task3(): 一直印 '', '/', '-', '\', 且將 '?' 填入dymmy[i] (很明顯的, stack使用率高於Task2())
char dymmy[500];
INT16U i;
此兩行資料誰放在stack最上方, 所造成的CPU使用率不同. 若發現比較高, 則把此兩行對掉即可改變stack方式使CPU使用率降低
Task4(): priority=4
Task5(): priority=5(永比task4高)
兩個task互相傳MSN(task4:" #*(&%@!... ", task5: "恩"....)
task4會在OSMboxPend(AckMbox, 0, &err)等待task5的回應, 且task5的OSTimeDlyHMSM(0, 0, 1, 0)會等待1秒, 所以priority高的task5不會一直執行
linux 2.6, linux 2.4 and uC/OS-II 之stack的比較:
linux2.6:
stack大小為4k or 8k
user mode下有的stack, kernel mode下也有一模一樣的stack
interrupt service routines(kernel mode)有的stack, kernel service routine(kernel mode )也有相對應的stack
優: 各自有各自的stack比較安全, 省記憶體空間
缺: 執行上比較慢
linux 2.4:
stack大小一定為8k, 因為要預留4k給ISR使用
將對於linux2.6不同的地方在於 interrupt service routines沒有stack, 而與kernel service routines下的stack共用
優: 速度上比linux2.6還要快一點
缺: 記憶體空間比linux2.6浪費
uC/OS-II:
stack大小一定為8k
只有kernel mode, 沒有user mode
kernel mode, kernel service rouutines and interrupt service routines 都使用同一個stack
優: 執行速度上是最快的
缺: 記憶體空間使用上是最浪費的
2009年3月9日 星期一
03/09
小考:
DOS可視為MC/OSII的boot loader
IVT的功能?內容物?機制?
1.當interrupt進來時, 用於中斷CUP目前正在執行的事, 轉而執行interrupt
2.一道指令或向量
3.借由一道指令或向量跳到ISR裡去執行interrupt
PC_VectSet()
要用什麼方法保護資料取決於該筆資料可能會由誰去讀
OSTaskCreate()
1.create TCB 放到 ready Q
2.
OSTaskCreate(
TaskStart, //第一到指令所在位置(function name)
(void*)0, //參數(被TaskStart用到)
&TaskStartStk[TASK_STK_SIZE-1], //stack開頭(與CPU設計有關, 跨平台需要修改, 設計上失敗, 但速度快)
0 //設定優先權
);
OSStart()
找出CPU中priority最高的task並將CPU控制權交給它
(never return)
return 定義
指執行ret這道組合語言
OSStart之後剛開始只有兩個task, 分別為TaskStart, idle task
因為idle task的priority=63...非常低, 所以由TaskStart先開始執行
OSTimeDLYhmsm 利用類似poling的方式去檢查有無按esc此鍵
若有則用longjmp指令回到boot loader(一般都直接關機不會回boot loader)
注意: 在此絕對不是return
DOS可視為MC/OSII的boot loader
IVT的功能?內容物?機制?
1.當interrupt進來時, 用於中斷CUP目前正在執行的事, 轉而執行interrupt
2.一道指令或向量
3.借由一道指令或向量跳到ISR裡去執行interrupt
PC_VectSet()
要用什麼方法保護資料取決於該筆資料可能會由誰去讀
OSTaskCreate()
1.create TCB 放到 ready Q
2.
OSTaskCreate(
TaskStart, //第一到指令所在位置(function name)
(void*)0, //參數(被TaskStart用到)
&TaskStartStk[TASK_STK_SIZE-1], //stack開頭(與CPU設計有關, 跨平台需要修改, 設計上失敗, 但速度快)
0 //設定優先權
);
OSStart()
找出CPU中priority最高的task並將CPU控制權交給它
(never return)
return 定義
指執行ret這道組合語言
OSStart之後剛開始只有兩個task, 分別為TaskStart, idle task
因為idle task的priority=63...非常低, 所以由TaskStart先開始執行
OSTimeDLYhmsm 利用類似poling的方式去檢查有無按esc此鍵
若有則用longjmp指令回到boot loader(一般都直接關機不會回boot loader)
注意: 在此絕對不是return
訂閱:
文章 (Atom)
