ARM經典300問

第1 章 體系結構 

第1 問:


Q:請問在初始化CPU 堆棧的時候一開始在執行mov r0, LR 這句指令時處理器是什麼模式


A:復位後的模式,即管理模式.


第2 問:


Q:請教:MOV 中的8 位圖立即數,是怎麼一回事 0xF0000001 是怎麼來的


A:是循環右移,就是一個0—255 之間的數左移或右移偶數位的來的,也就是這個數除以4


一直除, 直到在0-255 的範圍內它是整數就說明是可以的!


A:8 位數(0-255)循環左移或循環右移偶數位得到的,F0000001 既是0x1F 循環右移4 位,


符合規範,所以是正確的.這樣做是因爲指令長度的限制,不可能把32 位立即數放在


32 位的指令中.移位偶數也是這個原因.可以看一看ARM 體系結構(ADS 自帶的英文文


檔)的相關部分.


第3 問:


Q:請教:《ARM 微控制器基礎與實戰》2.2.1 節關於第2 個操作數的描述中有這麼一段:


#inmed_8r 常數表達式.該常數必須對應8 位位圖,即常熟是由一個8 位的常數循環移


位偶數位得到.


合法常量:0x3FC,0,0xF0000000,200,0xF0000001.


非法常量:0x1FE,511,0xFFFF,0x1010,0xF0000010.


常數表達式應用舉例:


...


...


LDR R0,[R1],#-4 ;讀取 R1 地址上的存儲器單元內容,且 R1 = R1-4


針對這一段,我的疑問:


1. 即常數是由一個8 位的常數循環移位偶數位得到,這句話如何理解


2. 該常數必須對應8 位位圖,既然是8 位位圖,那麼取值爲0-255,怎麼0x3FC 這種超


出255 的數是合法常量呢


3. 所舉例子中,合法常量和非法常量是怎麼區分的 如0x3FC 合法,而0x1FE 卻非法


0xF0000000,0xF0000001 都合法,而0xF0000010 又變成了非法


4. 對於彙編語句 LDR R0,[R1],#-4,是先將R1 的值減4 結果存入R1,然後讀取R1 所


指單元的 值到R0,還是先讀取R1 到R0,然後再將R1 減4 結果存入R1


A:提示,任何常數都可用底數*2 的n 次冪 來表示.


1. ARM 結構中,只有8bits 用來表示底數,因此底數必須是8 位位圖.


2. 8 位位圖循環之後得到常數,並非只能是8 位.


3. 0xF0000010 底數是9 位,不能表示.


4. LDR R0, [R1], #-4 是後索引,即先讀,再減.


可以看一看ARM 體系結構對相關尋址方式的說明.


3


第4 問:


Q:在程序移植的過程中,什麼代碼段處於什麼樣的模式,這可真是一個困擾人的大難題,


有沒有一種標誌或辦法能夠識別"代碼段處於什麼樣的模式"


A:讀取 CPSR ,任何時候都是可以讀.


第5 問:


Q:爲什麼保護現場時,總是保護 R0-R3,R12,爲什麼不保護R4-R11


A:請看一看"ARM-thumb 過程調用標準"這個文檔.


第6 問:


Q:請問 mov R1,#0x00003DD0 錯誤ARM經典300問(轉貼) - Emily - Emilyut of the range of operation 是怎麼回事情


我就是想IODIR=0x00003dd0,彙編就是


LDR R0,=IODIR


MOV R1,#0x00003dd0


STR R1,[R0]


編譯時候說是超出操作範圍


A:使用ldr,mov 的操作數爲8 位位圖數.


第7 問:


Q:"在ARM7TDMI(-S)處理器內部有37 個用戶可見的寄存器:"


問題:"用戶可見"應該怎樣理解 這37 個寄存器是否是37 個不同的物理寄存器,


例如R8 與R8_fiq 應該是兩個不同的物理寄存器吧


A:用戶可見是指用戶可以通過程序操作的.R8 與R8_fiq 是兩個不同的寄存器.


第8 問:


Q:USR 模式,SVC 模式,IRQ 模式分別有哪些限制


A:對於外設操作限制與芯片設計有關.USR 模式不能設置CPSR 寄存器.


用戶模式下無SPSR 寄存器,代碼可以爲ARM,Thumb.


第9 問:


Q:請問"在初始化堆棧時就決定了工作模式"是什麼意思 如何決定工作模式的


A:設置CPSR 寄存器.


第10 問:


Q:請問:ARM 彙編程序設計中所謂的"文字池"作何理解


A:可以理解爲常量數組,文字池中保存的是常量,這些常量可以是正常的常量,也可以是


地址.


4


第11 問:


Q:爲什麼在中斷向量表中不直接LDR PC,"異常地址".而是使用一個標號,然有再在後面


使用DCD 定義這個標號


A:因爲LDR 指令只能跳到當前PC 4kB 範圍內,而B 指令能跳轉到32MB 範圍,而現在這樣


在LDR PC, "xxxx"這條指令不遠處用"xxxx"DCD 定義一個字,而這個字裏面存放最終異


常服務程序的地址,這樣可以實現4GB 全範圍跳轉.


QARM經典300問(轉貼) - Emily - EmilyDR 不是可以全空間跳轉的嗎 《ARM 微控制器基礎與實戰》程序清單5.3.


AARM經典300問(轉貼) - Emily - EmilyDR 僞指令通過設置指令緩衝池才能實現全範圍跳轉,而LDR 指令則只能實現4KB 範圍


跳轉.


第12 問:


Q:ARM7TDMI-S 和ARM7TDMI 有何區別


A:ARM7TDMI-S 是ARM7TDMI 的可綜合(synthesizable)版本(軟核).


對應用工程師來說,除非芯片生產廠商對ARM7TDMI-S 進行了裁減,


否則ARM7TDMI-S 與ARM7TDMI 沒有太大的區別,其編程模型與ARM7TDMI 一致.


第13 問:


QARM經典300問(轉貼) - Emily - EmilyCD 僞指令的疑惑.


"StackUsr DCD UsrStackSpace + (USR_STACK_LEGTH - 1) * 4"


這句話是什麼意思 DCD 後面的程序標號或數字表達式是何意


A:它的內容是初始化遞減堆棧的最高地址,看《ARM 微控制器基礎與實戰》2.3.2 節.


5


第2 章 編譯器與語言


第14 問:


Q:00254: Unimplemented RDI message 是什麼錯誤提示 我的設置連接都正常,是不是


芯片燒了


A:是JTAG 的問題.可以先使用ISP 操作試試就知道了,如果能ISP,說明LPC2104 沒有損


壞,還能正常運行程序.


第15 問:


Q:請教:我在調試程序的時候在AXD 中出現這樣的提示信息:


RDI Warning 00159:could not open specified device port.


我是根據配套教程的步驟設置的.


A:請按照光盤\easyarm_drive\readme.txt 安裝驅動程序.


第16 問:


Q:我用實驗程序運行經常出現下列信息! 程序不能下載到目標板.


Warnning! interrupt vectors data is not correct!


Program you downloaded can not run freely!


A:1.仿真器配置一定要正確,即"EasyARM Configuration"設置窗口中的"FLASH"項中選擇


"Erase Flash when need";


2.向量表累加和要爲0;


3.可以先在RAM 調試一個程序(運行),然後STOP,再使用File->Load Image...加載要


下載到FLASH 的調試文件.


第17 問:


Q:在ADS 中是否可以進行軟件調試基於UCOS-II 的程序


A:ADS 軟件調試只能調試ARM 的內核,不能調試外設.但是取消 PLL 鎖定檢測後,


可以調試任務切換,最終到空閒任務上.開始移植時軟件仿真是最好的工具.


第18 問:


Q:ARMulate 軟件是幹什麼的 2104 不是用EasyJTAG.dll 來仿真嗎


A:軟件仿真只能仿真 ARM 核.


第19 問:


Q:有關LPC2106.INC 的問題.我無法在project 引用lpc2106.inc 文件,只能引用lpc2106.h


文件, 這是什麼原因 且當我的主程序用匯編編寫時,不能引用lpc2106.h,用


lpc2106.inc 則無法加入project,請問彙編器應如何設置


A:不用加2106.inc 只要該文件在你的工程文件夾中,就可以直接在彙編程序的開始處加


6


"include 2106.inc".


注意:該文件是彙編文件定義的頭文件,定義內部寄存器.


第20 問:


Q:入口點是什麼意思 我在使用LPC2106 上移植UCOS-II,每次MAKE 時總是提示我


Image does not have an entry point,可是我是把光盤的vetctors.s 複製過來的,


而且仔細看了看,已經聲明瞭ENTERY,這是怎麼回事


A:需要在ADS 中設置入口.


第21 問:


Q:請教:如何定義不被初始化變量


A:讓編譯器不知道有這個內存地址即可.


A:如用分散加載文件分配RAM 故意預留一部分RAM 不分配,用它來存您不需要初始化的東


西.或者不調用編譯器提供的啓動代碼,不過這樣可能編程會麻煩一些.


第22 問:


Q:我直接通過JTAG 口下載EasyArm 板帶的Ext1_test 程序到ARM 中,出現中斷向量的告警:


interrupt vector is not correct arm is not running freely.


果然復位後芯片不能運行.但是我用串口下載後芯片能正常工作,中斷也行的.


並且我用JTAG 仿真的話,芯片能正常工作,中斷也行的,唯獨JTAG 口下載不行.


不知道是什麼原因


A:仿真器配置中要設置Erase Flash when need.也可以這樣試試:


1.可以先打開一個工程在RAM 中調試運行;


2.stop 程序;


3.使用File->Load Image…重新加載Ext1_test 生成的*.axf 文件.


Q:仿真器配置中我是設置了Erase Flash when need,但照你說的話,那不是在RAM 下調


試嗎


在RAM 下調試我是可以的,但是下載後出現interrupt vector data is not correct.


我又看了幾篇文章,是不是跟中斷向量表的累加和不爲零有關係啊


A:是的,是向量表的累加和不爲零.


因爲如果用ISP 下載能運行,說明向量表的累加和已爲零,而用JTAG 下載不能運行的情


況可能是 沒有正常下載代碼.先在RAM 中調試,目的是爲了後面正確下載程序到


FLASH.


第23 問:


Q:用Scatter 怎樣將某個函數或文件定位在Flash 的某個位置


A:參考


http://www.zlgmcu.com/download/downs.asp


ID="1009"


7


第24 問:


Q:我在仿真時遇到這樣的提示:


Error, Flash is protected by user configation!


怎麼寫到flash 裏面呢


A:看配套《ARM 微控制器基礎與實戰》附錄一.


第25 問:


Q:我在移植實驗中想到了兩個問題,如下:


1.Debug 和Release 以及DebugRel 有什麼不同,爲什麼在作2104 移植實驗時,要用


Release


2.在Release 中爲什麼要將RW Base 設置爲0x40000040 我將其設置爲0x40003000,


爲什麼不能工作


A:都只是一個問題,內存空間的使用,因爲跑OS 要比較大的內存空間,所以要騰出點地方.


第26 問:


Q:請問沒有MMU 的ARM 芯片是否支持使用malloc()函數動態分配內存


A:是否支持malloc()函數與芯片沒有多大關係,主要與編譯器有關.


Q:再問:如果沒有操作系統支持呢


A:也支持.


第27 問:


Q:在I2C 實驗程序中,我想查看數據緩衝區DataBuf 的值,怎麼查看


A:watch 窗口或鼠標停留在要查看的變量名上.


Q:我查詢的是寫入DataBuf 緩衝區的值,鼠標在上面根本就不會出現他的值,即使在watch


中加入,


結果也是"name not found".


A:變量被優化,調試時可以把該變量定義爲全局變量查看.


第28 問:


Q:仿真軟件和2104 開發板連接不上


DBE Warning 00041:


!An unspecified Debug Toolbox call failed


電源和開發板都連好,錯誤和沒接開發板一樣,驅動也安裝了,安裝時按確定鍵時,軟


件很長時間纔有如上反應,請幫忙


A:1.並口是否正常


2.在其它操作系統(如98)下或其它臺式PC 下試試.


第29 問:


Q:如何生成32 位hex 文件


8


我在Release Setting->ARM fromELF->Output Format 中設置爲Intel 32bit HEX,可


是好像沒有生成hex 文件


A:試試這種方法:


Target-->Target Setting-->ARM經典300問(轉貼) - Emily - Emilyost Link 中選擇"ARM fromELF"加上你上面設的應該不


成問題.


第30 問:


Q:請問關於settings 中r0 base rw base 的意思


A:ro:read only,rw:read and write.


第31 問:


Q:編譯成功後的信息第一行,code,R0 data,RW data,ZI data,debug 分別代表什麼


A:R0 只讀段,即程序代碼空間;


RW 可讀/寫段,即數據變量空間;


ZI 清零變量段,即需要清零初始化的數據變量空間.


第32 問:


Q:如何在ADS 裏面看任務執行的一些情況 比如堆棧.


A:多任務環境下的堆棧,內存等信息需要調試軟件的支持纔可以實現.


ucos 下有一個統計功能的模塊可以間接實現部分功能.


第33 問:


Q:請問向flash 燒數據時出現:exceeds flash limitation 請予賜教!


A:要寫入的flash 地址超過了範圍.如果不是代碼太大的問題,可以檢查scf 文件是否正


確.


第34 問:


Q:在LPC2214 之類的芯片中如何實現數組的絕對地址定位,比如51 的_at_的用法.


A:*((char*)0x40000300)類似訪問


Q:謝謝,但這樣做就無須定義數組變量,訪問也不便,還有高招嗎


A:可以使用分散加載.


第35 問:


Q:請問 ADS 編譯錯誤"L6221E:Execution region ER_RO overlays with Execution region


ER_ZI" 該如何解決


A:請用我們網站上的工程模板試一試,最大的可能是因爲你的RELEASE 或者DEBUG 選項裏


面沒有正確設置,按照參考《ARM 微控制器基礎與實戰》上面的設置,是不會有這個問


題的.


9


第36 問:


Q:請教一下:將程序寫入flash,再用從JTAG 方式調試寫入之後再復位程序沒什麼反映.


看了很多以前的帖子,說memmap 寄存器要爲1,我用的是一個很簡單的控制led 的例子,


改動了參數之後寫入flash 的.在這個程序的vectors 中找不到關於memmap 寄存器操作


的部分啊,這是怎麼回事,該怎麼辦呢


A:《ARM 微控制器基礎與實戰》上附錄有"常見問題",列舉了幾點程序寫到FLASH 不能運


行的原因. memmap 操作可以在target.c 中的TargetResetInit()函數內添加.


第37 問:


Q:HEX 文件.EASY2100 配套《ARM 微控制器基礎與實戰》上講:把項目編譯成HEX 文件,


我不會呀,咋辦


A:Target-〉target settings 設置Post-linker 並且設置Linker-〉fromELF.


Q:再問:我用的是光盤裏的例子,打開工程項目裏是DebugInARM.DebugInFlash.


RelInFlash.不是《ARM 微控制器基礎與實戰》上的DebugRel 呀,我都照《ARM 微控制


器基礎與實戰》上設置的,可用ISP 下載,提示無法找到HEX 文件.


A:光盤上的例子是用專用工程模板建立,已經設置好參數,與默認模板不同.


第38 問:


Q:EasyARM2100 開發板如何通過JTAG 接口下載到Flash


我在用EasyARM2100 開發板時JTAG 接口不能進行Flash 中的調試(DebugInFlash),但


是可以在RAM 中調試(DebugInRAM),且通過ISP 編程可以寫入Flash.


通過JTAG 接口進行DebugInFlash 調試時,總是出現如下提示:


Flash Sector 0 write failed!


Warnning interrupt vectors data is not correct!


Program you downloaded can not run freely!


請問是什麼原因 我該如何辦


A:仿真器設置選項有一個允許擦除FLASH 的選項,選擇它.


第39 問:


Q:我發現程序在RAM 調試時(RO=0X40000000) OK,但是JTAG 下載到FLASH(RO=0X00000000),


顯示如下:


The session file 'c:\Documents and Settings\jan\default-1-2-0-0.ses'


could not be loaded.


A:這是ADS 自身的問題,請不要通過IDE 運行AXD,而是通過開始菜單運行,然後Load 調


試文件調試.


第40 問:


Q:我有幾個問題想問問大家.


10


調試主機負責對ARM 源程序進行編譯鏈接,最好用什麼樣的高級語言對ARM 源程序進行


