0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

在MAXQ2000數(shù)據(jù)存儲(chǔ)器中實(shí)現(xiàn)軟堆棧

星星科技指導(dǎo)員 ? 來源:ADI ? 作者:ADI ? 2023-02-14 18:20 ? 次閱讀

MAXQ2000微控制器MaximRISC微控制器系列MAXQ器件一樣,都是基于MAXQ20內(nèi)核?;贛AXQ20的微控制器通??蓪?shí)現(xiàn)一個(gè)16位寬硬堆棧,其深度固定不變(MAXQ2000為16),存儲(chǔ)在與數(shù)據(jù)和程序空間分開的專用內(nèi)部存儲(chǔ)器中。通過子程序調(diào)用和中斷,這一硬堆??捎糜诒4婧突謴?fù)微控制器的操作狀態(tài)。

雖然非常適合緊湊型應(yīng)用,但是在規(guī)模較大的匯編應(yīng)用中,使用深度嵌套的子程序(或者使用了在堆棧中保存和恢復(fù)多個(gè)工作寄存器的子程序),硬堆棧會(huì)很快耗盡空間。利用數(shù)據(jù)存儲(chǔ)器中的“軟堆棧”,以C編程語言(使用IAR的Embedded Workbench?等編譯器)或者Rowley Associates的Crossworks for MAXQ編寫應(yīng)用程序可避免這一問題。這一軟堆棧存儲(chǔ)子程序的調(diào)用/返回地址以及本地工作變量。然而,MAXQ20內(nèi)核沒有內(nèi)置機(jī)制來定位數(shù)據(jù)存儲(chǔ)器中的堆棧,這些數(shù)據(jù)存儲(chǔ)器只用在匯編應(yīng)用中。

本應(yīng)用筆記介紹了匯編應(yīng)用中在數(shù)據(jù)存儲(chǔ)器中實(shí)現(xiàn)軟堆棧的簡(jiǎn)單方法。應(yīng)用筆記中的代碼可以用于MAXQ2000和其他基于MAXQ20的微控制器。采用了MAX-IDE的宏預(yù)處理特性,在Maxim的MAXQ系列工程應(yīng)用開發(fā)和調(diào)試環(huán)境中編寫了實(shí)例代碼。

可以免費(fèi)下載MAX-IDE環(huán)境最新的安裝包和文檔:

MAX-IDE安裝(ZIP)

MAXQ內(nèi)核匯編指南(PDF)

開發(fā)工具指南(PDF)

MAXQ20內(nèi)核中的硬堆棧工作

MAXQ20內(nèi)核使用了兩種不同類型的堆棧工作模式:

PUSH工作(它包括操作代碼PUSH、LCALL和SCALL)被用于在堆棧中存儲(chǔ)數(shù)據(jù)。這些操作將堆棧指針SP預(yù)增1,然后,把數(shù)據(jù)存儲(chǔ)在SP指針(@SP)指向的堆棧位置。

POP工作(它包括操作代碼POP、POPI、RET和RETI)被用于從堆棧中恢復(fù)數(shù)據(jù)。這些操作從SP指向的堆棧位置恢復(fù)數(shù)據(jù),然后,將堆棧指針減1。

硬堆棧的一項(xiàng)主要功能是在調(diào)用子程序時(shí)保存并恢復(fù)地址,因此,堆棧含有16位(字)位置。這一位寬支持在一次push或者pop操作中保存或者恢復(fù)16位指令指針(IP)寄存器。盡管可以使用PUSH或者POP在堆棧中保存或者恢復(fù)8位寄存器(例如,AP),但每一堆棧操作總是使用整個(gè)16位字。

除了利用堆棧的各種操作代碼之外,還有兩種其他的情況,在這些情況下,微控制器自動(dòng)使用硬堆棧:

