MAXQ8913和其他MAXQ微控制器使用的哈佛存儲器映射架構為用戶提供了根據需要將不同的物理存儲器段(如數據SRAM)映射到程序或數據存儲器空間的靈活性。在某些情況下,從數據SRAM執行部分應用可以提高性能并降低功耗。這些好處是以增加應用程序復雜性為代價的。
概述
與許多其他MAXQ微控制器一樣,MAXQ8913包括一個基于SRAM的內部數據存儲器區域,該存儲器可以映射到數據存儲器空間,也可以映射到程序存儲器空間。內部SRAM通常用作數據存儲器,大部分代碼執行發生在程序閃存或屏蔽ROM中。但是,在某些情況下,應用程序從內部SRAM執行其代碼的有限部分可能很有用。
本應用筆記解釋了如何配置和加載基于匯編的代碼,以便從內部SRAM正確執行。討論了這種執行的優缺點。本應用筆記的演示代碼為MAXQ8913編寫,采用基于匯編的MAX-IDE環境。本應用筆記中介紹的演示應用的代碼和項目文件可供下載。
本應用筆記中討論的代碼專門針對MAXQ8913微控制器,但本文所示的原理和技術同樣適用于其它基于MAXQ的微控制器,其內部SRAM可以映射到程序空間。其他能夠以這種方式執行代碼的MAXQ微控制器包括MAXQ2000、MAXQ2010和MAXQ3210/MAXQ3212。
該代碼可在任何基于MAXQ8913的硬件上正常工作,該硬件為MAXQ232的串行端口8913提供串口接口(RS-0或USB轉串口)。通過將終端仿真器連接到串行端口,可以查看演示代碼的輸出,波特率為9600波特,8個數據位,1個停止位,無奇偶校驗。
MAX-IDE環境的最新安裝包和文檔可免費下載。
最大集成開發臺安裝
MAXQ磁芯組裝指南
開發工具指南
從 RAM 執行代碼的優點
通常,MAXQ微控制器上的大多數應用代碼都設置為從主程序空間執行,這通常使用大型內部閃存或(對于屏蔽ROM器件)客戶特定的應用ROM來實現。主程序空間是非易失性的,因此在大多數情況下將應用程序代碼存儲在那里是有意義的。內部SRAM用于存儲變量、軟件堆棧和類似數據,這些數據在器件斷電時不需要保存。
但是,對于某些應用,從數據SRAM執行某些代碼具有優勢。
降低功耗
在大多數MAXQ微控制器中,從內部SRAM(或實用程序ROM)執行代碼時,電源電流會降低,而不是程序閃存。之所以能節省功耗,是因為閃存在未被訪問時可以動態關閉電源。如果應用通?;ㄙM大部分活動時間執行非常少量的代碼,則從SRAM執行該代碼可以顯著降低總體功耗。
直接內存訪問主程序空間
通常,從主程序閃存執行的代碼不能直接讀取也存儲在主程序閃存中的數據。這種類型的數據可以包括常量字符串和應用程序數據中包含的數據表。要讀取此數據,應用程序必須在實用程序ROM中調用專用數據傳輸函數。 從RAM執行代碼會繞過此限制,并允許使用標準數據指針直接讀取閃存中包含的數據。這加快了訪問速度。如果小型算法花費大量時間遍歷查找表或存儲在閃存中的其他常量數據,則從RAM執行算法可以在更短的時間內完成操作。
整個閃存可以重寫
MAXQ8913上的實用程序ROM與大多數基于閃存的MAXQ微控制器一樣,包含標準功能,允許在應用控制下擦除和重寫程序閃存。此過程允許實現用戶加載程序,這些加載程序使用用戶指定的接口(例如串行端口、SPI 或 I2C)重新加載部分或全部應用程序。但是,如果用戶加載程序代碼包含在閃存中,則無法擦除或重寫它占用的閃存部分。從RAM執行用戶加載器代碼允許擦除整個閃存程序空間并使用新代碼重寫,包括用戶加載器本身。
從 RAM 執行代碼的缺點
從 RAM 執行應用程序代碼時也存在缺點和限制。有些缺點是可以解決的,而另一些則是MAXQ架構固有的。
有限的代碼空間
RAM 通常比程序閃存小得多,這意味著在任何給定時間只能從 RAM 執行少量代碼。但是,可以從 RAM 運行一個例程,擦除它并加載第二個例程,運行第二個例程,依此類推。
代碼必須鏡像
在從 RAM 執行代碼之前,必須將其復制到 RAM。此過程需要時間和代碼空間來實現。此外,代碼必須從某個地方復制,因此代碼實際上存儲兩次:一次在閃存或程序ROM中,一次在RAM中。即使代碼不打算從閃存執行,它仍然必須存儲在那里,從而消耗額外的空間。
無法直接訪問內存
從內部 RAM 執行代碼時,RAM 在數據存儲器空間中不再可見。這意味著數據指針不能用于直接讀取或寫入 RAM 位置??梢酝ㄟ^與從閃存運行的應用程序代碼相同的方式解決此限制。使用實用程序ROM數據傳輸功能(UROM_moveDP0和類似功能)從RAM讀取,并通過在閃存中寫入類似的功能,對RAM執行間接寫入。但是,此解決方法需要額外的時間和應用程序空間。
組裝要從 RAM 執行的代碼
在編寫將從數據RAM執行的應用程序代碼時,必須了解一個主要因素。每個代碼字將在一個地址組裝并加載到該地址的閃存中,但它將在不同地址的RAM中執行。例如,如果一段應用程序代碼從程序字地址 0100h 開始加載到閃存中,并從數據字地址 0100h 開始復制到 RAM,則無法跳轉到地址 0100h 以在 RAM 中執行代碼。地址 0100h 仍然是閃存中代碼的地址。程序空間中RAM中的代碼地址是其數據存儲器地址加上A000h的偏移量,如下圖1所示。
圖1.從RAM執行代碼時MAXQ8913的存儲器映射。
要執行復制到數據存儲器地址 0100h 的 RAM 的應用程序代碼,必須跳轉到程序地址 A100h。
從RAM執行代碼會給MAX-IDE匯編程序帶來困難。MAX-IDE根本不知道您將在與組裝代碼不同的地址執行代碼。例如,假設您有一個名為 subOne 的例程,它從閃存地址 0080h 開始,另一個例程位于 0300h 處,它調用第一個例程。此代碼如下所示。
org 0080h subOne: ....perform various calculations... ret ... org 0300h subTwo: call subOne ...and so on...
如果將這兩個例程都復制到 RAM 中并在那里執行,會發生什么?假設例程被復制到RAM中與它們在閃存中占用的程序存儲器地址相同的數據存儲器地址,則subOne將位于程序地址A080h,subTwo將位于A300h。
由于行“call subOne”和目標標簽subOne之間的距離大于相對跳轉距離(+127/-128字),因此必須將指令組裝為絕對LCALL。但是,匯編程序對 subOne 的唯一地址是 0080h,因此指令將被組裝為“LCALL 0080h”。當 subTwo 執行時,它不會調用位于 RAM 中的 subOne 的副本,而是調用位于閃存中的版本。
這種困境有兩種可能的解決方法。第一種也是最簡單的方法是強制匯編程序始終使用相對跳轉和調用,并在 RAM 中保持例程足夠接近,以便它們可以以這種方式相互調用。不要使用 JUMP 和 CALL 操作碼(允許匯編程序選擇短跳或長跳),而是始終使用 SJUMP 和 SCALL。這將強制使用指令的相對跳轉版本。
但是,這種方法有一個警告。如果從 RAM 運行的代碼量超過 128 個字,則相對跳轉可能不足以讓 RAM 中的一個例程調用另一個例程。在這種情況下,解決方案是使用 ORG 語句修復各種例程的地址,然后在 RAM 中定義包含其更正地址的等值。這些等價可用于LCALL和LJUMP語句,如下所示。
subOne equ 0A080h org 0080h ; subOne ....perform various calculations... ret ... org 0300h subTwo: lcall #subOne ...and so on...
此過程強制匯編程序使用 LCALL 的正確地址。
將代碼復制到內存
在從 RAM 執行代碼之前,必須先將其復制到 RAM 中。將大量代碼從閃存復制到RAM的最簡單方法是使用實用程序ROM copyBuffer功能。此函數將兩個數據指針(DP[0] 和 BP[Offs])和一個長度值 (LC[0]) 作為輸入。它將指定的字節/字數從源 DP[0] 復制到目標 BP[Offs];它一次最多可以復制 256 個字節/字。
我們的演示應用程序會將自身的前 512 個單詞從閃存復制到 RAM,然后跳轉到 RAM 中的副本以開始執行代碼。源指針 (DP[0]) 指向實用程序 ROM 內存映射中程序閃存的位置,該位置從 8000h 開始。請注意,為了避免無限循環,我們跳轉到 RAM 中 RAM 復制代碼后面的副本部分。
org 0020h copyToRAM: move DPC, #1Ch ; Ensure all pointers are operating in word mode. move DP[0], #8000h ; Start of program flash from UROM's perspective. move BP, #0 ; Start of data memory. move Offs, #0 move LC[0], #256 ; The Offs register limits us to a 256-word copy. lcall UROM_copyBuffer move DP[0], #8100h ; Copy second half. move BP, #0100h move Offs, #0 move LC[0], #256 lcall UROM_copyBuffer ljump #0A040h ; Begin execution of code from RAM. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Executing from RAM ;; org 0040h move LC[0], #1000 delayLoop: move LC[1], #8000 sdjnz LC[1], $ sdjnz LC[0], delayLoop ;; Initialize serial port. move SCON.6, #1 ; Set to mode 1 (10-bit asynchronous). move SMD.1, #1 ; Baud rate = 16 x baud clock move PR, #009D4h ; P = 2^21 * 9600/8.000MHz move SCON.1, #0 ; Clear transmit character flag.
數據傳輸操作
如上所述,從 RAM 執行代碼時,內存映射的兩件事會發生變化。首先,程序閃存現在映射到數據存儲器中。這意味著我們可以使用任何數據指針直接從程序閃存中讀取數據,如下所示。
;; Read the banner string from flash and output it over the serial port. Since ;; we are running from RAM, we can read from the flash directly without having ;; to use the Utility ROM data transfer functions (moveDP0inc, etc...). move SC.4, #0 move DPC, #0 ; Set pointers to byte mode. move DP[0], #(stringData * 2) ; Point to byte address of string data. stringLoop: move Acc, @DP[0]++ sjump Z, stringEnd lcall #TxChar sjump stringLoop stringEnd: move DPC, #1Ch ; Set pointers to word mode. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; This portion of the code (addresses 200h and higher) will remain in flash. org 0200h stringData: db 0Dh, 0Ah, "Executing code from RAM....", 00h
請注意,如圖1所示,SC.4(CDA0)位會影響程序閃存的哪一半(上頁或下頁)以字節模式映射到數據存儲器。當使用字模式指針時,整個程序閃存立即映射到數據存儲器中。
其次,雖然閃存現在可以在數據空間中訪問,但SRAM不再可以直接訪問。這意味著要從 SRAM 位置讀取或寫入 SRAM 位置,應用程序必須間接執行此操作。從SRAM位置讀取的方式與閃存中運行的代碼從閃存位置讀取的方式相同 - 它使用實用程序ROM數據傳輸功能(moveDP0inc等)。但是,由于實用程序ROM中沒有類似的函數來執行間接寫入,因此應用程序必須包含一個保留在閃存中的小函數,該函數可由RAM駐留代碼調用以執行寫入。
下面的代碼演示了用于讀取和寫入 RAM 變量 varA 的兩種方法,其初始內容與位于地址范圍 0000h-01FFh 中的其余應用程序代碼一起從閃存復制到 RAM。
scall printVar scall incrVar scall printVar scall incrVar scall printVar scall incrVar move Acc, #0Dh lcall #TxChar move Acc, #0Ah lcall #TxChar sjump $ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Variables stored in RAM (program) space. They can be read using the ;; Utility ROM data transfer functions (such as UROM_moveDP0) and written ;; using the writeDP0 function which remains in flash. ;; varA: dw 'A' ;============================================================================== ;= ;= printVar ;= ;= Reads the varA RAM variable value and sends it over the serial port. ;= printVar: move DPC, #1Ch ; Word mode move DP[0], #varA ; Variable's location in UROM data space lcall UROM_moveDP0 ; Moves variable value into GR. move Acc, GR lcall #TxChar ret ;============================================================================== ;= ;= incrVar ;= ;= Reads the varA RAM variable value, adds 1 to it, and stores it back in RAM. ;= incrVar: move DPC, #1Ch ; Word mode move DP[0], #varA ; Variable's location in UROM data space lcall UROM_moveDP0 ; Moves variable value into GR. move Acc, GR add #1 move GR, Acc lcall writeDP0 ret ;============================================================================== ;= ;= TxChar ;= ;= Outputs a character to the serial port. ;= ;= Inputs : Acc.L - Character to send. ;= org 01F0h move SBUF, Acc ; Send character. TxChar_Loop: move C, SCON.1 ; Check transmit flag. sjump NC, TxChar_Loop ; Stall until last transmit has completed. move SCON.1, #0 ; Clear the transmit flag. ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; This portion of the code (addresses 200h and higher) will remain in flash. org 0200h stringData: db 0Dh, 0Ah, "Executing code from RAM....", 00h ;============================================================================== ;= ;= WriteRAM ;= ;= This is a routine that can be called by code running in the RAM to load ;= a new value into a byte or word location in the RAM. ;= ;= Inputs : DP[0] - Location to write (absolute starting at 0000h) in RAM. ;= GR - Value to write to the RAM location. ;= ;= Notes : DP[0] must be configured to operate in word or byte mode as ;= desired before calling this function. Following a call to this ;= function, DP[0] must be refreshed before it is used to read data. ;= writeDP0: move @DP[0], GR ret
執行時,演示代碼通過串行端口輸出以下文本(圖2)。
圖2.通過演示代碼通過串行端口輸出文本。
結論
MAXQ8913和其他MAXQ微控制器使用的哈佛存儲器映射架構允許您將不同的物理存儲器段(如數據SRAM)映射到程序或數據存儲器空間。從數據SRAM執行部分應用可以提高性能并降低功耗。該過程確實需要額外的應用程序復雜性。
審核編輯:郭婷
-
微控制器
+關注
關注
48文章
7552瀏覽量
151426 -
存儲器
+關注
關注
38文章
7492瀏覽量
163842 -
usb
+關注
關注
60文章
7945瀏覽量
264682
發布評論請先 登錄
相關推薦
評論