編譯鏈接 使用調試程序(如AXD)進行JTAG 調試,AXD 是什麼調試程序,是否是類


似什麼軟件之類的 到哪能下載AXD 的調試程序呢 怎麼樣進行AXD 程序進行JTAG 調



如何通過JTAG 仿真器發送到目標機上呢


對於單片機的調試,都用到了什麼軟件


都個有什麼作用呢


A:可以使用 ADS1.2,Keil C 也支持.AXD 是ADS 的一個組件.


您可以在本公司網站下載 EasyARM2100 開發套件快速入門看一看.


第41 問:


Q:EasyARM2100AXD 調試時出錯,故障現象:


按照光盤上的方法設置好ADS1.2 後打開光盤上的expamples\gpio\c\LedDisp 的工程文


件(從光盤上拷貝到硬盤,已去處只讀屬性).


編譯通過後,按Debug 按鍵運行調試,進入AXD.按Go 按鍵,EasyARM 沒有反應.再按


Stop 按鍵.


AXD 彈出兩個確認框窗口:


"No disassembly could be read at the requested address".


如果進入AXD 直接按Step 按鍵,也是會彈出同樣的兩個確認框.


軟件是光盤上的,沒有經過任何改動.光盤上的程序試過4,5 個都是這種情況.


AXD 的設置是按照光盤上的說明設置的.


EasyARM 上的JP8 是斷開的.ADS 在出現這種問題後重新安裝過,故障依舊.


出現這個問題前,可以調試.只是單步的時候感覺比較慢.差不多1-2 秒鐘才能單步一


次.


A:原因找到了,是芯片被加密了,無法寫入新的程序,用FLASH ISP 清除後解決.


加密後JTAG 完全不能控制芯片,否則可能被解密.


第42 問:


Q:我板上的lpc2214 開始可以在線編程,只搞了兩三次可以把文件寫進去.但我發現P0.14


未置低電平時也進入ISP 模式,燒入的文件原來可以ISP 下載到2014 開發板中運行的.


最後只能讀芯片的一些ID,載文件都不能進行.以下是對整片ERASE 時,對串口的捕獲,


命令返回是19.


Synchronized


Synchronized


OK


11059


OK


U 23130


0


P 0 14


0


E 0 14


11


19 configure tar... -> ARMUL , 只能仿真ARM 核外設不能仿真.


第48 問:


Q:爲什麼盤中的工程會出錯啊


A:文件的只讀屬性去掉了嗎


第49 問:


Q:您在2104 的《ARM 微控制器基礎與實戰》中提到ucos 與應用代碼分開編譯,在分開編


譯調試成功之後,最後要將代碼統一固化到芯片中.在最後一步需要注意什麼 統一編


譯時感覺要改動很多東西,有沒有什麼最簡單的辦法 能否詳細介紹一下方法 多謝!


A:使用我們的工程模板,可在本公司網站下載.其實不分開編譯也可調試.


http://www.zlgmcu.com/tools/kaifaban/EasyARM2104.asp


的EasyARM2104 開發套件快速入門和LPC210...


第50 問:


Q:請問,我的2104 板子,通過EasyJTAG 仿真時,在AXD 上沒有文件,而且出現這樣


"Error, Flash is protected by user configation!"


的提示,這是怎麼回事啊 在AXD 應該打開什麼類型的文件啊 謝謝啦!!!!


A:在仿真器的配置窗口設置仿真器允許擦除FALSH.


AXD->Options->configure target->configure->erase……


13


第51 問:


Q:關於arm 彙編語言跳轉指令的特殊用法.有如下兩條跳轉指令:


beq lablef


beq lableb


其中lable 爲某段程序的標號,beq lablef 表示向前跳轉到與當前指令最接近的標號


lable 處執行,而beq lableb 表示向後跳轉到與當前指令最接近的標號lable 處執行.


在arm 彙編中有定義這樣的用法嗎


A:沒有.


第52 問:


Q:我將一段程序從flash 從複製到了RAM 中,但是因爲混合編程中不能直接向PC 寄存器中


賦值來實行跳轉,這樣我該如何跳轉到這個RAM 中的地址呢


A:用函數指針.可參考IAP 例子.


第53 問:


Q:我想詳細的瞭解一下ADS 開發工具中的stack.s ,heap.s 和startup.s 中代碼的含義,


各位高手推薦本書或給解釋一下


A:開發套件用戶指南的第3.1.3 節有說明.


stack.s 定義了系統模式堆棧的起始地址.


heap.s 爲初始化庫函數的堆,是按ADS 的編譯器要求編寫的.


startup.s 向量表及初始化代碼,是根據CPU 來編寫的.


第54 問:


Q:我不知道所選擇的C 文件到底是用ARM 還是THUMB 編譯的,請大俠指點!


A:看配套《ARM 微控制器基礎與實戰》7.1,7.2,7.3 節.


第55 問:


Q:我重新建立了一個工程,沒有用模板,TEST.C 程序在編譯的時候提示OS_EVENT 沒有申


明,但是我看了代碼,TEST.C 中包含了CONFIG_EX.H,而congif_ex.h 中又包含了


include_ex.h, include_ex.h,這兩個頭文件又包 含了ucos_ii.h,而OS_EVENT 是在


ucos_ii.h 中申明的,不知道爲什麼會出現這種錯誤,能不能給我一個比較合理的目錄


結構


A:請參考我們光盤的目錄結構.最好使用我們的工程模板.


第56 問:


Q:請問,我現在做2114 的產品開發.出現以下問題,特向您請教! 問題:


我們開發的產品要採樣,採用週期固定.於是我們採用timer0 進行時鐘觸發,利用觸發


中斷程序 每隔10 毫秒採樣一次並顯示波形.這都能很好的進行.但是在中斷程序裏


面對幾個全局變量賦值, 跳出中斷後卻不能使用該全局變量.很是頭疼!請賜教!!


14


框架如下:


uint8 a; //全局變量


void __irq funtimer0()


{


...


a=0; //在中斷函數裏面對全局變量賦值


...


}


void fun1()


{


uint8 i;


i=0;


.......


i=a; // 出錯位置,在調試過程中運行到當前位置,鼠標移動到變量a 上


// 顯示數值是0,但是不能傳給i,i 的值不會隨該命令改變.


......


}


因此,我在中斷函數中採集到的數據放到全局數組中.採集完成關中斷後在用戶模式下


的程序中來處理該數組,但是該數組中的數據也不能使用!全局數組變量佔1000 個字節,


IRQ 堆棧長度是256.


A:全局變量用volatile 聲明.


第57 問:


Q:在AXD 裏打開Debuger Internals,在Variable Name 裏爲什麼沒有PINSEL2,ADDR,ADCR


等寄存器 要在哪裏設置


A:有些片內外設寄存器是不能讀出,《ARM 微控制器基礎與實戰》上的P33 頁有說明及處理


方法(在Memory 窗口寫入相應寄存器地址).


第58 問:


Q:請問不連easyArm 板可不可以直接軟件調試程序


我是指如果想直接調軟件部分,能不能在ads 或axd 裏直接調試


A:這和板子沒關係啊,你直接選ARMulate 不就行了,注意把等待PLL 配置完那條語句屏蔽


就可以啦!


第59 問:


Q:AXD 裏面出現 "RDI Warning 00159: Could not open specified device port"


誰能告訴我這個是問題啊我一直搞不懂啊,全部是按照《ARM 微控制器基礎與實戰》第4


章上配的圖做的啊,但是就是不能仿真啊.


A:請先按照光盤的easyarm_drive\readme.txt 安裝驅動程序.


15


第60 問:


Q:1.在《ARM 微控制器基礎與實戰》的2.6.3 節有說到"浮點數寄存器(F0-F7...)",2104


是否具有這些寄存器


2.如果EasyArm 不支持浮點運算,而我的程序需要用到浮點運算,請問可以實現嗎


A:1.沒有.


2.用C 就可以用浮點運算.


第61 問:


Q:EASYARM2104 的例子程序怎麼都是調用C 寫的程序,彙編那個怎麼沒用的啊


A:按如下步驟進行處理:


1.在項目管理窗口中刪除原來的所有文件;


2.在項目管理窗口中增加彙編文件*.S;


3.編譯鏈接,調試.


第62 問:


Q:請問版主:在AXD 調試軟件中,我單步運行到一定時候,我想讓自己編的軟件從復位處


重新運行, 在AXD 軟件中,EXECUTE 欄目中有單步,連續,運行到光標處等功能,但


無復位功能,如果要實現此功能,如何操作


A:我也沒有發現,目前只能用重新裝載的操作實現.


第63 問:


Q:在AXD 調試中,通過從jtag 接口,連接上lpc2106,出現如下信息:


TKSimulator for ADS, V1.2, 2003/08


Software Supplied by: ZLGMCU


ARM7TDMI-S, Little Endian


在從file|load imgage...文件,出現兩種情況:


1.正常,完全能調試;


2.出現問題,如下:


RDI Warning 00254: Unimplemented RDI message


請問,這是錯在哪裏 如何解決 謝謝!


A:可能是電源或其他接插件接觸不良引起.


第64 問:


Q:請教幾個問題:


1.移植中底層接口裏的__swi 關鍵字在SDT 中能用嗎


2.爲什麼在勘誤文檔中時鐘節拍服務子程序裏去掉了開中斷及關中斷的宏


3.時鐘節拍中斷的優先級應該設爲最高嗎


16


A:1.不知,請自己看一看軟件自帶文檔.


2.因爲中斷服務程序中肯定是關中斷的.


3.不必.


第65 問:


Q:arm 彙編中的中括號是什麼意思 比如下面的例子中括號是什麼作用呀