當(dāng)處理中斷時(shí),開始執(zhí)行中斷服務(wù)程序(中斷矢量寄存器IV所指)之前,當(dāng)前程序執(zhí)行點(diǎn)被推入堆棧。

當(dāng)調(diào)用某些調(diào)試命令(例如,讀寄存器和寫數(shù)據(jù)存儲(chǔ)器)時(shí),需要執(zhí)行完程序ROM中的代碼,在控制被傳送給程序ROM之前,當(dāng)前的執(zhí)行點(diǎn)被推入堆棧。一旦執(zhí)行完程序ROM中的調(diào)試程序,執(zhí)行點(diǎn)從堆棧中彈出,恢復(fù)處理器以前的狀態(tài)。

找到中斷服務(wù)程序或者執(zhí)行調(diào)試器命令總是需要使用硬堆棧。由于這一行為嵌入在硬件中,因此,無法避開這一問題。然而,對(duì)于更常用的PUSH/POP和CALL/RET指令對(duì),可以采用軟堆棧。

注意,當(dāng)以下任一堆棧錯(cuò)誤狀態(tài)出現(xiàn)時(shí),MAXQ2000 (和其他的基于MAXQ20內(nèi)核的器件一樣)并不支持任何錯(cuò)誤探測(cè)或者報(bào)警:

堆棧上溢:將數(shù)值推入已經(jīng)滿的堆棧時(shí)發(fā)生。這一錯(cuò)誤導(dǎo)致堆棧中最早的數(shù)值被覆寫。

堆棧下溢:從空堆棧中彈出數(shù)值時(shí)發(fā)生。這一錯(cuò)誤導(dǎo)致返回?zé)o效數(shù)據(jù)值。例如,如果堆??諘r(shí)執(zhí)行RET,執(zhí)行后將返回一個(gè)不正確的(有可能是隨機(jī)的)地址。

在數(shù)據(jù)存儲(chǔ)器中建立一個(gè)軟堆棧

在數(shù)據(jù)存儲(chǔ)器中建立一個(gè)軟堆棧的第一步是定義要使用數(shù)據(jù)存儲(chǔ)器的哪一部分。然后,必須定義跟蹤堆棧頂當(dāng)前位置的數(shù)據(jù)存儲(chǔ)器指針(DP[0]、DP[1]或者BP[Offs])。注意:應(yīng)用軟件不會(huì)出于其他目的使用堆棧專用數(shù)據(jù)存儲(chǔ)器(例如,變量或者緩沖)。

定義并初始化這類軟堆棧的一種簡(jiǎn)單方法涉及到BP[Offs]寄存器對(duì)和一個(gè)公式。

SS_BASE  equ  0100h

ss_init:
   move    DPC,  #1Ch        ; Set all pointers to word mode   
   move    BP,   #SS_BASE    ; Set base pointer to stack base location
   move    Offs, #0          ; Set stack to start
   ret

如果基指針(BP)寄存器被設(shè)置在SS_BASE位置,那么,可以采用Offs寄存器指向堆棧的當(dāng)前頂部。由于Offs寄存器只有8位寬,硬件會(huì)自動(dòng)把堆棧限制在數(shù)據(jù)存儲(chǔ)器的范圍內(nèi)(BP .. (BP+255))。如果當(dāng)Offs等于255 (上溢)時(shí)出現(xiàn)推入,或者Offs等于0 (下溢)時(shí)出現(xiàn)彈出,那么,Offs寄存器只會(huì)限制在堆棧的另一端。這一行為模仿硬堆棧工作方式,支持簡(jiǎn)單的軟堆棧實(shí)現(xiàn);它不探測(cè)下溢和上溢狀態(tài)。

在使用軟堆棧前,主程序必須調(diào)用ss_init例程。它將BP[Offs]指針設(shè)置為字模式,由于軟堆棧以16位寬堆棧實(shí)現(xiàn),因此,必須完成這一步。它還將BP[Offs]寄存器對(duì)指向堆棧開始。

