2009年6月18日 星期四

OSSemPend() OSSemPost() 程式碼













OSSemPend()-1
(點擊可放大看)















OSSemPend()-2
(點擊可放大看)















OSSemPost()
(點擊可放大看)


OS學期心得

這學期給我的第一印象是

放假也放太多了吧~~~

到學期末好幾星期連續補課

幾個禮拜下來有種快掛掉的感覺

------------------------------------

uCOSII 與 linux 學習成效比較:

uCOSII 感覺比較有重點, 容易吸收

到最後 linux 老師在教得時候

有點搞不太懂重點在哪裡 想讓我們了解什麼

或許是 linux 東西太多太雜了 不好教 也不好懂

或許是 時間太短了 教得比較急促

----------------------------------

最後想抱怨期末proj...

也許是我能力欠缺

花了還蠻多時間在研究

雖然最後有做出來

可是卻遲交了

這是我第一次遲交作業 還蠻難過的

-------------------------------------

整體來看 受益頗多的

至少讓我更了解OS做作些什麼

想當初大一時 連作業系統是什麼都不知道

以前剛接觸到fedora freeBSD時

用起來都會怕怕的

現在已經可以跟用windows XP 一樣運用自如

OSSemPend()

OSEventCnt=1

task到kernel中執行完此event再回到user mode下繼續執行


前提: task 2已經進入critical section, OSEventCnt=0,

因為OSEventCnt=0, 讓task 1進入waiting狀態 並觸發sched() 把控制權交給task 2

等待task 2執行完, 呼叫sched() 讓task 1繼續執行


前提: task 2已經進入critical section 且沒有動作, OSEventCnt=0,

因為OSEventCnt=0, 所以task 1進入waiting狀態,

又因為task 2一直沒有動作, 所以最後task 1被timer叫醒

回到user mode

2009年4月18日 星期六

04/15

OS_Sched() and OSIntExit():
  1. OS_Sched(): 掌管 task 間的 scheduling
  2. OSIntExit(): 掌管 ISR 的 scheduling
下段程式碼, 若剛好進入contextswitch()怎麼辦(如何EI)?
ans:
OS_Sched(){
...
DI;
...
if(){
contextswitch();
}
...
EI;
...
}

A經context switch 到B後, 由B process做EI;

04/13

Ready list:
  1. heap:
    • ins: O(logn)
    • del: O(logn)
    • min: O(1)
  2. uC/OSII:
    • ins: O(1)
    • del: O(1)
    • min: O(1)
如果有了task的priority, 如何求出他在OSRdyTbl[]所在的位置:
若OSRdyTbl[]為n*n, n一定為2的power,
則x=priority/n, y=priority%n

2009年4月8日 星期三

04/08

INT8U os_TCBInit(){
...
/*在freelist中, 只有application存取, 可用semaphore取代, 但最好不要, 因為overhead大*/
OS_ENTER_CRITICAL();
ptcb=OSTCBFreeList;
if(){
OSTCBFreeList=ptcb->OSTCBNext;
OS_EXIT_CRITICAL();
...
...
...
/*不可用semaphore取代, 此段功能是把task放到readyQ中, 若用semaphore取代, ISR可能會去存取readyQ, 故不可取代*/
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio]=ptcb;
ptcb->OSTCBNext=OSTCBList;
ptcb->OSTCBPrev=(OS_TCB*)0;
if(OSTCBList!=(OS_TCB*)0){
OSTCBList->OSTCBPrev=ptcb;
}
OSTCBList=ptcb;
OSRdyGrp:=ptcb->OSTCBBitY;
OSRdyTbl[ptcb->OSTCBY]:=ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
...
}

ready list:
在readyQ中要做的3件事:
  1. insert
  2. delete
  3. find min. priority
在uC/OSII中, 因為insert時只限制priority=0~63的task進入readyQ, 演算法特殊, 故做這三件事都只有O(1)

由ready list再加上 OSUnMapTbl[]可迅速查出目前readyQ中priority最高的task位在哪個位置

2009年3月24日 星期二

03/25

星期一放假...因為五哥的媽媽開刀...
今日小考...
Q:
*OSTCBCur: 目前正在執行的task
*OSTCBHighRdy: priority最高的task
一般來說這兩個值會一樣, 在什麼情況下這兩個值會不同?
ans:
context switch時會不一樣
一開始OSTCBCur & OSTCBHighRdy都指向task A
因為某種原因使task B的priority變高
OSTCBHighRdy指向task B
接下來做context switch, CPU將task A 的TCB存回去, 把task B load進來
最後會讓OSTCBCur = OSTCBHighRdy

TASK CONTROL BLOCK
typedef struct os_tcb{
/*存放指向stack開頭的指標sp, stack中有存regs, pc, psw*/
OS_STK *OSTCBStkPtr;

/*OSTaskCreatEXT才有下列東西, 與此function後面跟的參數一樣*/
#if OS_TASK_CREATE_EXT_EN > 0
void *OSTCBExtPtr;
OS_STK *OSTCBStkBottom;
INT32U OSTCBStkSize;
INT16U OSTCBOpt;
INT16U OSTCBId;
#endif
}

/*把所有TCB串起來(readyQ, waitingQ...)*/

struct os_tcb *OSTCBNext;
struct os_tcb * OSTCBPrev;

/*下列五種功能只有一種用得到, 與行程間的通訊有關, 這樣寫是自己手動最佳化, 省記憶體空間*/
#if ((OS_Q_EN>0)&&(OS_MAX_QS>0))(OS_MBOX_EN>0)(OS_SEM_EN>0)(OS_MUTEX_EN>0)
OS_EUENT *OSTCBEventPtr;
#endif

#if ((OS_Q_EN>0)&&(OS_MAX_QS>0))(OS_MBOX_EN>0)
void *OSTCBMsg;
#endif

#if(...)
#if ...
#endif ...
#endif


/*決定要睡多久, 必須透過systemcall來修改(ex: OSTimeDly...)*/
INT16U OSTCBDly;
INT8U OSTCBStat;
/*task的priority*/
INT8U OSTCBPrio;

/*以下由OSTCBPrio算出來的, 在每次context switch時都會用到, 為加快CPU的速度所以先算起來放, 因為priority的更新速度並沒有比context switch快*/
INT8U OSTCBX;
INT8U OSTCBY;
INT8U OSTCBBitX;
INT8U OSTCBBitY;

#if OS_TASK_DEL_EN>0
/*若要讓該task死掉, 將下值改為1即可*/
BOOLEAN OSTCBDelReg;
#endif
}

OSTCBFreeList:
free TCB串成的list, 可以快速拿到free的TCB, 加快速度
感覺上像是linux中的slab(但平均速度快, 最佳情況比較慢)