學習ARM開發 21

2021-08-22 02:15:07 字數 2917 閱讀 7281

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 宣告乙個全域性指...