軟堆棧工作

不能重新定義使用堆棧的內(nèi)置操作代碼(PUSH、POP、CALL、RET等)以使用軟堆棧,這是因?yàn)檫@些代碼意味著MAXQ匯編器的硬線連接。而且,還有可能需要在應(yīng)用程序中的某些部分使用標(biāo)準(zhǔn)硬堆棧,例如,中斷服務(wù)例程等。出于這些原因,由復(fù)制標(biāo)準(zhǔn)操作代碼的宏來訪問軟堆棧。

mpush  MACRO  Reg
   move    @BP[++Offs], Reg  ; Push value to soft stack
endm

mpop   MACRO  Reg
   move    Reg, @BP[Offs--]  ; Pop value from soft stack
endm

mcall  MACRO  Addr
LOCAL  return
   move    @BP[++Offs], #return   ; Push return destination to soft stack
   jump    Addr
return:
endm

mret   MACRO
   jump    @BP[Offs--]       ; Jump to popped destination from soft stack
endm

下面將討論這些宏是怎樣工作的。

mpush

該宏的使用方式和PUSH操作代碼相同。它支持將8位或者16位寄存器,或者將立即值推入堆棧。

 mpush   A[0]              ; Save the value of the A[0] register
   mpush   A[1]              ; Save A[1]
   mpush   A[2]              ; Save A[2]

   ...                       ; code which destroys A[0]-A[2]

   mpop    A[2]              ; Restore the value of A[2] (pop in reverse order)
   mpop    A[1]              ; Restore A[1]
   mpop    A[0]              ; Restore A[0]

mpop

該宏的使用方式和POP操作代碼相同。它支持從堆棧中裝入8位或者16位寄存器,如上所示。注意,如果推入了一個(gè)16位值,該值彈入到一個(gè)8位寄存器中,那么,只有低位字節(jié)被存儲(chǔ)在寄存器中。高位字節(jié)丟失。這與內(nèi)置硬堆棧的方式一致。

subroutine:
   mpush   A[0]              ; Save the current value of A[0]
   
   ...                       ; Code which destroys A[0]

   mpop    A[1]              ; Restore A[0]
   mret

mcall
mret

mcall宏的使用方式和CALL操作代碼執(zhí)行子程序相同。一旦執(zhí)行完成,子程序必須使用mret宏(而不是標(biāo)準(zhǔn)RET操作代碼)才能返回。

 mcall   mySub

   ...

mySub:
   mpush   A[0]              ; Save A[0]
   mpush   A[1]              ; Save A[1]
   ...                       ; Perform calculations, etc.
   mpop    A[1]
   mpop    A[0]
   mret

擴(kuò)展軟堆棧的大小

某些應(yīng)用程序需要大于256級(jí)的軟堆棧。使用其他數(shù)據(jù)指針(DP[0]或者DP[1])之一可以實(shí)現(xiàn)任意大小的堆棧(最大達(dá)到數(shù)據(jù)存儲(chǔ)器的上限)。

SS_BASE  equ  0000h
SS_TOP   equ  01FFh

ss_init:
   move    DPC,   #1Ch       ; Set all data pointers to word mode
   move    DP[0], #SS_BASE   ; Set pointer to stack base location
   ret