[ PLLONSTART


ldr r0,=PLLCON


ldr r1,=((0xe8啓動AXD.現象:數碼管能


顯示不斷變化的數字0--F,但是AXD 的連接失敗,提示"DBE Warning 00041: ....".


重複試了幾遍,現象相同.


請教原因以及對策.


A:剛纔把我機器的Win2K 系統的用戶屬性從"ARM經典300問(轉貼) - Emily - EmilyowerUser"修改爲"Administrator"就沒


問題了.可能是ADS/AXD 安裝的時候用了Administrator 權限,在"ARM經典300問(轉貼) - Emily - EmilyowerUser"下工作


有問題吧.


如果哪位老兄有類似問題,不妨試一下這個方法.


第67 問:


Q:在Init.s 中有這樣一段:


Reset


BL InitStack ;初始化堆棧


BL TargetResetInit ;目標板基本初始化


B __main ;跳轉到c 語言入口


誰知道__main()函數的具體內容


假如我不需要調用庫函數的話,是否可以改爲B main


A:看調試是彙編代碼裏有__main(),組成成分與一些鏈接選項有關.


可以.但是全局變量初始化不了.


17


第68 問:


Q:我在C 中嵌入這樣一條語句


__asm


{


MRS R4,CPSR;


STMFD SP!,{R4};


ORR R4,R4,0x80;


MSR CPSR_cxsf,R4


}


會出新報錯"illegal write to sp"版主和各位大俠有什麼辦法解決阿


A:嵌入彙編不能使用SP.


第69 問:


Q:請問 ADS 如下的編譯錯誤是什麼意思


L6221E:Execution region ER_RO overlays with Execution region ER_ZI


A:程序段內存分配可能有問題,RO(只讀),ZI(0 初始化)


第70 問:


Q:在axd 中有沒有運行程序的時間計算器 keil 中就有那樣的東西.


A:有的,不過不是時間而是執行週期,可以換算成時間.在debugger internals 中,具體


可以參考幫助文檔.


第71 問:


Q:我最初的init.s 中沒有加入heap 的分配和__user_initial_stackheap 函數,結果程序


跳到SWI 中死循環.我把他們加入後就好了.或者不加入他們,把B __main 改爲B main


也可以.請問何解 另外,就算目標板會陷入死循環,但是用軟件仿真卻可以正常運


行.何解


A:堆的位置沒有分配到有效的RAM 中.


第72 問:


Q:在ARM 彙編語言中,對立即數的有要求,我記得原來沒有這樣一說了.現在反而糊塗了,


用立即數時候,很小心很忌諱,不回象51 下隨心所欲的使用了,有對立即數熟悉的朋友


站出來給大家釋疑.


A:如使用"非法數據可以使用lrd 送到寄存器"的方法.


首先在存儲器中定義一個常量,再ldr 進去,編譯器是這樣弄的.可以看下面語句反匯


編的區別;


int z="0x101";


int z="0Xff";


18


第73 問:


Q:請教各位:我在AXD 中單步運行一段程序後,想回到程序的開始重新運行,除了重新加


載,


還有其他方法或按鍵


A:你的程序有多大 程序在Flash 運行點擊Reload Current Image 也不需要1 秒吧~


或在代碼窗口Set PC="0"


第74 問:


Q:在《ARM 微控制器基礎與實戰》程序清單6.22 的376 頁的OSIntCtxSW_1 中:


LDR R4, [R6]


ADD SP, R4, #68


LDR LR, [SP, #-8]


MSR CPSR_c, #(NoInt | SVC32Mode)


MOV SP, R4


LDMFD SP!, {R4,R5}


LDR R3, =OsEnterSum


STR R4, [R3]


MSR SPSR_cxsf, R5


LDMFD SP!, {R0-R12, LR, PC }^


請問高手ARM經典300問(轉貼) - Emily - EmilyDMFD SP!, {R0-R12, LR, PC }^是不是恢復新任務工作寄存器和工作模式,


LR 寄存器一併得到恢復,那麼ADD 指令後面的 LDR LR, [SP, #-8] 指令是不是可


以去掉


A:兩者恢復的是兩個不同處理器模式的LR.


第75 問:


Q:既然option 頁中的Image entry Point 填入的是調試入口地址,那麼在實際的程序運行


當中它是不會 覆蓋代碼中的ENTRY 入口聲明的,對嗎 僅僅是爲了調試的方便.


A:Image entry Point 優先.其實代碼中的ENTRY 是爲了確保代碼不被優化掉.


第76 問:


Q:我想使用標準C 語言的庫函數,比如memset 在string.h 中有定義,可是我直接包含


#include , 但是編譯沒錯誤,運行確有錯誤,應當怎麼設置


A:請使用最新的工程模板


第77 問:


Q:軟件中斷是不是必須由SWI 指令觸發


A:可以直接用你定義成軟中斷的函數名啊.比如:


19


__SWI(0x12) void myswi(void); // 聲明函數


__asm // 調用方式1


{


swi 0x12


}


myswi(); // 調用方式2


第78 問:


Q:《ARM 微控制器基礎與實戰》程序清單6.9 的程序是在哪裏被調用的


_user_initial_stackheap


LDR r0,=bottom_of_heap


MOV pc,lr


A:__main.千萬別刪喲, 否則出大事的.


第79 問:


Q:"LDR R0, =PINSEL0" 中"="是什麼意思 這語句是取地址還是取地址中的內容呢


A:這是LDR 僞指令,可用來加載32 位立即數或地址,LDR R0,=PINSEL0 是將PINSEL0 的地


址加載到R0 中.


第80 問:


Q:我不明白"SWI 0"和"SWI 0X123456"這兩條指令中的0 和0X123456 中有何用.


有沒有應用SWI 的具體例子讓我看看


A:那是特定的中斷入口地址,見ADS_DeveloperGuide_D.pdf 下的swi.


第81 問:


Q:SWI 的功能表嗎


A:SWI 的功能表由swi 異常服務程序決定.很多時候由編程者自己決定.


第82 問:


Q:請問:我在實驗您的原代碼進行ucos 移植時用的是例1,但是在按照圖7.17 設置處理


器的仿真器模式時enable comms channel view 和semihostin 項爲不可激活狀態.爲


什麼,能否給一點提示


A:在一些仿真器上使能了它們會影響swi 異常處理程序.


第83 問:


Q:請問"Unimplemented RDI message"這個出錯提示是什麼意思啊


20


還有,有的時候當我用axd load 一個.axf 文件時,常常loading 的沒完沒了,這是怎


麼回事啊


A:Unimplemented RDI message:爲命令操作失敗,需要重新連接.


下載不結束爲出現不正常現象,請重新連接並下載.如果每次都出現該現象請聯繫我們


的技術支持.


第84 問:


Q:各位高手好,我是ARM 初學者我在程序調試中"LDR PC,[PC,R2]"命令執行後PC 爲什麼


=0x0000000c, 在這條命令執行前PC+R2 地址上的值是0x0000000c 嗎


A:要使用軟件仿真.0x0000000C 是預取中止了.


Q:請問:ARM7 在初始化CPU 堆棧時,寄存器CPSR 和CPSR_c 有什麼關係 CPSR_c 是在那裏


定義的


A:這是MSR 指令的語法,"_"後部分指定CPSR 的域,請參考《ARM 微控制器基礎與實戰》


上關於這條指令的說明.


第85 問:


Q:軟中斷SWI 作底層接口的問題.以下函數爲啥要通過軟中斷調用,可以直接調用嗎


OS_TASK_SW(),


_OSStartHighTdy(),


OS_ENTER_CRITICAL),


OS_EXIT_CRITICAL(),


A:在用戶模式或Thumb 狀態不能直接調用.


第86 問:


Q:ARM 的一條指令是32bit 長, 但有時一個立即數也是32bit, 這是如何解釋的


A:指令中使用的立即數需要時8 位數移位獲得,並非所有數都可以.


第87 問:


Q:請教:全局變量的值在復位(不斷電)後會不會自動清零 (用光盤自帶的啓動代碼)


A:在C 語言中一般會會初始化0 或用戶指定的值,但這不是硬件自動的.


第88 問:


Q:the setting files for *.mcp is locked!是什麼問題


A:文件屬性只讀.


第89 問:


21


Q:請問,關於printf() 在ads 中怎麼用不了 謝謝!


A:請用我們我們網站上下載2104 的工程模板,它解決了這個問題.


即使這樣,也不能真正使用prinf.您還需要自己編寫一些底層函數才能使用,詳細參


考ads 自帶的ADS_CompilerGuide_D.pdf.


第90 問:


Q:swi 的功能號是如何來的 它和LR 寄存器的值是何關係


如《ARM 微控制器基礎與實戰》程序清單6.13


LDREQ R0,[LR,#-4] ;BICEQ R0,R0,0xff000000


AARM經典300問(轉貼) - Emily - EmilyDREQ R0,[LR,#-4] ;用來讀SWI 的代碼


BICEQ R0,R0,0xff000000 ;是ARM 方式進入,取低24bit


第91 問:


Q:請問在TargetInit()中函數開始會執行srand((INT32U)TargetInit),它是做什麼用的


A:ex1 用它來產生隨機數種子的.


Q:請問:我建立的工程中,所有源文件與2104 附帶的光盤例子源文件相同,編譯鏈接也一


切正常, 可就是不能到板子上跑!


提示錯誤是:向量中斷有錯誤,無法自由運行!!


這是怎麼回事 相同的源文件,加在你的工程裏,正常;加到我的工程中就出錯!


我創建的是ARM 可執行映象.


A:vector.s 你自己的嗎 如果是要計算向量去的累加和了.


第92 問:


Q:請問:vectors.s 中"DCD 0xb9205f80" 的0xb9205f80 在實際運用中需要改動嗎


A:不需要更改,除非改動了向量表中的指令代碼.


第93 問:


Q:請問,爲什麼queue 數據隊列,《ARM 微控制器基礎與實戰》上給畫成了環形


A:因爲頭跟尾的指針指向一個地址,隊列邏輯上是環狀的.


第94 問:


Q:有沒有人成功的把一個數據定義到程序空間裏 各種方法我都試了,是不是有什麼編譯


開關


A:使用const 修飾,定義變量時帶初始化值,要定義爲全局的變量.


第95 問:


Q:ads 裏沒有CODE 關鍵詞,怎樣使定義的字符串數組不佔用RAM 空間


22


A:const unsigned char string[]


第96 問:


Q:在例程中TIME_test 中的TIMEOUT 當寫入時提示:


Warnning! interrupt vectors data is not correct!


Program you downloaded can not run freely!


我不知怎樣改設置,哪位提醒一下


A:中斷向量表的校驗和不爲0,用AXD 看0 地址的數據(32 位方式),自己加一下.注意把


高於32 位的部分去掉.


第97 問:


Q:請教各位:我做TIMEOUT 實驗(2104 板),Make 通過,Debug 時出現瞭如下錯誤提示:


Warnning! interrupt vectors data is not correct!


Program you downloaded can not run freely!


設置Link:ARM Link


r0 base:0x00000000


rw base:0x40003000


image entry point:0x00000000 其它的沒變!!


而我使用ISP 完全可以下載而且可以運行!這可以說是設置問題,但是我實在找不到!


怎麼辦


A:請看一看配套《ARM 微控制器基礎與實戰》附錄1,ISP 軟件可能對它進行了處理,而JTAG


沒有特殊處理


第98 問:


Q:*(volatile unsigned int *)是什麼意思 例如*(volatile unsigned int *)addr 具體


是什麼意思


A:分開來看,(volatile unsigned int *)就是定義一個可變的無符號整形指針,前面的那


個*就是取起內容.


第99 問:


Q:如何理解#define VICIRQStatus (*((volatile unsigned long *) 0xFFFFF000))


A:宏定義,參考C 語言的書籍.


(volatile unsigned long *) 0xFFFFF000 將0xFFFFF000 強行轉換爲指針,然後 *(指


針) 即可對此地址進行訪問.


第100 問:


Q:在異常處理向量表的設置中,爲什麼不直接將異常向量的入口地址寫入PC 中呢,爲什麼


非要用什麼DCD 這些僞指令,到底有什麼用啊


A:爲了保證任何時候其累加和爲零,不然改一次程序就要計算一次.


23


第101 問:


Q:單步調試i2cINT.C 在ISendStr 中啓動總線後,程序怎麼又跑到vectors.o 中,進行初


始化了呢


A:由於VIC 的限制,程序不能在0x18 停下來,否則執行非向量中斷.如果沒有設置,則非


向量中斷爲0,將從0 地址執行.


建議:有中斷時不要單步執行程序,可以手動暫時關中斷或設置斷點代替單步.


(編者注:下載最新的驅動可以解決這個問題)


第102 問:


Q:請教:如何修改 ADS 的啓動代碼,從__main 到main,按道理應該有一個文件,修改這


個小文件, 就可以修改 啓動代碼.


A:__main 是ADS 運行庫,最好不要修改,要是不使用庫就不要用main()函數,起個別的名


字.直接跳轉過去就行了.


詳見:《ARM 體系結構與編程》P328.


第103 問:


Q:我在JTAG 仿真時出現的對話框,提示:


Warnning! interrupt vectors data is not correct!


Program you downloaded can not run freely!


A:參見《ARM 微控制器基礎與實戰》附錄一第一個問題的第二部分,選擇源代碼的啓動代


碼文件夾下的vectors.s,並參照《ARM 微控制器基礎與實戰》圖7.11 設置.


第104 問:


Q:初始化代碼中分配堆棧的問題


MSR CPSR_c, #0xd3 ;進入特定的處理器模式


LDR SP, StackSvc ;給當前處理器模式的堆棧指針賦值,這只是一個值而已,


;他在接下去的DCD 語句賦值


SvcStackSpace SPACE SVC_STACK_LEGTH * 4


這個語句開闢一個SVC_STACK_LEGTH * 4 大小的內存,SvcStackSpace 是這塊內存的標


號,我想應該就是內存的首地址,這樣應該好理解了.


StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4


這個語句就是把這個首地址加上堆棧大小值.


A:計算出堆棧指針來,我想這個堆棧是向下生長的,所以SP 賦值的是堆棧地址最高的那個.


第105 問:


Q:請問啓動代碼中這句是什麼意思


24


__user_initial_stackheap


LDR r0,=bottom_of_heap


MOV pc,lr


;/* 分配堆空間 */


AREA Myheap, DATA, NOINIT, ALIGN="2"


bottom_of_heap SPACE 256 ;庫函數的堆空間


我的問題是:


1.這個函數在哪裏被調用


2.賦值給r0 以後就完事了 r0 起什麼作用


A:堆和棧的分配函數,由ADS 提供的初始化代碼調用,具體參考配套《ARM 微控制器基礎


與實戰》的相關部分.


第106 問:


Q:2104 的啓動代碼是否適用2124 呢


網站上下載的那個easyarm2104 工程模版裏面寫着arm executable imag for lpc21**,


是否說也適用2124 呢 如果不行,哪些地方需要修改 希望能夠指點一下!


A:您可以下載2100 的工程模板.


第107 問:


Q:我在用ARM 的IAP 功能,要把已經燒到flash 中的數據寫到RAM 中,我是這麼寫的:


uint32 *q,data;


q = 0x00006000;


data = *q;


這是要讀的flash 的起始地址,但是第二句編譯出錯,我想應該是C 編譯器不許給指針


直接賦值, 我用匯編解決了這個簡單的問題,但是怎麼用C 來解決呢


A:q = (uint32 *)0x00006000;


第108 問:


Q:問一個有關彙編的基礎問題.


例程: ANDS R1,R1,#0x0400


BEQ WAITOK


請問 ANDS 是如何影響標誌位的,而BEQ 判斷的是那兩個操作數相等時執行


A:R1&0x0400 => R1,若結果爲0(即R1 爲0),則標誌位Z=1.


當Z=1 時,BEQ WAITOK 有效執行.


第109 問:


Q:請教:在ADS 中怎麼給某個變量確定固定物理地址


就是類似KEIL 中的 XDATA xxx _AT_ 0x4456 的功能.


A:使用分散加載機制,mem_c.scf 等就是例子.


25


第110 問:


Q:哪裏有介紹ARM 的C 語言編程的


A:其實大多數嵌入式系統的C 語言都差不多,可找一本寫嵌入式C 語言的書即可.


第111 問:


Q:請問在系統復位後首先執行的是否爲Boot Block 的中斷向量


然後由boot block 裏面的程序決定是執行用戶程序還是ISP 程序.


那麼這時啓動的boot block 裏的中斷向量表和用戶程序裏的中斷向量表是如何在flash


裏安排的


在《ARM 微控制器基礎與實戰》上看到的是復位後boot 扇區的最低64 字節出現在


0x00000000 區域,那用戶的中斷向量表應該在哪個區域


產品中一般爲0x00000000,在開發板中重啓後實際爲boot block 的中斷向量地址,對



A:看一看3.3.6 節.產品中一般爲物理0 地址處.


第112 問:


Q:《ARM 微控制器基礎與實戰》上有一段程序:


uint32 i;


i = VICIRQStatus;


i = IOSET;


請問:爲何先要讀取VICIRQStatus 的值,才能讀IOSET 的值


A:讀出VICIRQStatus 只是爲了方便觀察當前VICIRQStatus 的值,沒其它用途.


第113 問:


Q:請問處理器在什麼情況下處於用戶模式 多謝!


A:需要你去設置CPSR 寄存器.


用戶程序前臺程序一般在用戶模式/系統模式下運行.


第114 問:


Q:在EINT1_LED.S 中的倒數第二行有一個單獨的B 指令,它是什麼含義 多謝!


A:是"B .",跳轉到當前地址,即死循環,與以下代碼等效:


HALT B HALT


第115 問:


Q:模板裏到底有些什麼


A:起動代碼,相關編譯鏈接設置.


起動代碼是用來初始化系統的程序,如Startup.s,target.c,stack.s 等等.


26


第116 問:


Q:今天試用了工程模板.使用了ARM Executable Image for lpc21xx 建了個項目,看了下


啓動文件與原來的不同了,用了個《ARM 微控制器基礎與實戰》上的例程來作試驗,用


的是time0 定時中斷來亮燈的程序,用的例程的TargetInit()和int main(void);


修改了用戶堆棧和bottom_of_heap 的長度,程序能運行,但不能產生中斷,time0 和VIC


初始化的是正確的,是什麼原因


用工程模板建立的項目文件夾的src 中多了幾個文件,其中的


mem_a.scf,mem_b.scf,mem_c.scf,怎樣才能導入到項目中來 謝謝!


A:原來startup.s 默認是關了中斷的!


第117 問:


Q:在easyarm 2104 的配套光盤中的IAP 例子中,定義了一個函數指針


void (*IAP_Entry)(uint32 param_tab[], uint32 result_tab[]);


我看不懂,這個函數和普通的函數定義方法不一樣,尤其是(*IAP_Entry),大家教教我.


A:這是一個指向函數的指針!!


第118 問:


Q:變量定義中volatile 是什麼意思 請大俠告訴我一下《ARM 微控制器基礎與實戰》上c


語言定義變量時出現了volatile,不知道是做什麼用的.C 語言裏好像沒有這個語法阿!


A:告訴編譯器不要優化掉,volatile 是易變的意思.


第119 問:


Q:請問ARM 中的一個編譯方面碰到的問題.


在ARM 地彙編語言中,有條件編譯僞指令IF..ELSE...ENDIF;


而在C 語言中,有相應的條件編譯僞指令#IF...#ELSE...#ENDIF,在較大的程序設計中,


往往需要對整個程序進行條件編譯.


我要問的問題是:我在CONFIG.H 中設置一個編譯開關,對所有的C 文件進行條件編譯是


有效的, 因爲每個C 文件中都有一個語句:#include "config.h",我如何將該編譯


開關的信息傳遞給彙編語言文件,如VECYORS.S


A:好像沒有直接的方法,可以編寫一個CONFIG.INC 來管理彙編程序的配置.


27


第3 章 操作系統


第120 問:


Q:在SWI_Exception 的0x40 中的_OSFunctionAddr[regs[0]]中的Regs[0]指的是堆棧中的


R0 還是其它


A:是堆棧中的R0.


第121 問:


Q:《ARM 微控制器基礎與實戰》中在ucos 移植中說C 語言無法保證堆棧的結構,請問這是


什麼含義


A:就是不能保證有哪些寄存器入棧及寄存器入棧的順序.


第122 問:


Q:請問斑竹OSNeedToSwapContext 在哪個文件裏聲明的,我找不到


A:這是要刪除的,我的OS_CPU_C.C 中函數OSIntCtxSw:


/*


***************************************************************************


* 函數: OSIntCtxSw.


* 描述: 中斷級任務切換,此處並不真正進行任務切換,具體切換在 IRQ 服務程序中.


***************************************************************************


*/


void OSIntCtxSw (void)


{


}


第123 問:


Q:我的情況如下:我自己製作了一個硬件模塊,用的是lpc2214,現在需要將ucos-ii 移


植到上面去.我用板子做ZLG 公司提供的實驗,是可以做的,如led 燈等,按道理說串


口等硬件應該沒有問題,然後我就做公司提供的那三個移植實例:ex2_arm.編譯等是通


過的,生成了hex 文件,下載到flash 中,運行easyarm,但是沒有任何顯示,不知道是


什麼問題,應該是硬件上呢,還是其他的


A:這主要是RAM 的問題,請用我們的工程模板,並選擇在FALSH 中調試,如果編譯通過,


則一般行, 否則請減少任務堆棧的大小.


第124 問:


Q:下載了工程模板以後,將工程模板目錄下的文件都拷貝到了stationary 目錄下,然後建


立了一個 ARM Executable Image for UCOSII(for lpc21xx)的工程,在PROJECT 目


錄下的文件結構如下:


28


test.c


inlcudes.h


src->config.h,heap.s,includes.h,irq.s,lpc2294.h,


lpc2106.h,mem_a.scf,os_cfg.s,stack.s,startup.s


target.c,target.h,ucos_ii.c,ucos_ii.h,


arm->os_cpu.h,os_cup_a.s,os_cup_c.c


uCOS->ucos 源文件


arm_pc->pc.h,pc.c


編譯可以通過,但是MAKE 時提示:


ERROR:Execution region IRAM overlaps with Execution region STACKS.


如果我表述得不是很清楚的話,那麼可否告訴我工程模板到底怎麼操作,怎樣才能把例


子在 ARM2104 上跑起來.


A:RAM 佔用太大,請在flash 中調試,並減少任務堆棧的大小.


第125 問:


Q:我改了以下SCF 文件,把堆棧的值設置大了一些,但是還是出現以前的老問題,那就是


程序跑到


TargetResetInit()函數處後就跳到取數據終止的異常中斷去了.


A:不能把堆棧設置到內部RAM 之外.


第126 問:


Q:新舊任務級的切換是不是必須在管理模式下切換 切換後新任務的運行是不是必須在管


理模式下


A:在配套《ARM 微控制器基礎與實戰》裏的任務切換是通過SWI 實現的.SWI 會使CPU 進入


管理模式.同時CPU 自動將任務的CPSR 保存到管理模式的SPSR 中.


SWI 程序還保存了一些寄存器到管理模式的堆棧中.然後任務切換程序會在管理模式


和系統模式間來回切換,目的是把保存在管理模式堆棧的寄存器內容拷貝到任務的堆棧


中(注意:任務是運 行在用戶模式或系統模式的,這兩個模式使用同一個SP,這時的


系統模式的SP 指向的就是任務的堆棧),也會將管理模式的SPSR 拷貝到任務堆棧(注意


管理模式的SPSR 就是在執行SWI 時CPU 自動保存的任務運行時的CPSR,它記錄了任務


運行的CPU 模式和其他的運行狀態信息).最後把任務模式SP 保存到任務的任務控制塊


中(注意此時CPU 已經是運行在系統模式下的了).以上大致就是uC/OS-II 中所說的保


存任務運行環境的工作.


任務的恢復運行就比較好理解了.


接着前面的說,CPU 還在系統模式下.程序從任務控制塊中得到任務的堆棧指針.


(OSIntCtxSw_1 的第一句)將這個指針的值加上一定的偏移量保存到SP 中.爲什麼要


加上一定 的偏移量呢 因爲這時任務的堆棧中除了保存任務運行時的數據外還保存


了任務的上下文,即任 務切換時保存的CPU 寄存器等內容.而我們恢復任務等一下是


在管理模式下進行的,用的是管理模式的堆棧指針.等恢復任務後CPU 就開始執行任務


29


代碼了.我們已經沒有機會再修改系統模式下的SP 值了.所以在這個時候就應該對SP


進行調整.調整的大小就應該是所保存的上下文佔用的大小.從堆棧中恢復LR 的值.同


樣的道理,管理模式和系統模式使用不同的LR,在切換到管理模式之前,必須先在系統


模式下恢復任務運行時的LR.(OSIntCtxSw_1 的第三句)接下來就切換到管理模式了.


(OSIntCtxSw_1 的第四句)使管理模式SP 指向任務堆棧(第五句)注意這是沒調整過


的任務SP,也就是保存了上下文環境的SP.


接下來的事情就真的很簡單了.從堆棧中恢復出保存的東西.先是OSEnterSum,然後是


任務的CPSR (注意任務的CPSR 就是進入SWI 時由CPU 自動保存到管理模式的SPSR


中的,所以此時也是恢復到管理模式的SPSR 中)最後一句就是典型的中斷返回語句了.


恢復寄存器,恢復PC,加了一個^號意味着同時將SPSR 拷貝到CPSR 中.


現在是回答你的問題的時候了.


切換前任務是運行在什麼環境下的(包括CPU 模式,所有的寄存器),任務切換後任務就


是運行在 什麼環境下的.對任務來說,什麼也沒改變.只有PC 值指向了下一條指令,


哈哈.


第127 問:


Q:請教:在rtos51 解釋的概念裏的"信號量"比較難懂,"消息隊列"可以理解爲任務之間


互相傳遞的參數,但"信號量"怎樣理解呢 具體一點,謝謝!


A:信號量是60 年代中期Edgser dijkstra 發明的,它實際上是一種程序間的約定機制,


這種約定決 定那個程序(任務)可以執行.在多任務內核中普遍使用信號量用於:


1.控制共享資源的使用權(滿足互斥條件);


2.標誌某事件的發生;


3.使兩個任務的行爲同步.


信號量像是通行證,且通行證的數目是有限的.任務要運行下去,要先拿到通行證.如


果信號量 已被別的任務佔用,該任務只得被掛起,直到信號量被當前使用者釋放掉.


信號量的值可以是0 到255 或0 到65535,或0 到4294967295,取決於信號量規約機制


使用的是8 位,16 位還是32 位.到底是幾位,實際上是取決於用的那種內核.根據信


號量的值,內核跟蹤那些等待信號量的任務.


一般地說,對信號量只能實施三種操作:初始化,也可稱作建立;等信號也可稱作掛起;


給信號或發信號.信號量初始化時要給信號量賦初值,等待信號量的任務表應清爲空.


想要得到信號量的任務執行等待操作.如果該信號量有效(即信號量值大於0),則信號


量值減1,任務得以繼續運行.如果信號量的值爲0,等待信號量的任務就被列入等待信


號量任務表.多數內核允許用戶定義等待超時,如果等待時間超過了某一設定值時,該


信號量還是無效,則等待信號量的任務進入就緒態準備運行,並返回出錯代碼(指出發


生了等待超時錯誤).任務以發信號操作釋放信號量.如果沒有任務在等待信號量,信號


量的值僅僅是簡單地加1.如果有任務在等待該信號量,那麼就會有一個任務進入就緒


態,信號量的值也就不加1.於是通行證給了等待信號量的諸任務中的一個任務.至於


給了那個任務,要看內核是如何調度的.收到信號量的任務可能是以下兩者之一:


1.等待信號量任務中優先級最高的任務;


2.最早開始等待信號量的那個任務,即按先進先出的原則(FIFO).


30


有的內核有選擇項,允許用戶在信號量初始化時選定上述兩種方法中的一種.但Small


RTOS51 只 支持優先級法.如果進入就緒態的任務比當前運行的任務優先級高(假設,


是當前任務釋放的信號量激活了比自己優先級高的任務).則內核做任務切換(假設,使


用的是佔先式內核),高優先級的任務開始運行.當前任務被掛起.直到又變成就緒態中


優先級最高任務.


第128 問:


Q:我用了兩個串口,但當我把程序做大的時候,發現在這個任務裏所建立的郵箱失敗,


我只用一個串口時是沒有這種事情的.


Uart0ReviceMbox = OSMboxCreate((void *)0 ); /* 建立郵箱 */


if (Uart0ReviceMbox == NULL)


{


while (1);


}


我想問一下有幾種可能會造成這種分配失敗 我的程序存儲器用量如下:


Total R0 size 22168


Total RW size 7956


Total ROM size 22168


A:在OS_CFG.H 中定義最大事件數,太小的話,分配會失敗的.


第129 問:


Q:在周立功的原例子中,系統代碼事先燒到ROM 中,應用代碼在RAM 中運行.我想知道,


(RAM)應用代碼調用系統函數,那麼2104 是如何把ROM 中的系統函數的地址傳遞給RAM,


也就是應用代碼和系統代碼是如何關聯在一起的 我猜是通過swi(軟中斷),應用代碼


通過swi 調用系統代碼,但是swi 中斷程序中,是如何獲得燒到RAM 中的系統函數的地


址哪 百思不得其解.


A:您看一看romcode 工程中swi 的0x40 和0x41 功能,


及Os_call.c,Os_call_arm.s,Usr_call_arm.s.


第130 問:


Q:16k 的RAM,128 的FLASH ROM 跑uc/os-II 夠嗎 再跑點應用程序夠嗎


A:取決於您的應用程序對RAM 的需求,及代碼量.一般程序可以.


第131 問:


Q:利用lpc2104 開發應用程序時,在Os_call_arm.s,Os_call.c 兩個文件中,那幾個函數


需要在彙編中實現,哪幾個需要在.c 文件中實現,爲什麼 謝謝各位大蝦 !


A:4 個以上參數用c 實現.因爲通過寄存器只能傳遞4 個參數.


31


第132 問:


Q:如果禁止SmallRTOS51 進行中斷嵌套管理(#define EN_OS_INT_ENTER 0),是否還需要


設置中斷優先級寄存器IP,使得所有中斷的優先級都相同(全高或全低)


A:受SmallRTOS51 管理的設置爲最低優先級,不受SmallRTOS51 管理的設置其它優先級較


好.


第133 問:


Q:在OS_CPU_S.s 文件中有如下一段代碼,其中有兩句代碼的作用不是很明白,請解說一下.


OSIntCtxSw_1


LDR R4, [R6] ;獲取新任務堆棧指針


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;這兩行代碼有何作用呢


ADD SP, R4, #68 ;17 寄存器CPSR,OsEnterSum,R0-R12,LR,SP


LDR LR, [SP, #-8]


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


MSR CPSR_c, #(NoInt | SVC32Mode) ;進入管理模式


MOV SP, R4 ;設置堆棧指針


LDMFD SP!,{R4, R5} ;CPSR,OsEnterSum


;恢復新任務的OsEnterSum


LDR R3, =OsEnterSum


STR R4, [R3]


MSR SPSR_cxsf, R5 ;恢復CPSR


LDMFD SP!, {R0-R12, LR, PC }^ ;運行新任務


A:這兩條指令是在系統模式下恢復用戶模式下的LR;可以參考配套《ARM 微控制器基礎與


實戰》6.4.9 節.


第134 問:


Q:我將《ARM 微控制器基礎與實戰》上uC/OS-II 的第一章例2 移植例在ARM2104 開發版上


實現例2 中的TEST.C 中的"#define TASK_STK_SIZE 512"改爲"...256",程序編譯


後,數據量低於16K,能正常運行,但運行時"Total Stack"不是256 全是1024.另


UC/OS-II 書上,第一章例2 每一個任務的堆棧都是512,爲什麼書上11 頁"Total Stack"


是"624,1024,1024,1024,1024,1024,1024",請老師指點,萬分感謝!


A:顯示的是字節而定義的是字.


第135 問:


Q:可不可以把所有的任務和相關信號量(二值)在一個任務裏面一起創建呢 我現在是這


樣做的, 不知是不是這方面的原因 而且全部信號量是這樣創建的:


XX1 = OSSemCreate(0);


32


XX2 = OSSemCreate(0);


XX3 = OSSemCreate(0);


一共創建了十個信號量,以前程序代碼版本是分開寫的執行起來沒有問題,不知現在爲


什麼這樣寫就會出現小問題呢 這樣的問題和我的任務和信號裏書寫位置有關係嗎


A:必須在使用信號量前創建信號量.


第136 問:


Q:UCOS 在中斷處理完後調用 OSIntExit(),該函數將判斷是不是要進行任務切換,如果是


則調用 OSIntCtxSw()切換任務, 然後才恢復寄存器,中斷返回.這樣說來,在中斷


返回前,已經切換到別的任務去了,在再次回到被中斷的任務前,是不是一直沒有中斷


返回


A:如果進行任務調度,則不會執行OSIntCtxSw()後的語句,相當於中斷已退出.


第137 問:


Q:最近我在學習使用SMALL RTOS 時發現一個 BUG.


任務在調用系統等待函數 OSWait(K_TMO | K_SIG,x) 後,不能在延時 x 個 ticks 後


被喚醒.


我分析了一下原因如下:


在 OS_CORE.C uint8 OSWait(uint8 typ, uint8 ticks) small 中,


case (K_TMO | K_SIG): 中執行了函數 OSTaskSuspend(OSTaskID);


( OS_CORE.C 第549 行)而此函數將延時值改爲了 0!


解決辦法:將此函數改用另一個函數 OS_TaskSuspend(TaskID);


並在其後加入任務切換函數 OSSched();


便能工作正常.


A:對,這是疏忽,謝謝.您的更改是對的.


第138 問:


Q:在文件Os_cpu_a.s 中的函數OSIntCtxSw 中有如下語句:


……


(1) LDR R4, [R6]


(2) ADD SP, R4, #68


;17 寄存器 CPSR,OsEnterSum,R0-R12,LR,SP


(3) LDR LR, [SP, # --8]


(4) MSR CPSR_c, #(NoInt | SVC32Mode) ;進入管理模式


(5) MOV SP, R4


……


(6) LDMFD SP!, {R0-R12, LR, PC }^ ;運行新任務


《ARM 微控制器基礎與實戰》404 頁中解釋:只所以要(1)(2)是因爲"OSTCBHighRdy


—>OSTCBStkPtr 保存的是任務棧位置,而寄存器恢復後堆棧指針並不指向這,所以要調


33


整新任務堆棧指針." 可是將堆棧指針調整到 "新任務入棧的其它數據(見《ARM 微控


制器基礎與實戰》圖6.3)"處後,除了取出了LR 以外並沒有做 什麼,而當執行了(4)


後又重新將堆棧指針指向了棧頂(即第(5)句).我認爲可以將(2)省去,直接將(3)改爲


"LDR LR, [SP, # 60]",而當執行完(6)後,堆棧指針就自動指向了"新任務入棧的其它


數據"處.這樣修改後我運行了EX1_arm 例子,正常.


請問這利用(3)進行堆棧指針調整的原因是什麼 不調整可以嗎 謝謝.


A:注意不同模式有不同的SP 指針.您這樣做會造成內存泄漏,長時間運行會耗盡堆棧而使


程序崩潰.


第139 問:


Q:不明白在光盤上ROMCODE/SRC/下的os_call.c 做什麼用.


A:是應用程序與事先固化到flash 中的ucosii 接口的一些代碼.在本例中爲應用程序如何


調用事先 固化到flash 中的ucosii 的OSFlagPend 等函數的接口代碼.請看配套《ARM


微控制器基礎與實戰》的7.4.3 節的第10 點.


第140 問:


Q:請問在OS_CORE.C 中的常數數組OSUnMapTbl[]是做什麼用的


A:用來計算優先級的,查表計算比較快.


第141 問:


Q:ucos 的中斷嵌套層數是否受到初始化時分配的IRQ 堆棧大小的限制 我的理解是每一次


中斷需入棧的寄存器有R0-R3,R12,LR,SPSR,共7 個,如果想達到8 層嵌套的話,堆棧長


度IRQ_STACK_LEGTH 應設爲56,不知這樣理解對不對.


A:是,但中斷至少佔用8 個字,因爲c 語言的中斷處理函數會將一些數據壓入堆棧.


要達到8 級嵌套需要的堆棧長度與具體的代碼有關.


(編者注:新移植代碼已有改變)


第142 問:


Q:請問:核心定時器中斷不進入可能因爲……


我的程序在運行一段時間以後,核心定時器中斷即操作系統用的Timer0 不能進入,查發


現CPSR 的I 位爲1,請教這可能是哪個原因


A:估計爲開關中斷次數不匹配造成.


第143 問:


Q:請問:GetOSPprioCur()函數應怎樣調用 它是一個內核函數嗎


爲什麼我在內核和任務分別編譯時正常,而合到一起編譯時它告警爲未定義呢


同時我已給您發了一個郵件,請教如何將分別編譯的程序合在一起編譯的方法,請指教!


A:這是我自己編寫的函數,其實就是返回OSPrioCur 的值,請參考MyFunction.c.


34


第144 問:


Q:關於不受uc/os 控制的中斷:在ARM 板中,非屏蔽中斷可以掛起正在執行的uc/os 任務,


除了不能使用uc/os 中的函數外,它的執行工序是不是和受管理的中斷一樣,先掛起當


前任務,再保存CPU 寄存,然後再執行中斷ISR,完成後,內核脫離,寄存器恢復,最


後任務調度.


另外,《ARM 微控制器基礎與實戰》中提到不受管理的中斷,它的工作是否和非屏蔽中斷


一樣,也可以在uc/os 正執行時發生中斷.如果不同,它們是怎樣工作


最好是象受管理中斷一樣說明一下它的工作時序!


A:必須比受管理的中斷的優先級高,編寫方法與沒有OS 時中斷的編寫方法一樣.


第145 問:


Q:不受uc/os-ii 管理的中斷和受管理的中斷是否具有相同的響應方式,即不受管理的中斷


在中斷 uc/os 正執行的任務後,是不是也是先掛起當前的任務,保存CPU 寄存器,再


執行中斷子程序,恢復CPU 寄存器,進行最優先級任務的調度.


A:不受uc/os-ii 管理,uc/os-ii 都不知道,還有什麼任務調度


Q:我知道不受管理的中斷不能調用uc/os 的函數,但《ARM 微控制器基礎與實戰》上說:


FIQ 不受uc/os 管理,但可以用來執行緊急任務,就是說在uc/os 運行時,不受uc/os


管理的中斷還是可以發生的,它是把整個uc/os 操作系統中止,還是隻是中止uc/os 正


在執行的任務.不受管理的中斷完成後,接着執行什麼


A:可以發生,中斷整個RTOS.


Q:我看了您在lpc210x 上的移植代碼,你在說明中說:"如果您想通過軟件仿真,請將


target.c 中的第 51 行屏蔽, 這樣就可以看到任務逐個切換,最後將進入空閒任務."


我照這做了,但是在單步或者設斷點執行時會產生異常,原因是未定義指令


OS_ENTER_CRITICAL()引起的,經過編譯的函數都會變成藍色,但這個函數還是黑色,因


爲它實際上是一個軟中斷,請教您如何調試才能看到任務逐個切換 謝謝!


A:1.屏蔽的那一行是死等鎖相環鎖定,軟件仿真時是沒有鎖相環的.


2.黑色是正常的,因爲沒有定義成函數.


3.因爲你的 AXD -> OPTION -> 配置處理器中的 VECTOR CATCH 中的 S 選中了,所以 AXD


將你的軟件中斷當成了異常給捕捉了,取消即可.


第146 問:


Q:請教ucos2 的源代碼中經常碰到:return((void*)0)是什麼意思


A:返回空指針.


第147 問:


Q:這是個什麼錯誤,怎麼改啊


OsMemPut 是個函數名稱


Error : L6200E: Symbol OSMemPut multiply defined (by uCOS_II.o and


Os_mem.o).


A:這是重複定義錯誤.請不要把uCOS_II.C 添加到你的工程中.


35


第148 問:


Q:我想請教一下在配套光盤中有沒有ucosII.h 文件,怎麼我總是找不到的


如沒有能否提供下載地方 謝謝!


A:北航出版的第2 版就帶有uC/OS 2.52 源代碼,


還可以到其它網站上找找.


第149 問:


Q:我想問一下一個任務中的子函數的局部變量算不算進堆棧的容量.


我發現我在用郵箱傳遞一個較大的值時,是在一個任務的函數中聲明瞭uint8


byte[500],可在傳遞時值發送了變化,只好用的外部變量了,最後搞得郵箱只起了信號


量的作用,所以我覺得局部變量雖然是從堆棧中取得數據,最後在任務切換時,把局部


變量也保存到堆棧中,不知道我這種理解是否正確


A:算.局部變量在函數退出後(不管任務是否卻換過)被釋放.


第150 問:


Q:我用UCOS 在EASYARM 上的一個程序內編寫了5 個任務,前4 個任務調試後工作正常,在


編譯第5 個任務時,提示爲:


Execution region ER_RO overlaps with Execution region ER_ZI.


編譯還提示:


TOTAL ROM SIZE (CODE +RO DATA +RW DATA ) 8624


我曾經試圖修改"#define TASK_STK_SIZE 64 "也不管用,請問,如何解決


A:問題已找到,代碼超過16K.上面的信息會在zi 段或者rw 段與ro 段(代碼段)發生重


疊時發生.


第151 問:


Q:請教uc/os 移植問題


在2104 上面能進行移植嗎 如果不行的話,需要買2106


A:你要在os_cfg.h 中把不用的內部調用都裁減掉,就可以做一個很小的內核,就是不裁減


你就是14k 左右,寫在FLASH 裏一樣也能運行.


第152 問:


Q:請教信號量的概念問題.


我準備用信號量來編寫一個ARM 程序,但我沒有完全理解信號量的概念.


例如:現在有4 個任務:TASK1,TASK2,TASK3 和TASK4,任務的要求是:TASK1 和TASK2


之間需有信號量傳遞信息;TASK3 和TASK4 之間需也有信號量傳遞信息.


假定TASK1 和TASK2 之中已建立了一個信號量爲


RandomSem = OSSemCreate(1);


我要問的問題是:TASK3 和TASK4 之中的信號量是否需重新建立一個 例如,加一條


36


RandomSem1 = OSSemCreate(1);


換一個問法:即若TASK1 和TASK2 之間需有信號量傳遞信息;


TASK3 和TASK4 之間需也有信號量傳遞信息,我只需在運行這4 個任務之前的初始化程


序中有一條指令即可:RandomSem = OSSemCreate(1);


A:用兩個信號量,你第一個說法對了.


第153 問:


Q:各位:在UCOS 多任務中有一個任務結構如下:


void TASK(*pdata)


{


uint8 i;


任務循環前的一些指令集A;


while(1)


{


任務循環;


}


}


我要問的是:與該任務有關的初始化,如串口初始化,是否不用放在整個程序的開始處,


而作爲指令集A 的一部分,也可達到同樣效果


A:啓動和初始化代碼放在一個文件裏主要是爲了程序的模塊化,不過代碼少的話倒是可以


放在一個函數裏完成.


A:ucos 的事件標誌使用注意點:


請在事件標誌結構定義前加__packed,否則由於字節對齊的問題會產生沒有反應的bug!


第154 問:


Q:移植中碰到的問題!


我把周工《ARM 微控制器基礎與實戰》上的範例1 移植到ARM 上,但任務沒有跑起來,


請做過移植的朋友幫幫我吧!


我是把代碼生成HEX 文件全部下到FLASH 中,不知道這樣對不對啊 軟件需要怎麼設置



A:先檢查ARM Linker 的設置是否正確 參照《ARM 微控制器基礎與實戰》P42O 設置release


的參數.


A:感覺運行ex1 還是比較容易的,畢竟斑竹都已經把代碼寫好調試好了,你可以不必完全


把它拷貝下來,可以自己建一個project,然後一個個文件添加,這樣比較容易弄懂哪


些文件都是來幹嘛的,哪些還需要自己改寫.推薦在建立project 時可以把相應文件分


組,我就是把uC/OS2.52 文件放在一個組下,需要自己改寫的(如OS_CPU_A.S)放在一個


組內,啓動代碼放在一個組內,自己的代碼(如main,自己的任務)放在一個組內,這樣


比較分明些,個人建議.


第155 問:


Q:看過操作系統固化之後,有點疑問:


37


把操作系統和用戶代碼分開真的能節約RAM 空間嗎 只是在用戶代碼定義的起始地址在


0x40000000 的情況下(即調試時)纔會節約吧 一般情況下我覺得如果要真正使用的話


都應該是把程序起始地址定義到00000000 上的,這樣的話纔有,不然一掉電程序就沒了.


這樣理解對嗎


A:是的,參考合併在一起的例程


http://www.zlgmcu.com/download/downs.asp


ID="861".


第156 問:


Q:任務間的數據傳輸除郵箱等外是否可以建立一個全局變量在任務間傳遞數據!


A:可以,但要注意重入問題和代碼優化問題,最好使用volatile 修飾變量,如果不能一次


讀寫完畢則需要加上開關中斷的代碼.


第157 問:


Q:請問:uc/os 任務堆棧問題.


在ucos 移植的程序EX1_arm 中:


#define TASK_STK_SIZE 128 /* Size of each task's stacks (# of WORDs) */


#define N_TASKS 10 /* Number of identical tasks */


請問,任務堆棧設爲什麼設這麼大


A:可以變小,但要在複雜任務中應保證夠用.


第158 問:


Q:在看uc/os-II 的書時,關於ucos-II 中任務切換的幾種情況的問題.


1.在一個時鐘週期內,至少所有的任務都要運行一遍,對嗎


2.任務切換髮生的三種情況:


a.任務A 主動放棄CPU 的主動權,利用 OSTimeDly() 延時,進行任務切換;


b.中斷時鐘週期發生時,在任務就緒表中尋找最高優先權的任務,如果當前任務不


是最高優先級,發生任務切換,否則仍執行原任務;


c.發生irq,fiq,軟中斷,取指錯誤和取數據錯誤五種異常模式時,直接發生任務


切換, 中斷處理結束後,在任務就緒表中尋找最高優先權的任務,如果當前任


務不是最高優先級,發生任務切換,否則仍執行原任務.


A:1.不一定,如等信號時 OSPend(x, 0, &err)時.


2.只有在IRQ,FIQ 和軟中斷受OS 管理時才能進行任務切換,同理取指,取數異常在啓


動階段的 死循環根本談不上任務切換.


第159 問:


Q:請問:在移植UC/OS 中的軟件中斷彙編接口程序中取功能號碼.原程序爲:


如果是在THUMB 狀態,則爲LDR R0,[LR,#-2]


如果是在ARM 狀態, 則爲LDR R0, [LR, #-4],


在清除R0 中的最高兩位,R0 的值就爲功能號.


爲什麼是從LR 中取值呢 LR 的值是進入中斷時候保存的PC 值嗎 迷惑!


A:執行SWI 指令後,處理器進入管理模式,LR_svc 中保存返回地址,順藤摸瓜,根據LR_svc


38


就可以取得SWI 語句,也就取得了中斷號.


第160 問:


Q:請問及各位高手:OSIntCtxSw()函數分別在includes.h 和OS_CPU_A.s 中有定義,區別


在哪


程序OSIntExit 中調用該函數的時候是不是都是去調用了includes.h 中的宏定義的那



兩者各自的應用範圍在哪兒 我看過一個移植實例上只有一個OSIntCtxSw 函數.請指


教!


A:includes.h 中的宏 OSIntCtxSw 在C 中被調用.


第161 問:


Q:問一個堆棧指針的問題


在OSIntCtxSw_1,獲取新任務堆棧指針.


LDR R4, [R6]


ADD SP, R4, #68 ;17 寄存器


CPSR,OsEnterSum,R0-R12,LR,SP


LDR LR, [SP, #-8]


MSR CPSR_c, #(NoInt | SVC32Mode) ;進入管理模式


MOV SP, R4 ;設置堆棧指針


LDMFD SP!, {R4,R5} ;CPSR,OsEnterSum


;恢復新任務的OsEnterSum


......


我想問一下ARM經典300問(轉貼) - Emily - EmilyDR LR, [SP, #-8],這一行程序中,爲什麼堆棧指針要減去8 個字節


的值


A:這是調整SP 的指針,使其指向棧中的LR.看一看配套《ARM 微控制器基礎與實戰》的圖


6.3.


Q:ucos 中斷丟失.


在ucos 在每秒切換200 次時正常,但在1000 次時中斷丟失 可能是哪裏的問題


A:問題已經找到,是隨2104 中的ucos 不支持中斷嵌套.在不嵌套時4000 次/秒也是正常


的.


第162 問:


Q:uC/OS-II 能在2104 上和用戶程序一起編譯嗎 一定得分開編譯嗎


《ARM 微控制器基礎與實戰》上介紹的移植方法上是分開編譯的,我想合併在一起調試,


這樣就不必用軟件中斷去尋找系統函數的入口地址.要做到這樣,是不是隻需把


OS_TASK_STAT_EN 設置爲1,OS_SELF_EN 爲0


39


A:可以,網站上有例子


http://www.zlgmcu.com/tools/kaifaban/EasyARM2104.asp


.


第163 問:


Q:請教:我運行OSInit(); 函數,程序死在SoftwareInterrupt B SoftwareInterrupt 困


惑呀!


A:uc/osii 的啓動代碼與普通的啓動代碼不同,您使用的是普通的啓動代碼.


第164 問:


Q:請問:在UC/OS-II 目錄中的README.TXT 下,有的例子說:"僅lpc2106 有足夠的RAM


可以在RAM 中放入所用代碼."那麼,如果我使用LPC2104,在FLASH 中存放運行代碼


是否能正常運行 謝謝!


A:主要看數據是否超出16k,如果超出,請減少任務佔用的堆棧.


第165 問:


Q:請問:在UCOS-II\ex2_arm 中,我編譯時出現錯誤提示如下:


ERRORARM經典300問(轉貼) - Emily - Emily6221E:execution region ER_R0 overlaps with Execution region ER_ZI.


如何解決 而我在UCOS-II\ex1_arm 中編譯.運行都正常,謝謝!


A:定義任務堆棧小一點,如"#define TASK_STK_SIZE 128"


第166 問:


Q:uCOS-II\EX2_arm 我什麼也不動,用ADS 打開,可是編譯的時候出錯,是很多文件找不


到.


比如ucos_ii.h 就找不到.


#include "..\..\source\ucos_ii.h"


可是我的光盤裏沒有source 這個文件夾啊,還有很多uCOS-II 文件也找不到,是不是我


的光盤少了東東 站上有得下載嗎


A:要將uC/OS-II(v2.52)源代程序放到source 目錄下,北航出版的uC/OS-II 書(第二版)


帶有.


第167 問:


Q:OSIntNesting(嵌套層數)和OsEnterSum(關中斷計數器),有什麼區別嗎


我個人認爲這兩個變量相同,不知爲什麼要定義兩個變量


A:OsEnterSum 是關中斷的計數器,目的是實現臨界段嵌套.


OSIntNesting 是中斷嵌套層數,目的是實現中斷嵌套.


第168 問:


Q:爲何我EX1_FLASH 移植的時候總出現如下錯誤提示,請問是哪裏出錯了


Error : C2933E: type disagreement for 'OSTaskStkInit'


40


Os_cpu_c.c line 70


A:是調用OSTaskStkInit 時類型不一致導致,好好看一下C 語言.


第169 問:


Q:請問:在SWI 軟中斷指令中,LR 中放的是異常模式下的返回地址,而這個地址的低8 位


和低24 位分別是thumb 和ARM 指令下的立即數,這種對應的關係是如何來的


還有執行THUMB 和ARM 指令,LR 中放的地址最後的位應是0 和00,那麼爲什麼會有


swi 01


swi 03


這樣的立即數呢


A:您的理解不對,可以看一看os_cpu_s.s 這個文件.


第170 問:


Q:2104,2119 中都不能用UCOSII 的flag 的問題.


在模板中ARM Executable Image for UCOSII(for lpc21xx)加入這個程序文件.實際上


程序運行到 KeyFlagGrp = OSFlagCreate(KeyFlags,KeyFlagErr); 時就進入Startup.s


的取數據終止,但在沒模板的情況下是沒問題的,請問哪位在模板中用過UCOSII 的


flag


A:字節對齊問題,請在事件標誌結構定義前加__packed.


第171 問:


Q:我請教您一個問題,在2104 裏寫程序的時候用 malloc()來分配內存單元的時候,經常


出現在程序中被分配的單元數值在任務切換的過程中被改變的情況,不知道您碰到過沒



是如何解決的 謝謝!用ucos 中的內存分配函數就不回出現這種問題.


A:請在網上下載最新的模板,其中啓動代碼有更新.


另外,如果分配太大的空間可能會造成程序跑飛.


第172 問:


Q:在uC/OS 中進入臨界代碼區時,只是關swi 中斷,還是將所有的中斷都關斷.


A:要關所有調用了OS 系統服務函數的中斷.一般是IRQ 中斷.


41


第4 章 芯片


第173 問:


Q:2100 實驗板的問題.


使用幾次RelInFLASH 後不能正常工作,包括其他兩種方式也不能工作在RelInFLASH 和


DeBUGinflash 時顯示一個錯誤


Warnning! interrupt vectors data is not correct!


Program you downloaded can not run freely!


不知怎麼回事 使用DebugInRAM 雖然不報錯,但無法正常工作.


A:可能是啓用了加密功能引起的,使用ISP 擦除FLASH.


第174 問:


Q:很有意思,自從買了2100 實驗板一直在用DebugInRAM,今天想試試DebugInFLASH,後


來就選了後者進行調試,奇怪的現象發生了,以後再進行DebugInFLASH 之前確切的說是


進入AXD 在運行之前都顯示着我第一次用DebugInFLASH 時下裝的程序,一運行就可以顯


示當前程序的結果,每次如此,只要不運行其他程序,實驗板上的LED 就保持第一次下


載的程序的狀態,RESET 和重新上電都不行,是不是我的這個程序把開機的DEMO 替換掉


了,哪裏可以下載到那個DEMO,我想再裝回去.


AARM經典300問(轉貼) - Emily - EmilyebugInFLASH 就已經把程序下載到FLASH 了,原先出廠的程序已被你的程序覆蓋.


第175 問:


Q:我將其按照intle 32 bit hex 編譯後將hex 文件通過ISP 下載到2104 開發板上爲什麼


沒有反映 後來再下載C 語言編寫的同樣功能的文件,前幾次可以運行,後來又下載


了別的程序後就又不能運行了,請問這是什麼問題 多謝!


A:光盤上的EINT1_LED.S 只適合於在RAM 中調試,如果要下載到FLASH 中運行,需要加入


向量表(且要求向量表累加和爲0).


Reset


LDR PC, ResetAddr


LDR PC, UndefinedAddr


LDR PC, SWI_Addr


LDR PC, PrefetchAddr


LDR PC, DataAbortAddr


DCD 0xb9205f80


LDR PC, [PC, #-0xff0]


LDR PC, FIQ_Addr


ResetAddr DCD MAIN


UndefinedAddr DCD Undefined


SWI_Addr DCD SoftwareInterrupt


PrefetchAddr DCD PrefetchAbort


DataAbortAddr DCD DataAbort


42


Nouse DCD 0


IRQ_Addr DCD 0


FIQ_Addr DCD FIQ_Handler


MAIN ...


第176 問:


Q:手冊上只有I1.8,而沒有I3.3,無法計算片子功耗.


A:3.3V 與外設相關.芯片本身在3.3V 中的消耗可以忽略不計.


第177 問:


Q:通過查看數據手冊LPC2119 的接地有三種,分別是Vss(0V 電壓參考點),Vssa(模擬地),


Vssa_pll (pll 模擬地),三種的電壓都爲0V,但爲了降低噪聲和出錯機率需要隔離,


請問如何隔離 電源方面:有兩種供電電壓,一種是1.8V(內核),一種3.3V(I/O 口)


分別存在隔離問題,請問如何解決 吾乃新手,還忘老手不吝賜教,謝謝!


A:與普通的多種地佈線類似(它們有多少種方法就有多少種方法),最終這些地線還是要接


到一起.


第178 問:


Q:請問LPC2119 的電源芯片選哪款較爲合適 有沒有推薦的匹配


A:與2104 一樣,可選SPX1117.


第179 問:


Q:我現在數字電路除LPC2114 使用3.3V 電壓外,其餘的大部分是5V 的.我想先將LPC2114


連接到 CPLD,再連接到其它電路(CPLD 的I/O 口可以輸出或輸入5V)不知道行不行.


謝謝.


A:我覺的簡單的電路可以用LVC 芯片,必要時可以用3V 的CPLD.


第180 問:


Q:請問:你們公司的ARM 芯片相對於 象44B0X 等等一系列的ARM 處理器的優點在那裏


好象LPC2104 還比較的貴啊!現在我正在考慮選擇 ARM 芯片的問題,望回答.謝謝


A:我們的LPC210X 內部有FLASH 和RAM,LPC211X 爲工業級適用於工控領域,並且是全球唯


一可加密 的ARM.


以整個系統成本來說,LPC ARM 內部有FLASH 和RAM,低功耗,可加密性價比更高.具有


ARM 的性 能,單片機的特點,在許多應用場合比其它的ARM 更優越.


第181 問:


43


Q:我的2214 板IO 口和中斷均能正常工作,今天準備調顯示器,顯示器接在CS2 上,8 位


數據線,通過查資料,得cs2 的地址空間爲8200 0000,於是我將命令口地址定爲0x8200


0001,數據口地址定義爲0x8200 0000,對啦,數據命令切換線在A0 上,在顯示器初始


化前,對CS2 進行了配置,即BCFG2&=0XCFFF FFFF,即除修改成8 位數據線外,其它均


不變,對顯示初始,定時送顯示器,但是測量CS2 口線,根本不出現低電平,更不用說


數據線啦,即好像外部總線根本沒有工作.


之後根據2214 的模板,從新設置了參數,結果寫信號出不來,片選,讀地址,數據均有.


PINSEL2=0x0f814910;


BCFG2&=0xcfffffff; // CS2,8 位數據線,


請問,配置外部總線還需要其它寄存器嗎,由於手上沒有這方面的資料,請給予幫助.


謝謝!


A:注意BCFG2 的寫保護位.


第182 問:


Q:請問:關於LPC2214 的BOOT0 和BOOT1 的用法.


前提:我使用內部FLASH 作爲程序存儲器,利用外部總線CS0 擴展一片並口的12 位AD,


CS1 擴展並口的液晶,CS2 擴展一片RAM 芯片.


我的想法:將BOOT0 和BOOT1 上拉,系統上電啓動後,檢測到11,那麼從內部FLASH 啓


動,之後我可以設置管腳的選擇寄存器,使能CS0 和CS1 和外部總線,那麼我就可以隨


時的利用它的地址訪問我的外部擴展的設備.


請問我的想法對嗎,並請指點一下我應該注意的相關的問題.


A:正確.


第183 問:


Q:請問:2214 外擴SST39VF320 在CS1 上爲什麼讀ID 不正確 程序如下:


//設置PINSEL2 位


#define P1_26_31_Debug 4 // JTAG D2


#define P1_16_25_Track 8 // 跟蹤 D3


#define P2_Data_Bus 0x10 // D0-15 IO (D5 D4=01)


#define P3_27_WE 0x100 // 寫信號 D8


#define P3_26_CS1 0x800 // D11


#define P3_25_CS2 0x4000


#define P3_24_CS3 0x10000


#define P3_0_23_ADDR 0x0f800000 // 地址總線


//PINSEL0=P0_0_15_Set;


#define PIN2Set (P1_26_31_Debug+P1_16_25_Track+P2_Data_Bus+\


P3_27_WE+P3_26_CS1+P3_25_CS2+P3_24_CS3+P3_0_23_ADDR)


#define SST39VF320_Com_Add1 (*((volatile unsigned long *) 0x81005555))


#define SST39VF320_Com_Add2 (*((volatile unsigned long *) 0x81002aaa))


#define SST39VF320_ID1_Add (*((volatile unsigned long *) 0x81000000))


44


#define SST39VF320_ID2_Add (*((volatile unsigned long *) 0x81000001))


void InitGPIO()


{


PINSEL2=PIN2Set;


BCFG1=0x10000000; // 16 位


}


void Check320(void)


{


SST39VF320_Com_Add1=0xaa;


SST39VF320_Com_Add2=0x55;


SST39VF320_Com_Add1=0x90;


// Delay_150_Nano_Seconds();


// Read the product ID from 39VF320


SST_id1=SST39VF320_ID1_Add; // 讀出ID 不對


SST_id2=SST39VF320_ID2_Add; // 讀出ID 不對


SST39VF320_Com_Add1=0xaa;


SST39VF320_Com_Add2=0x55;


SST39VF320_Com_Add1=0xF0;


}


A:CPU 的A0 不能不能接,另外地址也要相應的變化(針對FLASH 的地址和針對CPU 的地址


不一樣).


第184 問:


Q:請問1.8V 電源和3.3V 電源的跳線要同時供電嗎 分別是給誰供電的


A:一個是給核心(內核)供電,一個是給I/O 口供電.


第185 問:


Q:1.ARM 的P0.1(WR),P0.4(RD)爲何不直接和以太網控制芯片的IOWB,IORB 相連


NETCS 起什麼作用


2.網卡控制芯片的INT0 爲何要接一個反相器和ARM 的P0.7 相連


3. 我能否直接連接到ARM 的P0.16(外部中斷0 輸入)口呢


4.8 位數據線和5 位地址線怎麼實現分時複用


A:1.使用片選選擇,NETCS 就是片選信號.


2.因爲8019 的中斷是輸出高電平,爲了適應所選芯片,所以加反相器.


3.如果所選芯片支持低電平或跳變觸發,就可以不用加反相器而直接與外部中斷輸入相


連.


4.加鎖存器.


第186 問:


45


Q:目前210x 的各功能均試驗完畢,現在想知道的是其IAP 功能是否可以向PSD 產品那樣實


現遠程的程序更新 如果可以,那麼當程序代碼寫入FLASH 後如何讓程序轉到更新後的


程序 PSD 是通過寄存器來完成轉換的,那麼210x 如何實現呢 比如210x 的程序是從0


地址開始執行的,假如原代碼長2FFFH,現在更新後的程序長3500H,那麼在IAP 時只能


將代碼寫到非00000000~00002FFFH 區域FLASH 中,寫完後該如何讓當前程序停止而轉到


更新後的程序呢 PSD 產品是因爲有2 塊存儲器,在執行當前存儲器中程序時可對另塊


存儲器寫操作,寫完後在將執行權交給另塊存儲器.期待您的回覆!


A:如果,你的程序較小(64k),你就把它當作兩塊獨立的FLASH(多個扇區).


寫入其中一塊,另一塊空着...


程序開始執行的時候,判斷哪一塊是最新的,跳轉過去就行了!


一旦從外界收到"更新程序"的命令,檢驗數據,更新另外一塊,就行了!


接收完畢,燒寫結束,寫入最新程序標誌.立即跳過去.


下一次開機,執行最新的.


這個方法,比較安全.可以防止中途通訊結束,復位等.


如果你的程序比較大,有點懸……至少,在某些干擾環境下,不要那麼做.


第187 問:


Q:開發板實驗中 delay_ns(uint32 dly) 在上述條件下是延時dly 秒嗎 如是則執行速度


似乎並不 快 怎麼估計出來的呢


A:如果程序和數據均在片內RAM 中,這樣計算:


1.一般指令需1 個主時鐘時.


2.每次跳轉增加3 個主時鐘時間(也許是2 個,需要確認).


3.從RAM 中取一個操作數多增加一個主時鐘時間,以此類推.


4.保存一個結果到RAM 中多增加一個主時鐘時間,以此類推.


5.訪問片內外設,增加一個外設時鐘時間.


注意僞指令ldr rn,=x 需要從ram 中取一個操作數.


第188 問:


Q:請問如果lpc2104 和5V 的芯片字節連接,中間不接小電阻,會怎樣 對系統有沒有很大


的影響


A:不安全而已.


第189 問:


Q:2104 的功耗最大在多少,(考慮外設全部工作,功率損耗)


EASY ARM 板上提供的電源最大輸出電流好象只有300mA 哦.


A:芯片本身功耗最大值小於70mA(120 攝氏度,核2.1V 供電,運行於60MHz).一般情況


小於50mA.


IO 口耗電(即3.3V 耗電)與其它電路密切相關,實質是其它電路在消耗電源(ARM 本身


對3.3V 的消耗是極小的).


46


第190 問:


QARM經典300問(轉貼) - Emily - EmilyPC2114 替換LPC2104 的話,我的程序還需要做哪些變動


哪些內部專用寄存器的地址是否變動


還有,我原來設計電路用的是LPC2104 的次要JTAG 口,現在換到LPC2114 上來,需要怎


麼改電路


A:程序無需改動,JTAG 設計時在RTCK 接一個4.7k 的下拉電阻即可.


第191 問:


Q: 有一問題請教,在市場上買的ARM 核單片機的程序用ADS1.2 建立項目,添加初始化程


序vectors.s, init.s,target.c 和target.h 後再寫自己的主程序,編譯燒錄到ARM


中即可投入使用了嗎 而有的ARM 嵌入式系統中還有bootloader,那是不是利用ARM 開


發的產品都要bootloader,而bootloader 是通過什麼軟件編譯的


我所買的easyarm 開發板的lpc2104 中有bootloader 嗎


A:bootloader 是用來下載程序到FLASH 中的,LPC210x 具有ISP 功能,可直接使用ISP 下


載程序,不需要自己編寫bootloader.


第192 問:


Q:我想用IAP 把數據存到2104 的FLASH 裏,可我怎麼讀出來呢


A:定義一指針,指向你用IAP 寫數據的那個區域,就可以讀了.


第193 問:


Q:當PLLCFG 設置爲0x05 時的效果和設置爲0x25 時一樣,但晶振是11.0592MHz 的,如果


設爲0x05, Fcco 的範圍不在156M-320MHz,爲什麼還可以用,而且和其它沒有區別


A:手冊說明的是保守值.實際的芯片的Fcco 可能在更大的範圍可以工作.


第194 問:


Q:WDT 復位後從地址0 開始執行嗎 運行程序5.40 後,WDT 復位後並不是從地址0 開始執


行,卻跑去執行


[0x07806808] dcd 0x07806808,


並一直執行此語句.如何才能從地址0 開始執行


A:WDT 復位後是從0 開始執行程序.可在復位處設置一些外部現象(如LED 閃爍),然後脫


機運行.


第195 問:


Q:我運行光盤上原始的IAP 程序例子,使用它的project 是正常的,但我自己重新建一個


目錄和project,參數設置按照原來工程的設置,編譯出來的axf 文件就是會在運行到


第一個 SelSector(1,1)時無法繼續下去,我自己的axf 文件和光盤上的一樣大16kB,


究竟是怎麼一回 事 有一處設置Language Settings 裏的ATPCS 項有什麼意義 其他


47


工程好像沒有選擇這一項.


A:IAP 是THUMB 指令,如果用戶程序是ARM 指令,所以調用時需要使用BX 指令.則C 編譯


器的ATPCS 項要設置"ARM/Thumb interwork...".


第196 問:


QARM經典300問(轉貼) - Emily - EmilyPC2104 具有6 個PWM,可以應用與電機控制,可是卻沒有計數器進行電機轉速的PID


閉環控制, 這個情況是不是lPC2106 的一個缺陷呢 如果不是,那應該怎麼樣才能進


行外部脈衝的計數 在不用外加計數器的情況下! 很是困惑!


A:捕獲算週期.


第197 問:


Q:ISP 通訊的問題.


自己做的板子,使用ISP 下載程序,提示無法通訊.板子上使用了跳線使得44 腳和地連


通,也通過max3232 進行電平轉換了.還有復位電路感覺也一切正常.不知道爲什麼就


是無法通訊.好暈啊,各位成功下載的大俠們指點一下吧.試了好幾天了,都沒法成功.


A:你確保了max3232 過來的電平正確了嗎 如果正確了,還要確保通信方向是否弄反,最


後注意復位信號是否正確.


A:搞定了,原來是max3232 的問題,現在已經可以下載程序了!


第198 問:


Q:如何用ISP 軟件擦除FLASH 中的內容啊


我在調試UART0 串口程序的時候出現問題,上網看到很多文章都建議要先擦除FLASH 中


已有的內容,於是用ISP 軟件進行擦除.但是在使用該軟件過程中,按到很多鈕都說:


串口不能正常工作.


這是什麼原因啊 請教高手正確使用ISP 軟件的方法及注意事項.


A:看看你的跳線是不是按要求接好了!!


第199 問:


Q:EasyArm2104 開發板上的ISP 下載的時候通訊不上.請問,要跳JP6 嗎


A:您可以自己試一下:


1.是不是接的UART0 口


2.系統晶振(XATL.Freq)是不是11059.2kHz


3.串口選擇是否正確


4.要求你復位的時候你是否有復位


5.ISP 使能跳線使用JP1(JP6 和JP7 保持主JTAG 調試狀態)!


第200 問:


Q:請教高手,lpc2104 和lpc2114 外部晶振接法


原來我用LPC2104 做的板子,外部晶振接到X1 時不可用.後來接到X2 上時好象可以用,


但這與資料上的說法好象有點出入.現在我想換LPC2114 改版,但不想再次改版了.故


在此請教外部晶振接法


48


A:使用外部無源晶振,晶振兩個管腳無需連接,與51 單片機基本一致;時鐘信號由X1 輸


入.


第201 問:


Q:請問有沒有工業級的21**系列


A:lpc2114 等芯片就是工業級的.


第202 問:


Q:讀LPC2119/2129/2194/2292/2294 使用指南之迷惑.


1. 對於2292/2294,開放了外部總線,程序應該可以放到外部,外部和內部的存儲空間


地址不連續,如何保證程序超過128K 後自動跳轉到外部執行程序


2. VIC 部分,VIC 通道號17#和18#都是EINT2,是什麼意思 難道一箇中斷源佔2 個號


EINT3 的VIC 通道號是多少


3. 我購買的芯片是否內部已經有了Boot 裝載程序


A:1.使用分散加載.


2.可能是筆誤.


3.有.


第203 問:


Q:請問用LPC2104 擴展D12 有沒有問題


A:可以使用模擬總線,速度比51 快幾倍.


第204 問:


Q:請教ARM經典300問(轉貼) - Emily - EmilyPC2114 的V3 能否接2.8V


系統有多個外設,有一個使用2.8V±5%的電平接口,其它使用3.3V,那麼LPC2114 的


V3 怎樣接


V3 接2.8V 電壓基準是否可以,口線與其它3.3V 的接口能否直接相連


A:建議不要超出手冊說明的範圍使用芯片.


第205 問:


Q:我自己做的板子,把2104 的44 腳(EINT1)接地,再利用LPC210XISP 軟件通過串口0


往芯片裏寫程序,爲何按了復位鍵以後連芯片的ID 都不能讀到


A:應該檢查如下幾點:


1. 確保你的芯片在工作.一般可以查看芯片的幾個電源是否都正確,查看晶體是否有


波形, 最好還可以看看各電源的紋波是否嚴重.


2. 確保電平轉換芯片的正確工作,以及各輸入輸出的正確.這個方向最容易弄反.


3. 查看復位端的電平是否正確,復位按健正常.


4. 確保44 腳接地.


49


第206 問:


Q:請教如何通過2104 的串口1 來往芯片裏寫程序


A:使用ISP 功能,不能用串口1,只能用UART0.


第207 問:


Q:請教ARM2104 配套《ARM 微控制器基礎與實戰》上第一個實驗的問題.


在ADS1.2 中編譯以下程序後進入AXD 進行調試成功.


程序稍加修改,使LED1..LED4 同時閃爍,在ADS1.2 中編譯以下程序進入AXD 調試成功.


問題:兩個程序的軟件延時部分相同,但兩個程序使LED 的閃爍間隔時間不同,不知是


何原因


A:可以先使用ISP 將芯片FLASH 擦除試試,可能是FLASH 程序設置PLL 的緣故.


第208 問:


Q:1.《ARM 微控制器基礎與實戰》上說32 字節的向量表的累加和必須爲0 纔可脫機運行,


是否需要每次修改程序後修改第六個保留向量的值(因爲地址有改變).


2.《ARM 微控制器基礎與實戰》上說用ldr pc, resetaddr 指令代替b 指令可全空間跳


轉,但是我看指令說明ldr 指令的地址只能是當前地址的+-4k 呀!


A:1.不用修改.


2.請看書.


第209 問:


Q:關於2119 的can 的通訊問題,就是2119 的波特率的設置與SJA1000 有什麼不同


A:基本上一致,將ARM7 的Fvpb 與SJA1000 的晶振對比:


BRP,SJW,TSEG1,TSEG2 均是同樣的設置方法,需要計算,可參照SJA1000 中位定時參


數的計算方法.


第210 問:


Q:請問各位高手.新買的ARM 芯片是不是直接安裝上去就可以直接下載程序工作了了嗎,


還需要有什麼別的設置嗎.


AARM經典300問(轉貼) - Emily - EmilyPC2000 系列有片內FLASH 的都可以直接ISP,不過要保證硬件正常.


第211 問:


Q:2119 實時時鐘電池怎麼供電 所有的電源引腳都要供電嗎


A:沒有獨立的電池供電引腳,以後會推出RTC 獨立晶振和備份電源接口的型號.


不太適合電池供電,除此以外,功能還是很強的.


第212 問:


50


Q:在調試實驗程序的時候,把低功耗掉電模式實驗代碼PDRUN 編譯後下載到2104 FLASH


以後,程序正常運行了.可是再DEBUG 程序時,在AXD 下總是提示錯誤:


Error:flash is user configured protected


我能明白這個是因爲2104 一直處於掉電模式的原因,可是如何解除這種狀態,把現在


FLASH 裏的這段程序擦除掉啊


A:通過ISP 軟件擦除.


第213 問:


Q:請教關於"IAP 實驗的問題"


《ARM 微控制器基礎與實戰》359 頁的IAP 實驗是用匯編寫的,然而在光盤上IAPtest


實驗的程序是用C 編寫,其中提到本實驗是調用IAP 服務程序.請問:


1. IAP 服務程序放在了什麼地方(彙編部分)


2. 我想向其中寫入10 字節數據,而不是諸如256 個字節,是否可以,如何實現


3. 在主程序中定義一個數組,如何把此數組中的數據固定在特定地址中阿,然後我好


進行RamToFlash.


A:1.在BOOT 區,入口地址爲0x7ffffff0,IAP 服務程序爲THUMB 指令.


2.先讀取原數據到RAM 中.如果只需要保存小量數據,且經常要更改,最好使用外部


E2PROM.


3.可能不好實現,參考ADS 幫助手冊吧.


第214 問:


Q:請問LPC2104 系統爲什麼採用11.0592Mhz 的晶振,是在定時上有優勢還是其他原因.


A:選用11.0592MHz 只是爲了得到精確的通信波特率,串口通信的可靠性高.


第215 問:


Q:請教:lpc2104 和RTL8019AS 的接口問題.


以前在C8051F 上做,高低地址是固定的,容易接口,RTL8019 映射地址也容易算出.現


在lpc2104 是32 位的,32 個地址線和32 個數據線,和外圍器件接口時帶到很困惑.不


知有沒有高手看過周立功網站的提供的lpc2104+RTL8019AS 的接口電路,SA0-SA4 和


lpc2104 的哪個腳接在一起 請指點由一個573 來控制地址與數據總線複用現在有點明


白虛擬總線了,加上一個地址鎖存器,和51 機的就很相似了.


A:對,爲了兼容51.


第216 問:


Q:開發板上的74HC125 的U5C,U5D 起什麼作用


A:去抖動.


第217 問:


Q:請教:在2100 開發板的ADC 實驗(P119 面)中爲什麼每次AD 轉換都要啓動兩次


51


A:切換通道後,丟棄第一次ADC 轉換值.


第218 問:


Q:如果我的AD 轉換需要的滿量程是0V~5V,是不是把AD 部分的電源即V3A 由現在的3.3V


改爲5V 供電就可以了


A:把輸入的電壓用電阻分壓就可以了.


第219 問:


Q:疑問:2104 開發板上用了MAX708,其已有高/低電平復位輸出,爲什麼還要用74HC125



A:爲了使手動與JTAG 都可以對芯片復位.


第220 問:


Q:請教高手關於自己做板子的問題.


我自己做了一個2104 的板子,第一次上電可以通過串口順利地把 .hex 文件從串口寫入


flash, 然後再次上電,程序就不執行了,並且再次用周立功公司提供的ISP 軟件卻


無法訪問該芯片.同樣地程序我放到周立功地2104 的開放板用同樣的步驟,它卻能正常


運行,我的板子基本上是按《ARM 微控制器基礎與實戰》上的圖製作的,請指點我的問


題可能的原因在哪裏 請教自己做板子容易出錯和注意的地方.


A:重新上電試試.


P0.14 口是否已接爲低電平


測一下晶振是否起振


Q:晶振測過已經起振,運行自己的程序不是要把P0.14 口斷開嗎 用ISP 軟件下載程序的


時候才把P0.14 接地是不是


A:需要ISP 時P0.14 口接地;


需要運行用戶程序時,P0.14 口要接一個上拉電阻,因爲P0.14 內部無上拉(作爲輸入時).


第221 問:


Q:請問2104 的復位電路我不用MAX708 和74HC125,做成象51 單片機那樣的復位電路可以



A:做成這樣是爲了保證JTAG 接口和按鈕,上電都可以復位芯片!


實現線與邏輯,如果你不需要調試只是生產的話,完全可以那樣設計復位電路.


第222 問:


Q:關於REMAP


請問remap 的時候只要給MEMMAP 賦值就好了嗎 具體的中斷向量表的映射系統自動給你


生成


在啓動代碼中關於remap 我只看到賦值,而在《ARM 微控制器基礎與實戰》上寫了一段


重映射的代碼示例P280 程序清單5.2.


52


如果系統自動remap 的話,那麼映射到的地址空間我們沒法改動了


代碼中,通過B lable1 或bl Lable2 進行跳轉時,要不要進行棧的操作


如果調用的是c 語言函數,除了傳遞必要的參數,有沒有保存寄存器呢


A:中斷向量表不是系統自動生成的,是由用戶編寫.Remap 通過改變MEMMAP 的值實現.


請看一下"ARM-Thumb 過程調用標準"(ATPCS.pdf)這篇文檔.安裝ADS 後就有.


第223 問:


Q:請問:lpc2104 運行速度


ARM7TDMI(-S)能提供0.9MIPS/MHz 的指令執行速度,lpc2104 cclk 爲60MHZ 時指令執行


速度應爲0.9*60 = 54 MIPS,這樣得到一條指令的執行速度大概爲0.018us.可我用示


波器觀察計算得出一條指令的執行時間遠遠大於這個數值,大概爲0.1us-0.8us(可能由


於流水線的影響,指令執行時間的差別很大).這是怎麼回事呀


A:這是一個在存儲器帶寬足夠時的平均值.如果程序和數據均在片內RAM 中,這樣計算


1. 一般指令需1 個主時鐘時間


2. 每次跳轉增加3 個主時鐘時間(也許是2 個,需要確認)


3. 從RAM 中取一個操作數多增加一個主時鐘時間,以次類推


4. 保存一個結果到RAM 中多增加一個主時鐘時間,以次類推


5. 訪問片內外設,增加一個外設時鐘時間


注意僞指令ldr rn,=x 需要從ram 中取一個操作數.


在flash 中如果MAM 配置爲最優,平均速度與在ram 中相差無幾.


第224 問:


Q:請教斑竹關於211x 和22xx 系列P1.16-P1.25 這些引腳的作用


另外在開發版上除了JTAG 口外,上述引腳是否用到


在設計自己的系統時,如果將P1.16-P1.25 這些腳作爲普通輸入輸出口用,是否會影響


系統的調試


A:ETM 跟蹤端口.


一般JTAG 仿真器不使用這些引腳,所以設計自己的系統時用作I/O 即可.不會影響調試.


第225 問:


Q:請問,請問評估板上的S-1131B 哪裏能訂購到,或者有什麼替換型號.謝謝


A:SPX1117M3_1.8 和 SPX1117M3_3.3.


http://www.zlgmcu.com/Sipex/power/SPX1117.asp


.


第226 問:


Q:關於 P2104 的驅動能力!


我正在用2104 外接LCD 其中用P0 口模擬總線 我的了LCD 電壓是5V 的,而2104 是3.3V


的,能否直接相接 我沒接時還有信號輸出但接上之後就什麼信號都沒有了,請問是何


緣故 是否需要電平轉換芯片或驅動芯片 上拉電阻能否滿足要求


A:中間串一個小電阻試一試.我們接過多種總線器件都沒有問題.


53


第227 問:


Q:問一下,lpc2104 的I/O 的驅動能力


單個I/O 可以走多大電流


全體I/O 可以走多大電流


A:數據手冊上有,Ioh,Iol.


第228 問:


Q:2119 最高頻率可達60MHZ,在頻率比較高的時候應該使用幾層的電路板,有沒有確切的


規定


A:不知道什麼時候有人就把PCB 的層數與頻率劃上了一個必然的關係.60MHz 很高嗎


看看你的調頻收音機,FM 波段範圍是88-108MHz,內部部本振頻率可達118.7MHz,1


層板!看看電視機裏頭的電路板,高頻盒內一般最多就2 層板(還是一層的居多)它跑


多高的頻率 自己查查UHF 的範圍吧,記得保持冷靜因爲沒有什麼值得去驚訝的!再有


幾年前拆過一個GIGA 的遊戲機,音頻部分的PCB 是4 層板(獨立的小板),小日本的東西


元器件密密麻麻的,看看這個它又能是跑多高的頻率 況且現在數字電路的電平容差相


對於模擬電路的至少有一個數量級的差別.在高頻模擬電路下,多一塊覆銅可能就使電


路的性能下降或工作點異常,例如它可能使電感特性器件的Q 值下降,產生渦流耗損等.


很多時候增加PCB 的層數決不是單純因爲系統速度,你所說的60Mhz 也只是芯片內部的


系統時鐘, 難道你的IO 也要作爲時鐘源使用嗎 在ARM 中採用PLL 技術使得外部時


鍾可以下降到一個較低的水平,則可以抑制部分由時鐘電路產生的射頻干擾,有較好的


EMC,EMI 特性,一個合理的PCB layout 可能比盲目增加PCB 層數的方法提高系統的穩


定性來得更合理和有效!看你是想做精品還是想做產品或其他,這就要綜合多方因素考


慮了.


無可否認,增加PCB 的層數後比較容易的處理一些由於電源寄生干擾產生的問題,適當


配合layout 可以滿足一些速度(時序)要求苛刻的電路.由於現在元器件體積日漸小


型化,PCB 上元器件密度大,很多時候單面或雙面的layout 實現已經非常困難,增加PCB


層數是爲了更好的使設計變得合理和可靠.


第229 問:


Q:ARM 抗干擾能力怎樣,是否低壓器件一定比高電壓器件抗干擾能力弱 謝謝!


A:我們用自己的開發板打羣脈衝到最高都正常工作(程序沒有任何抗干擾措施).


第230 問:


Q:我剛剛設計完了一塊LPC2106 的電路板.在用EASYARM 仿真器通過JTAG 接口調試沒有能


夠使用,但是通過JTAG 口下載到FLASH 後上電覆位卻不能正常工作,手動復位也不行.


同樣的程序在購買的實驗板上完全可以使用.不知道是怎麼回事.我初步懷疑是復位電


路問題,但不知道怎麼解決.


A:問題解決了!只要將P0.14 上拉到高電平就可以了.


54


第231 問:


Q:VPB 是什麼意思 英文全稱是什麼


A:VPB (VLSI Peripheral Bus)


第232 問:


Q:請問大俠們,2104 怎樣與5V 的外設連接,多謝!!


下一個產品想用2104,可是用慣了51,不知怎樣與5V 外設連接,多謝!!


A:可以考慮使用3.3V 至5V 的緩衝器件如4245,最簡單的方法就串上個小電阻.


第233 問:


Q:請教大家:LPC2104 芯片中的PWM 有中斷功能,請問輸出置PWM 匹配通道的中斷標誌有


什麼意義,有什麼作用


A:舉個例子,如果 使用PWM 濾波 生成正弦波,有中斷,就方便很多!


55


第5 章 GPIO


第234 問:


Q:我是在LPC2119 與光隔相連時遇到的這個問題,以前用的片子IO 口都是5V 電壓,由於


2119 是


3.3V 所以和以前系統中採用的高速光耦相連時就涉及到兩個問題:


接受光耦送來的信號2119 可否承受


還有2119 輸出的信號能否驅動光耦


搞CAN 的朋友可否同樣遇到此問題,我覺得可以解決這個問題,但不敢肯定,我想通過


分析光耦內部結構可以解決這個問題,有經驗的朋友談談吧


A:可以將 CAN 引腳當成普通 IO 口對待,就不會存在疑惑了.


第235 問:


Q:LPC2119 的IO 口輸出電壓是多少,我在數據手冊上沒有找到


還有它的IO 口帶不帶上拉電阻


A:GPIO 輸出可輸出高電平電壓約爲3.3V,手冊上的Voh.


GPIO 作輸入時沒有內部上拉.


第236 問:


Q:請教:LPC2214 的P2,P3 作爲普通IO 時,怎麼設置輸入輸出方向 沒有找到它們的IODIR!


A:與P0 一樣,請下載工程模板,內有頭文件.


第237 問:


Q:請問:LPC2214 的GPIO 的管腳在輸入時沒有上拉,在輸出時有沒有上拉


好像在資料裏說的都沒有上拉.


AARM經典300問(轉貼) - Emily - Emily0.2,P0.3 是I2C 接口,是開漏輸出,所以要外接上拉電阻,其它GPIO 不用接.


第238 問:


Q:LPC2104 實驗板接上JTAG 線時,P0.22 變爲0 我在測試鍵盤時發現的,一拿下JTAG 插


頭,一切正常.


A:使用主JTAG 調試時,P0.22 爲ETM 跟蹤調試口,不能作GPIO 用.


第239 問:


Q:請教LPC2214 的P2/P3 口做I/O 口擴展而不是EMC 怎樣訪問 手冊上沒有找到,只有P0/P1


的訪問方法.


A:同P0 口一樣.請下載"EasyARM2100 開發套件快速入門和L...",裏面的頭文件有其地


址的定義.


56


第240 問:


Q:GPIO 哪些內部有上拉,哪些沒有


A:《ARM 微控制器基礎與實戰》中說的明白,都沒有上拉電阻的,不過是推輓輸出的,輸入


0,1 都沒問題,放心!


第241 問:


Q:因爲看到LPC2114 外圍電源用的是3.3V 供電,而我想用它的I2C 接口去控制後面用5V


供電的芯片,因此想問一下是否可以直接接上拉電阻和5V 相連 如果不能是不是隻能加


電平轉換了 謝謝!


A:可以.


第242 問:


Q:當外部有數據送到IO 口時,是不是通過讀寄存器IOPIN 就可以得到其IO 的當前狀態呢


A:你說的對,但是要將你要用的IO 口設爲GPIO(PINSEL0\PINSEL1)方式,並將其設爲輸


入方式(IODIR),就可以了.不過要是你用的IO 口不連續的話,要將輸入的管腳狀態處


理一下才是你要的字節或是字數據.我就是用這種方式擴展外部CAN 總線器件的.


第243 問:


Q:當用用GPIO 時,輸出電流是多大呢 急用!


A:數據手冊上有,Ioh = 4mA.


第244 問:


Q:請教:2104 的IOPIN 這個寄存器爲什麼老是一個值.


我的IO 不斷變化,他就是不變,不知爲什麼


A:我認爲可能是IODIR(管腳方向寄存器)和PINSEL0,PINSEL1(管腳功能寄存器)中的


一個寄存器沒設置好吧.


第245 問:


Q:可以直接把+5V RAM/FIFO 的數據線和2104 連接嗎(模擬總線時)


A:我做過外接RAM 的實驗,RAM 輸入的直接連,輸出到ARM 的串電阻.


第246 問:


Q:我用2104 的時候,怎麼設置IO 口,比如例子上有一個:#define LEDCON 0x00002000.


爲什麼設置P0.13 的時候要定義爲0x00002000,是怎麼計算的.謝了


A:右移13 位(1  6)/a_mode->ubps;


U0DLM = tmp >> 8;


U0DLL = tmp & 0xff;


70


tc = a_mode->data_bit;


tc |= a_mode->stop_bit;


tc |= a_mode->parity_bit;


U0LCR = tc;


VICIntSelect = 0x00000000; // 設置所有通道爲IRQ 中斷


VICVectCntl0 = 0x26; // UART0 中斷通道分配到IRQ slot 0,即優先級


最高


VICVectAddr0 = (int)IRQ_UART0; // 設置UART0 向量地址


VICIntEnable = 0x00000040; // 使能UART0 中斷


A:要在VECTOR.S 文件中打開IRQ 中斷.如"MSR CPSR_c, #0x5F"


第271 問:


Q:我用開發板自帶的一個程序Debug 調試,然後AXD 提示:


Warnning! interrupt vectors data is not correct!


Program you downloaded can not run freely!


我不知道其中中斷向量的地址是如何算出來的,也就是說程序中的異常向量所指向的位


置我不清楚.我買的《ARM 微控制器基礎與實戰》中提到這兒有一句話解釋了下面的程


序:在保留的異常向量位置填數據0xb9205f80,是爲了使向量表中所有的數據32 位累


加和爲0.(沒明白,0xb9205f80 是如何計算出來的!)


Vectors


LDR PC, ResetAddr


LDR PC, UndefinedAddr


LDR PC, SWI_Addr


LDR PC, PrefetchAddr


LDR PC, DataAbortAddr


DCD 0xb9205f80


LDR PC, [PC, #-0xff0]


LDR PC, FIQ_Addr


ResetAddr DCD Reset


UndefinedAddr DCD Undefined


SWI_Addr DCD SoftwareInterrupt


PrefetchAddr DCD PrefetchAbort


DataAbortAddr DCD DataAbort


Nouse DCD 0


IRQ_Addr DCD 0


FIQ_Addr DCD FIQ_Handler


A:從mem 窗口看這些地址是什麼數(32 位方式),然後加起來.


第272 問:


Q:我將光盤裏的EINT1 中的:


71


config,init.s,


LPC2106.h


target.c


target.h


vectors.s


eint1_led.c


加入項目中,設置的編譯環境爲:debug, Release DebugRel 中的R0 base 爲0x40000100;


Rw base 爲: 0x40003000;Image entry point 爲0x40000100.編譯通過,調試,f5 出


現第一個默認斷點,在全速執行,程序在while(1) ;循環,按k1 鍵led4 不閃爍,我


想是沒有進入中斷,但我不知道這是爲什麼,另外我將r0base 設爲0x40000100 是認爲


0x40000000 到0x40000100 之間要放置remanp 後的中斷向量表,不知道這樣做對否.


A:如果設置robase 設爲0x40000100,那麼你要把向量表的代碼複製到0x40000000,然後


再REMAP 操作.另處用我們的EasyJTAG 暫時不能單步調試中斷,否則會破壞VIC 的狀態.


請用先設置斷點,然後全速執行的方式調試.特別注意不能在0x18 處設置斷點(別的仿


真器也不能在這設置斷點,否則破壞VIC 的狀態).


第273 問:


Q:貴公司網站上提供的可固化的中斷程序中,是將中斷向量表先拷貝到0X40000000,再


REMAP 到FLASH 的底部(我的理解).我認爲既然是固化到FLASH 裏,把完成上述功能的


程序去掉不是也可以嗎


即下面的程序段:


; 實現REMAP 操作


REMAPS MOV R2,#0x40000000 ; 複製中斷向量代碼,設置目標地址


LDR R1,=Vectors ; 設置源地址


LDMIA R1!,{R3-R10} ; 共複製16 個字(64 字節)


STMIA R2!,{R3-R10}


LDMIA R1!,{R3-R10}


STMIA R2!,{R3-R10}


LDR R2,=MEMMAP ; REMAP 操作


MOV R1,#0x02


STR R1,[R2]


A:可以去掉,只是這樣做可以動態改變向量表.


第274 問:


Q:在《ARM 微控制器基礎與實踐》中的157 頁,在0X0000018 處加LDR PC,[PC,#-0XFF0]


指令,爲什麼就會將VICVectAddr 寄存器中保存的地址裝入PC


A:like this:


VICVectAddr = 0xFFFFF030


0x00000018+0x08-0xFF0 = 0xFFFFF030


therefore PC = [FFFFF030]


72


A:爲什麼不能進入中斷,init.s,target.c 都是貴公司的提供的啓動代碼!!!


向量的初始化爲:


Vectors


LDR PC, ResetAddr


LDR PC, UndefinedAddr


LDR PC, SWI_Addr


LDR PC, PrefetchAddr


LDR PC, DataAbortAddr


DCD 0xB8A06F58


LDR PC, [PC,#-0xff0]


LDR PC, FIQ_Addr


ResetAddr DCD Reset


UndefinedAddr DCD Undefined


SWI_Addr DCD SoftwareInterrupt


PrefetchAddr DCD PrefetchAbort


DataAbortAddr DCD DataAbort


Nouse DCD 0


IRQ_Addr DCD 0


FIQ_Addr DCD FIQ_Handler


Undefined


B Undefined


SoftwareInterrupt


B SoftwareInterrupt


PrefetchAbort


B PrefetchAbort


DataAbort


B DataAbort


FIQ_Handler


STMFD SP!, {R0-R3, LR}


BL FIQ_Exception


LDMFD SP!, {R0-R3, LR}


SUBS PC, LR, #4


主程序如下:


void __irq IRQ_Handler(void)


{


}


73


void __irq Time1_Handler(void)


{


}


int main(void)


{


.


.


.


T0PR = 99;


T0MCR = 0x03;


T0MR0 = 110592/2;


T0TCR = 0x03;


T1PR = 99;


T1MCR = 0x03;


T1MR0 = 70000;


T1TCR = 0x03;


T0TCR = 0x01;


T1TCR = 0x01;


VICIntSelect = 0x00000000;


VICIntEnable = 0x00000030;


VICVectCntl0 = 0x00000022;


VICVectAddr0 = (int)IRQ_Handler;


VICVectCntl1 = 0x0000002f;


VICVectAddr1 = (int)Time1_Handler;


while(1);


}


A:the Problem may be the channel selection


VICVectCntl0 = 0x00000022; may be VICVectCntl0 = 0x00000024;


VICVectCntl1 = 0x0000002f; may be VICVectCntl1 = 0x00000025;


第275 問:


Q:斷點如果設置在啓動時鐘節拍之後,在斷點處停頓後在繼續運行,程序運行就異常了,


這是什麼原因


A:不是不中斷,而是時鐘走過頭,還需很長時間才中斷.target.c 如下修改即可避免:


T0MCR = 0x01; 改爲T0MCR = 0x03;


函數 Timer0 改爲


void Timer0(void)


{


T0IR = 0x01;


// T0MR0 += (Fpclk / OS_TICKS_PER_SEC); // 刪除此句


74


VICVectAddr = 0; // 通知中斷控制器中斷結束


OSTimeTick();


}


第276 問:


Q:請教寄存器VICVectAddr 和VICVectAddr0~15 的使用區別,看文檔沒有明白,謝謝!


A:VICVectAddr 在發生中斷時,存放有服務程序的地址(來自VICDefVectAddr 或


VICVectAddr0~15);而VICVectAddr0~15 是存放各個向量中斷服務程序地址的寄存器,


當發生向量中斷時,相應的地址會自動裝載到VICVectAddr 中.


第277 問:


Q:在一個程序中同時編入兩個中斷時,不知道如何將一箇中斷的優先級設定高於另一箇中


斷.


例如:外部中斷和定時器的中斷.


A:VICVectCntl0~15 優先級遞減,參看實驗程序IRQ2_test.


第278 問:


Q:還有在AXD 環境下,單步執行怎麼起不了作用,會跳到void IRQ_Exception(void)裏面



A:有中斷時不能單步調試,否則VIC 工作異常.


第279 問:


Q:我想問向量表累加和是如何計算的


A:前8 個字的32 位機器碼相加.


第280 問:


Q:我把程序下載到FLASH 中發現MEMMAP 的值是01,可是我把程序下載到RAM 時發現MEMMAP


的值是0;不過程序都能運行.我這個程序沒有中斷,是不是如果我的程序中有中斷而


且在RAM 中運行時就必須修改MEMMAP 同時拷貝向量表到0x40000000 呢 如果程序中沒


有中斷並在RAM 中運行時就可以不管MEMMAP 的值了阿


A:是的.


第281 問:


Q:爲什麼在EINT1 中斷實驗程序中,中斷函數裏沒有VICVectAddr=0x00;是因爲它是非向


量中斷嗎


A:因爲它根本沒有使用VIC 的VICVectAddr 來判斷中斷服務程序入口.


75


第282 問:


Q:當我作向量IRQ 中斷實驗時,將EINT0 設爲最高優先級,EINT1 次之.我在IRQ_Eint1(void)


函數中加入一條while(1)指令,想作一下優先級差別的實驗.我先讓EINT1 中斷,這時


進入IRQ_Eint1(void)函數中,併產生死循環,然後我按下KEY3 想產生EINT0 中斷,結


果卻沒反應,我已經將EINT0 的優先級設成了最高,爲什麼不進入EINT0 中斷函數


A:有沒有允許中斷 進入中斷後處理器自動設置cpsr 中的中斷允許位,禁止中斷.


第283 問:


Q:執行FIQ 代碼時,操作系統在做什麼呢 當執行FIQ 中斷代碼時,需要注意什麼呢 要


對相關寄存器進行入棧嗎 那執行完了以後,又怎麼返回到OS 裏執行任務呢 FIQ 可不


可以調用OS 函數 IRQ 呢


A:1.FIQ 服務程序中斷了OS 啊.


2.FIQ 中斷服務不在OS 管理範圍內,所以不能訪問任何與OS 相關的函數及變量.


3.FIQ 其實就是普通的FIQ 中斷服務函數而已,與普通的一樣處理.


4.受OS 管理的IRQ 可以調用 OS 的系統功能函數.


第284 問:


Q:請問,在vectors.s 程序中中斷向量操作如下:


Vectors


LDR PC, ResetAddr


LDR PC, UndefinedAddr


LDR PC, SWI_Addr


LDR PC, PrefetchAddr


LDR PC, DataAbortAddr


DCD 0xb9205f80


LDR PC, [PC, #-0xff0]


LDR PC, FIQ_Addr


ResetAddr DCD Reset


UndefinedAddr DCD Undefined


SWI_Addr DCD SoftwareInterrupt


PrefetchAddr DCD PrefetchAbort


DataAbortAddr DCD DataAbort


Nouse DCD 0


IRQ_Addr DCD 0


FIQ_Addr DCD FIQ_Handler


;未定義指令


Undefined


B Undefined


;軟中斷


SoftwareInterrupt


B SoftwareInterrupt


PrefetchAbort


76


B PrefetchAbort


;取數據中止


DataAbort


B DataAbort


;快速中斷


FIQ_Handler


STMFD SP!, {R0-R3, LR}


BL FIQ_Exception


LDMFD SP!, {R0-R3, LR}


SUBS PC, LR, #4


現我將它改爲


Vectors


LDR PC, =Reset


LDR PC, =Undefined


LDR PC, =SoftwareInterrupt


LDR PC, =PrefetchAbort


LDR PC, =DataAbort


DCD 0xb9205f80


LDR PC, [PC, #-0xff0]


LDR PC, =FIQ_Handler


;未定義指令


Undefined


B Undefined


;軟中斷


SoftwareInterrupt


B SoftwareInterrupt


PrefetchAbort


B PrefetchAbort


;取數據中止


DataAbort


B DataAbort


;快速中斷


FIQ_Handler


STMFD SP!, {R0-R3, LR}


BL FIQ_Exception


LDMFD SP!, {R0-R3, LR}


SUBS PC, LR, #4


程序編譯可以通過,用AXD 調試時報告不能自由運行,可以仿真運行.


按我的理解DCD 前面爲地址(也就是指針),DCD 後面爲4 個字節的內容(指針的值),


LDR PC,ResetAddr


LDR PC,=Reset,


都是採用間接尋址,也就是將Reset 的地址放進PC,爲什麼"LDR PC, ResetAddr"地


址從中間轉一道就對了而"LDR PC, =Reset"就不對,既然不對爲什麼還可以仿真,而


77


脫機運行就不行


A:因爲異常向量表累加和不爲0.詳細看一看5.1.3 節或6.3 節.我記得以前也有一個類


似的帖子


可以參考.


第285 問:


Q:是不是FIQ 與IRQ 的使用上沒有什麼區別


FIQ 自己獨有的寄存器有什麼用


我是否可以把INT1,UART1 等中斷設爲FIQ


FIQ 的中斷服務程序應該定位到什麼位置


A:沒有本質的區別.


FIQ 擁有獨立的R8_fiq~R12_fiq,FIQ 中斷時,其它模式相應的寄存器就可不入棧,從


而加快FIQ 的處理.多箇中斷源共用還不如單獨用IRQ.因爲FIQ 比較適合在人命關天


的情況下用.


第286 問:


Q:這是VECTORS.s 中的一段,裏面的REMAP 操作都做了些什麼 好像是保護一類的操作.


REMAP 和MEMMAP 各是什麼含義 如果我要同時使用兩個外部中斷,應當怎樣寫這一段


REMAPS MOV R2,#0x40000000


LDR R1,=Vectors


LDMIA R1!,{R3-R10}


STMIA R2!,{R3-R10}


LDMIA R1!,{R3-R10}


STMIA R2!,{R3-R10}


LDR R2,=MEMMAP


MOV R1,#0x02


STR R1,[R2]


MSR CPSR_c, #0x1f


MOV PC, R0


A:REMAP 是重映射的意思,MEMMAP 是存儲器映射控制寄存器.


MEMMAP = 0b01,不映射,程序由FLASH 開始.


MEMMAP = 0b10,程序從RAM 開始,如果你的程序在RAM 中,必須使用這種方式.


如同時使用兩個中斷,這一段也不用改.


第287 問:


Q:特定的異常出現時,處理器進入相應的異常模式.如出現IRQ 就進入IRQ 模式,那出現


什麼情況進入管理模式呢


A:復位或SWI 中斷.


78


第288 問:


Q:請問什麼時候需要通過軟件中斷進入管理模式


A:如果你的程序是在用戶模式下運行,那就可以通過軟中斷進入特權模式,修改CPSR 寄存


器.如開關IRQ 中斷(CPSR 的I 位).


第289 問:


Q:軟件中斷是用軟件置位的方法產生中斷請求,比如定時器0 中斷請求.用軟件中斷的方


法可以產生IRQ, FIQ 中斷,對嗎


A:VIC 中的軟件中斷是這樣,而swi 產生的異常,英文也爲軟件中斷,它是不一樣的.


第290 問:


Q:我現在在看ads 編譯器文檔中的swi 部分,我理解軟中斷就是一種預期發生的中斷而一


般中斷是不可預期的,對嗎


A:可以這樣說.


第291 問:


Q:爲什麼以下的程序進不了中斷


/**********************************************************


*修改說明 加中斷


*修改目標 我是想每發一個字符就讓LED 變換一次,現在結果是


* 仍正常發送字符,但沒有中斷效果,爲什麼呢


* 哪位幫看看!先謝謝了!


**********************************************************/


#include "config.h"


#define HC595_CS 0x00000100


#define LEDCON 0x00000400 // LED1~LED4 設置爲輸出


void DelayNS(uint32 dly)


{


uint32 i;


for(; dly > 0; dly--)


for(i = 0; i < 50000; i++);


}


/**************************************************************************


*初始化SPI 接口


**************************************************************************/


void MSpiIni()


{


SPI_SPCCR = 0x52; // 設置SPI 時鐘分頻


SPI_SPCR = 0xB0; // 配置MSTR = 1 CPOL = 1 CPHA = 0 LSBF = 0


}

轉自:http://bbs.ednchina.com/BLOG_ARTICLE_270783.HTM

/***********************

發佈了14 篇原創文章 · 獲贊 4 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章