基於ARM7軟中斷程式的設計

2021-08-28 13:21:32 字數 3241 閱讀 3393

1 儲存器部分原理

筆者在設計一專案時採用lpc2458。此cpu為 核心,帶512k位元組的片內flash,98k位元組的片內ram,支援片外local bus ,可從片外nor flash啟動cpu。由於**量較大,程式放在片外的nor flash中。且存在片外nor flash在執行程式時,需對片外的nor flash擦寫的需求。圖1為儲存部分 。

圖1 儲存部分原理框圖

在設計中,片外nor flash的大小為16m位元組。其中2m規劃為存放執行程式,剩餘的空間用於產品執行日誌,告警燈儲存空間。因此存在著在程式執行時對片外nor flash擦寫的需求。如果程式正在正常執行的片外flash中去擦寫flash,會存在匯流排衝突的問題,無法實現此功能。我們採用arm7核心的swi軟中斷功能來實現。

2 arm軟中斷原理(swi)

軟中斷(swi)目前沒有找到任何官方的正式定義。筆者嘗試與硬中斷對比定義如下:

1. 軟中斷發生的時間是由程式控制的,而硬中斷發生的時間是隨機的。

2. 軟中斷是由程式呼叫發生的,而硬中斷是由外設引發的。

3. 硬中斷處理程式要確保它能快速完成它的任務,這樣程式執行時才不會等待較長的時間。

在c程式中呼叫軟體中斷需要用到編譯器的擴充套件功能,使用關鍵字「_swi」來宣告中斷函式。注意軟中斷號碼同時在函式定義時指定。

_swi(0x24) void my_swi(void);

這樣當呼叫函式my_swi的時候,就會用「swi 0x24」來代替普通的函式呼叫「bl my_swi」。

可以發現軟體中斷同樣存在著中斷分支的問題,即需要根據中斷號碼來決定呼叫不同的處理程式。軟中斷號碼只存在於swi指令碼當中,因此需要在中斷處理程式中讀取觸發中斷的指令**,然後提取中斷號資訊,再進行進一步處理。下面是軟中斷指令的編碼格式:

arm狀態下的swi指令編碼格式,32位長度,其中24位是中斷編號。

thumb狀態下的swi指令編碼格式,16位長度,其中低8位是中斷編號。

為了在中斷處理程式裡面得到swi指令的位址,可以利用lr暫存器。每當響應一次swi的時候,處理器都會自動儲存並調整lr暫存器,使裡面的內容指向swi下一條指令的位址,所以把lr裡面的位址內容上溯一條指令就是所需的間隔不一樣,如果進入swi執行前是在arm狀態下,需要通過lr-4來獲得swi指令位址,如果是在thumb狀態下進入,則只有lr-2就可以了。

下面是一段提取swi中斷號碼的例程:

mrs r0,spsr;檢查進入swi響應前的狀態

tst r0,#t_bit;

ldrneh r0,[lr, #-2];是thumb,讀回swi指令碼

bicne r0, r0, #0xff00;提取低8位

ldreq r0, [lr, #-4];是arm,讀回swi指令碼

biceq r0, #ff000000;提取低24位;

暫存器r0中的內容是正確的軟中斷編號了。

3 flash的cfi介面簡介

在程式設計時,軟體由於需要支援多個廠家不同型號的flash,因此在對flash擦寫操作時,我們採用cfi介面。

cfi(common flash inte***ce)是jedec制定的乙個介面,用來幫助程式讀取flash的製造商id和裝置id,確定flash的大小,獲得flash的各個物理特性,比如block的擦除時間等等。主要的功能是使得軟體和硬體公升級更加方便,不同廠家之間的硬體相容性更好,可以實現底層硬體的互換。專案使用的flash命令定義列表如表1所示。

表1 nor flash命令定義列表

4 實現方案

4.1 swi實現介面程式

如圖1所示,lpc2458內部的flash存放boot程式,外部的flash存放應用程式。在需要擦寫外部flash時,由應用程式產生乙個軟中斷,使程式跳到內部flash中執行。cpu不再從片外flash中取指令,因此可擦寫片外flash。當 執行完畢後,程式又跳回片外flash中。

由於swi軟中斷中傳送引數比較麻煩,我們的swi軟中斷程式僅返回處理函式的位址,獲得位址後,重定義為函式位址指標的方法簡化處理,使程式的可讀性和維護性增強。

我們以flash的寫函式舉例說明採用swi方式的流程。

//定義函式指標型別

typedef unsigned long (*funcwr_t)(unsigned long, void *, unsigned long);

//定義寫flash函式,呼叫軟中斷

unsigned long write_flash(unsigned long startaddr, unsigned short* dataptr, unsigned long count)

extern unsigned long __swi(3) get_write_addr(void);

funcwr_t func; //定義乙個函式指標

func = (funcwr_t)get_write_addr();

return func(startaddr, dataptr, count);

unsigned long __swi(3)get_write_addr(void);

unsigned long __swi_3(void) //get write flash function address

return (unsigned long)norflash_write;

norflash_write函式 如下:

unsigned long norflash_write(unsigned long startaddr, unsigned short * dataptr, unsigned long count);

4.2 cfi介面實現

unsigned long norflash_write(unsigned long startaddr, unsigned short * dataptr, unsigned long count)

write_cmd(0x5555,0xaaaa);

write_cmd(0x2aaa,0x5555);

write_cmd(0x5555,0xa0a0);

5 總結

本文以arm7核心的lpc2458 mcu,採用軟中斷的方法實現片外flash在執行程式時,同時實現對此flash的寫操作例程。詳細描述了arm7核心的mcu軟中斷程式的設計方法。希望能對使用arm7核心、cortex-m3/m4核心的mcu,實現軟中斷程式起到乙個參考的作用。

ARM7板子的驅動

uart 主要用到的暫存器有 pinsel0 pin功能連線模組 u0lcr 串列埠控制暫存器 u0lsr 串列埠狀態暫存器 u0rbr 緩衝區暫存器 u0iir 串列埠中斷暫存器 計算波特率相關的暫存器 time counter 計時器 t0tcr time control register t0...

ARM7在嵌入式應用中啟動程式的實現

摘要 本文給出了基於arm7嵌入式系統的啟動程式的實現流程,並針對儲存器控制單元的使用以及目標檔案的分布裝載等技術難點進行詳細分析。關鍵字 嵌入式系統 啟動程式 arm7 嵌入式系統被定義為 以應用為中心 以計算機技術為基礎 軟體硬體可裁剪 適應應用系統對功能 可靠性 成本 體積 功耗嚴格要求的專用...

ucOS II基於ARM920T的中斷處理過程

程式清單 ucos ii 基於arm920t 的中斷處理過程 ucos irqhandler 中斷入口位址,在中斷向量表初始化時被設定 此時已處於中斷模式 在arm處理器中,當中斷發生時,cpu自動儲存cpsr到spsr irq,並切換到中斷模式 因此sp為中斷模式下的棧指標 如上所說,arm具有中...