上面的代碼存儲(chǔ)在數(shù)據(jù)存儲(chǔ)器的0000h至01FFh,因此,產(chǎn)生的堆??梢员3?11級(jí)。(沒有使用堆棧存儲(chǔ)器空間中的某一位置;這樣可以更有效,以更短的代碼實(shí)現(xiàn)

只改變數(shù)據(jù)指針,而代碼中的其他部分保持不變可以擴(kuò)展堆棧。雖然如此,由于DP[0]并沒有限制在數(shù)據(jù)存儲(chǔ)器的一定范圍內(nèi),因此,沒有措施來防止推入或者彈出操作使DP[0]增加或者減小導(dǎo)致超出所指定的軟堆棧邊界。為避免這一點(diǎn),可以加入簡(jiǎn)單的下溢/上溢檢查。

加入下溢和上溢檢查

為保持宏(每次使用時(shí)擴(kuò)展為代碼)盡量短,在子程序中完成下溢和上溢檢查,使用硬堆棧,由宏調(diào)用子程序。

mpush  MACRO  Reg
   call    ss_check_over     ; Check for possible overflow
   move    @++DP[0], Reg     ; Push value to soft stack
endm

mpop   MACRO  Reg
   call    ss_check_under    ; Check for possible underflow
   move    Reg, @DP[0]--     ; Pop value from soft stack
endm

mcall  MACRO  Addr
LOCAL  return
   call    ss_check_over     ; Check for possible overflow
   move    @++DP[0], #return ; Push return destination to soft stack
   jump    Addr
return:
endm

mret   MACRO
   call    ss_check_under    ; Check for possible underflow
   jump    @DP[0]--          ; Jump to popped destination from soft stack
endm

ss_check_under:
   push    A[0]
   push    AP
   push    APC
   push    PSF   

   move    APC, #80h         ; Set Acc to A[0], standard mode, no auto inc/dec
   move    Acc, DP[0]        ; Get current value of stack pointer
   cmp     #SS_BASE
   jump    NE, ss_check_under_ok
   nop                       ; < Error handler should be implemented here >
ss_check_under_ok:
   pop     PSF
   pop     APC
   pop     AP
   pop     A[0]
   ret

ss_check_over:
   push    A[0]
   push    AP
   push    APC
   push    PSF   

   move    APC, #80h         ; Set Acc to A[0], standard mode, no auto inc/dec
   move    Acc, DP[0]        ; Get current value of stack pointer
   cmp     #SS_TOP
   jump    NE, ss_check_over_ok
   nop                       ; < Error handler should be implemented here >
ss_check_over_ok:
   pop     PSF
   pop     APC
   pop     AP
   pop     A[0]
   ret

上面的代碼導(dǎo)致在推入或者彈出(或者call,或者ret)操作之前檢查當(dāng)前的堆棧位置。如果探測(cè)到下溢或者上溢錯(cuò)誤,不同的應(yīng)用程序有不同的響應(yīng)。一般情況下,這類錯(cuò)誤只會(huì)出現(xiàn)在應(yīng)用程序開發(fā)階段;如果代碼編寫正確,不會(huì)出現(xiàn)這類錯(cuò)誤。如果的確出現(xiàn)了錯(cuò)誤,一般將其考慮為重大錯(cuò)誤,就像使用硬堆棧時(shí)出現(xiàn)下溢/上溢錯(cuò)誤。對(duì)這類錯(cuò)誤可能的響應(yīng)包括暫停,發(fā)送錯(cuò)誤消息,或者閃爍LED。在開發(fā)階段,一個(gè)好的方法是兩個(gè)程序中的每一個(gè)都在MAX-IDE中設(shè)置斷點(diǎn)(例如,在“Error handler should be implemented here”行中),如果出現(xiàn)下溢或者上溢,立即發(fā)出反饋。

但是,應(yīng)用程序有時(shí)候也可以從堆棧下溢或者上溢中恢復(fù)(例如,重新裝入和從頭重新啟動(dòng)應(yīng)用程序子任務(wù))。在這種情況下,需要簡(jiǎn)單地設(shè)置一個(gè)標(biāo)志,指示出現(xiàn)了堆棧錯(cuò)誤??蛇x的這類標(biāo)志包括位于PSF寄存器中的兩個(gè)通用標(biāo)志(GPF0和GPF1)。由于有兩個(gè)位標(biāo)志,因此,其中一個(gè)可以用于指示上溢,另一個(gè)用于指示下溢。

結(jié)論

MAX-IDE強(qiáng)大的宏預(yù)處理功能實(shí)現(xiàn)了MAXQ2000以及其他MAXQ20微控制器數(shù)據(jù)存儲(chǔ)器軟堆棧的直接替換。這一軟堆棧使子程序更加模塊化,可重復(fù)使用,有助于大規(guī)模匯編應(yīng)用程序的開發(fā)。堆棧還支持堆棧錯(cuò)誤的探測(cè)。

審核編輯:郭婷

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 微控制器
    +關(guān)注

    關(guān)注

    48

    文章

    7454

    瀏覽量

    150850
  • 存儲(chǔ)器
    +關(guān)注

    關(guān)注

    38

    文章

    7430

    瀏覽量

    163514
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    MAXQ2000 SPI模塊與MAX6951/MAX6950怎么配合使用?

    本應(yīng)用筆記提供了MAXQ?匯編程序范例,說明MAXQ2000 SPI模塊與MAX6951/MAX6950的配合使用。
    發(fā)表于 05-31 06:08

    MAXQ2000微控制與MAX4397是如何連接的?

    MAX4397是什么?MAXQ2000微控制與MAX4397是如何連接的?
    發(fā)表于 06-04 06:15

    MAXQ2000文資料pdf

    MAXQ2000微控制是低功耗16位器件,包含液晶顯示(LCD)接口,可以驅(qū)動(dòng)最多100 (-RBX/-RBX+)段或132 (-RAX/-RAX+/-RFX/-RFX+)段。MAXQ2000適用于血糖監(jiān)測(cè)系統(tǒng),也適用于其他需
    發(fā)表于 06-30 11:29 ?97次下載

    利用MAXQ2000微控制實(shí)現(xiàn)快速傅里葉變換

    利用MAXQ2000微控制實(shí)現(xiàn)快速傅里葉變換
    發(fā)表于 12-13 17:24 ?19次下載
    利用<b class='flag-5'>MAXQ2000</b>微控制<b class='flag-5'>器</b><b class='flag-5'>實(shí)現(xiàn)</b>快速傅里葉變換

    采用MAXQ2000進(jìn)行音頻濾波

    集成了乘累加單元(MAC)和單周期內(nèi)核的MAXQ2000非常適合用作通用微控制MAXQ2000所具有的性能和I/O外設(shè)適合多種應(yīng)用:如鬧鐘、手持醫(yī)療設(shè)備、數(shù)字讀取等需要低功耗、高
    發(fā)表于 12-25 23:24 ?34次下載

    用uIP堆棧實(shí)現(xiàn)MAXQ微控制聯(lián)網(wǎng)-MAXQ2000的應(yīng)用

    用uIP堆棧實(shí)現(xiàn)MAXQ微控制聯(lián)網(wǎng) 摘要:本應(yīng)用筆記描述了如何用uIP TCP/IP網(wǎng)絡(luò)協(xié)議棧實(shí)現(xiàn)M
    發(fā)表于 08-04 09:47 ?492次閱讀
    用uIP<b class='flag-5'>堆棧</b><b class='flag-5'>實(shí)現(xiàn)</b><b class='flag-5'>MAXQ</b>微控制<b class='flag-5'>器</b>聯(lián)網(wǎng)-<b class='flag-5'>MAXQ2000</b>的應(yīng)用

    MAXQ2000數(shù)據(jù)存儲(chǔ)器實(shí)現(xiàn)堆棧

    摘要:本應(yīng)用筆記介紹了匯編應(yīng)用數(shù)據(jù)存儲(chǔ)器內(nèi)實(shí)現(xiàn)堆棧的簡(jiǎn)單方法。該方法使用了
    發(fā)表于 04-23 16:04 ?953次閱讀

    利用MAXQ2000設(shè)計(jì)電壓表

    摘要:本應(yīng)用筆記演示了如何配置MAXQ2000微控制實(shí)現(xiàn)簡(jiǎn)單的電壓表設(shè)計(jì)。該應(yīng)用采用MAXQ2000評(píng)估板,其中包括4½位段式LCD顯示
    發(fā)表于 04-23 16:07 ?818次閱讀
    利用<b class='flag-5'>MAXQ2000</b>設(shè)計(jì)電壓表

    利用SD存儲(chǔ)介質(zhì)擴(kuò)展MAXQ2000的非易失性數(shù)據(jù)存儲(chǔ)空間

    摘要:本文討論如何使用安全數(shù)字(SD)媒體格式擴(kuò)展MAXQ2000的非易失數(shù)據(jù)存儲(chǔ)器。 低功耗、低噪聲的MAXQ2000微控制適合于多種應(yīng)
    發(fā)表于 04-23 16:25 ?1184次閱讀
    利用SD<b class='flag-5'>存儲(chǔ)</b>介質(zhì)擴(kuò)展<b class='flag-5'>MAXQ2000</b>的非易失性<b class='flag-5'>數(shù)據(jù)</b><b class='flag-5'>存儲(chǔ)</b>空間

    采用MAXQ2000進(jìn)行音頻濾波

    摘要:集成了乘累加單元(MAC)和單周期內(nèi)核的MAXQ2000非常適合用作通用微控制(µC) 。MAXQ2000所具有的性能和I/O外設(shè)適合多種應(yīng)用:如鬧鐘、手持醫(yī)療設(shè)備、數(shù)字讀取
    發(fā)表于 04-23 17:27 ?1043次閱讀
    采用<b class='flag-5'>MAXQ2000</b>進(jìn)行音頻濾波

    采用MAXQ2000微控制和MAX6970 LED驅(qū)動(dòng)

    采用MAXQ2000微控制和MAX6970 LED驅(qū)動(dòng)顯示不同的LED排序 Abstract: This note shows an application circuit
    發(fā)表于 07-25 21:07 ?854次閱讀

    利用SD存儲(chǔ)介質(zhì)擴(kuò)展MAXQ2000數(shù)據(jù)存儲(chǔ)空間

    本文討論如何使用安全數(shù)字(SD)媒體格式打“展MAXQ2000的非易失數(shù)據(jù)存儲(chǔ)器。
    發(fā)表于 04-08 09:59 ?4次下載

    MAXQ2000數(shù)據(jù)存儲(chǔ)器實(shí)現(xiàn)堆棧

    本應(yīng)用筆記演示了一種在數(shù)據(jù)存儲(chǔ)器實(shí)現(xiàn)堆棧的簡(jiǎn)單方法,用于基于匯編的應(yīng)用。該方法使用
    的頭像 發(fā)表于 01-11 11:20 ?682次閱讀

    使用鍵盤和LCD顯示屏與MAXQ2000

    MAXQ2000通過專用的LCD控制外設(shè)輕松直接地與LCD顯示接口。使用MAXQ2000提供的靈活端口引腳配置,可以直接讀取多路復(fù)用鍵盤。中斷驅(qū)動(dòng)的狀態(tài)機(jī)允許
    的頭像 發(fā)表于 02-21 12:01 ?750次閱讀
    使用鍵盤和LCD顯示屏與<b class='flag-5'>MAXQ2000</b>

    使用MAXQ2000進(jìn)行音頻濾波

    乘法累加單元(MAC)和單周期內(nèi)核的組合使MAXQ2000成為多功能微控制(μC)。MAXQ2000具有性能和I/O外設(shè),非常適合許多應(yīng)用:鬧鐘、手持醫(yī)療設(shè)備、數(shù)字讀數(shù)——任何需要低功耗、高性能和大量I/O的應(yīng)用。通過集成MA
    的頭像 發(fā)表于 03-02 14:13 ?875次閱讀
    使用<b class='flag-5'>MAXQ2000</b>進(jìn)行音頻濾波