os任務切換源程式分析
先要宣告任務指標,因為後面需要使用。
//任務指標.
volatile task_tcb* volatile g_pcurrenttask = null;
volatile task_tcb* volatile g_pcurrenttask1 = null;
volatile task_tcb* volatile g_pcurrenttask2 = null;
/////函式名稱: taskinitstack
//函式功能: 分配任務的棧。
//輸入引數:
//輸出引數:
//返 回 值:
//開發人員: 蔡軍生
//時間: 2006/02/26
//修改說明: //
///void taskinitstack(void)
接著再建立兩個簡單的任務,它們都是輸出一行字串,就等待一會,**如下://
void tasktest1(void)
} //
void tasktest2(void)
} 然後再初始化任務棧,**如下:
void taskstart(void)
**初始化了兩個任務棧後,接著設定第乙個任務為優先執行的任務。
最後就需要進行中斷任務排程任務進行執行了,**如下:
///
//函式名稱: einttickisr
//函式功能: 時鐘中斷函式。
//輸入引數:
//輸出引數:
//返 回 值:
//開發人員: 蔡軍生
//時間: 2006/02/26
//修改說明: //
///void einttickisr(void) __attribute__((naked));
void einttickisr(void)
");
//關閉tick中斷.
intmsk |= bit_global|bit_tick;
//取得儲存irq的lr位址,並儲存lr.
asm volatile (" ldr r0,=g_dwirqlr" );
asm volatile (" subs lr,lr,#4 ");
asm volatile (" str lr,[r0] ");
//取回前面儲存的r0-r12寄存的值.
asm volatile (" ldmia sp!, ");
//取得最後返回的spsr,就是svc模式下的cpsr.
//從irq模式切換回到svc模式.
asm volatile (" mrs lr,spsr ");
asm volatile (" orr lr,#0xc0 ");
asm volatile (" msr cpsr,lr ");
//現在已經轉換回到svc模式,取回irq模式下儲存的lr.
//把r0的值儲存到棧中第二個位置.
asm volatile (" str r0,[sp,#-8] ");
//從儲存位置取回irq模式下儲存的lr值.
asm volatile (" ldr r0,=g_dwirqlr" );
asm volatile (" ldr r0,[r0] ");
//把irq模式下的lr儲存到棧裡,就是出棧時的pc值.
asm volatile (" s***b sp!, ");
//從棧裡第二個位置取回先前儲存的r0值.
asm volatile (" subs sp,sp,#4 ");
asm volatile (" ldmia sp!, ");
//儲存r0-r12,lr到棧裡,入棧順序是剛好相反的.
asm volatile (" s***b sp!, ");
//儲存cpsr的值到棧裡,就是spsr的位置.
asm volatile (" mrs r4,cpsr ");
asm volatile (" bic r4,#0xc0 ");
asm volatile (" s***b sp!, ");
//儲存棧頂到任務指標裡.
asm volatile ( "ldr r0, %0" : : "m" (g_pcurrenttask) );
asm volatile ( "str sp, [r0]" );
//增加時鐘計數.
g_dwtickcount++;
// printf("g_dwtickcount = (%d)/n",g_dwtickcount);
// //清除遮蔽位.
i_ispc = bit_tick;
intmsk &= ~(bit_global|bit_tick); //
if (g_dwtickcount < 3)
else if (g_dwtickcount < 4)
else
//取得新任務指標
asm volatile ( "ldr r0, %0" : : "m" (g_pcurrenttask) );
asm volatile ( "ldr sp, [r0]" );
//取回spsr值.
asm volatile ( "ldmia sp!, " );
asm volatile ( "msr spsr, r0" );
//取回r0-r12,lr,pc值,並執行最後的任務.
asm volatile ( "ldmia sp!, ^" ); }
寫完上面的**,就可以真正地實現了任務排程了。有了以上的**,寫其它複雜的任務除錯都變得很容易了,這些**得來是不太容易的,我經歷了好幾個星期的除錯才通過的。
這些都是在我的s3c44b0開發板上除錯通過的,如果你沒有開發板,可以跟我購買。聯絡方法ccaimouse#gmail.com(請把#換成@
)。
學習ARM開發20 21
學習arm開發 20 os的任務切換 有了前面的tick中斷,那麼基本的任務切換條件已經是 萬事俱備,只欠東風 了。不過,這個 東風 也是很難搞得懂的,只有不斷地通過實踐才會找到合適的方法。現在我就需要去找這個東風了,就是解決不同的任務切換的問題。從簡單到複雜,這是任何事物的認識過程,也是行之有效的...
學習ARM開發 5
學習arm開發 5 蔡軍生 2005 07 16 寫於深圳 上一次說到要學習uboot的 但在看之前,首先要知道目標機器的程式設計資源,這裡的資源,是指s3c44b0所提供的執行程式的資源,對任何嵌入式軟體開發,都首先要對硬體有乙個很好的了解,這跟pc機的程式設計是大不一樣的。因為pc機都已經發展了...
學習ARM開發 9
學習arm開發 9 上一次把引導的彙編看完,已經準備c的執行環境,下面就開始學習c的源程式,從start.s檔案裡到跳檔案 lib arm board.c裡執行.引導程式從彙編start.s裡跳到這裡執行。蔡軍生 2005 07 19 void start armboot void 宣告乙個全域性指...