版本 a5945927ff000d6af9c9d81eb3bc2c4657c9f785
Changes from a5945927ff000d6af9c9d81eb3bc2c4657c9f785 to 10c3bc156b173c164c445a9186b3464feebecf8c
---
title: Flash
categories: STM32F4
...
1.STM32F407VG 硬體介紹
=============
- STM32F407VG版子外觀與模組如下圖所示:
.. image:: /STM32F4_2.jpg
- 上方USB Programmer/Debugger為ST-Link
- 石英晶體震盪器(Crystal),可參考(http://zh.wikipedia.org/zh-tw/%E7%9F%B3%E8%8B%B1%E6%99%B6%E4%BD%93%E8%B0%90%E6%8C%AF%E5%99%A8)
- 中央的晶片為ARM® Cortex™-M4F core with embedded Flash and SRAM,其內部結構如Figure 5所示。
- 三軸加速度感知器(3-axis Accelerometer)
- 音頻數位類比轉換(Audio DAC)
- 麥克風晶片(Chip Microphone)
- USB On The Go (http://forum.slime.com.tw/thread180246.html)
- 音效輸出(Audio Jack)
- 此外,板子上有兩顆按鈕,藍色按鈕為User Button,黑色按鈕為Reset。
.. image:: /block_diag_1.JPG
.. image:: /block_diag_2.JPG
2.Software STM32F4 Lib
============
.. image:: /lib_1.JPG
3.debug gdb
============
- gdb指令介紹 :
--------------
檔案處理
========
- file a.elf 載入可執行檔a.elf
- path 告訴gdb obj code在那
- directory 告訴gdb source code在那裡
SHELL
=====
- shell ls 就會執行ls了
流程控制
========
- break 設定中斷點
::
break 在目前位置設中斷點
break 100 在100行中斷
break main 在main()中斷
break +100 目前位置+100行中斷
break *0x08048123 在這位址中斷
break file.c:100 因為如果是多個c檔案時指定file.c
tbreak 同break的寫法 不過中斷一次後 此中斷點就失效
break 100 if (var == 5) 條件中斷: 如果var=5就在line 100中斷
- delete 清除中斷點
::
delete 1 刪除編號為1的中斷點
delete 刪除所有中斷點
- disable 暫時使中斷失效
- enable 把失效的中斷恢復
::
disable 3 暫時使3號中斷點沒作用 後面是中斷點流水編號
enable 2 使2號中斷點作用 後面是中斷點流水編號
condition 進一步設中斷點的條件 如果條件為true則中斷
::
condition 3 (var > 3) 設3號中斷點的條件 如果條件為true則中斷
condition 3 清除3號中斷點的條件
- commands 如果中斷發生了則執行commands與end中的一連串gdb命令
::
break 100 在第100行中斷並且執行command...end中的gdb命令
commands
p/x var
end
- run 開始跑程式
- continue 中斷後繼續跑
- next 往下一步: 如果有副程式 執行完整個副程式
- step 往下一步: 如果有副程式 追進副程式
- until 跳離一個while for迴圈
- nexti 往下一步CPU組語的指令(Instruction)執行完整個副程式
- stepi 往下一步CPU組語的指令(Instruction)追進副程式
訊息觀看與設定
==============
- list 看原始碼
::
list x 從第x行的source code印出,x不寫則印出目前中斷點前後的code
list *addr 秀出addr所在source code的行
可以先用info program找出目前PC的值
再用list *addr
search REGEXP 在目前source code用正規表示式搜尋
- whatis var 告訴我var的資料型別是啥 int, char or double
- ptype var 告訴我var的資料型別是啥 這用來看struct用的
- set 設定gdb, 系統的控制變數值(這些變數不是program內的)
::
set listsize xx 設定要看xx行source code
set $pc xx 把PC設到 xx
set convenience可以自己設變數
程式變數值(data)處理
====================
- print var 看var的值
- print &var 印出var的位址
- print *var 印出位於位址var的值
- display var display會每次step, next時都會印出值來, print只印一次
- print (var=value) 設var的值為value
- p/x
::
p/x 表示印16進位值
p/u 表示unsigned digit
p/d signed digit
p/t 二進位值
- x/3uh 0x8000000 印出記憶體
::
其中
3表示看3個 (0x8000000 - 0x8000003)
u unsigned digit(跟上面p命令一樣意義)
h halfword就是2bytes(bhwg分別是1248bytes)
- Debug設定(TCP/IP) :
---------------------
.. image:: /gdb_1.JPG
- Debug流程主要為 :
(1) 在Target(MCU)端開啟App與gdbserver。如果已經將程式燒入flash, 要透過MCU內建的gdb server來debug, 則必須使用st-util:
::
st-util -p 3333
(2) 開啟Host端的gdb:
::
arm-none-eabi-gdb your_elf_image.elf
(3) 連接到Target端的gdbserver,如
::
target extended-remote : 3333
(4) 當應用程式就緒後,可指定中斷點,接著按c,就會在指定的中斷點停下來。
- 可參考(http://www.codeproject.com/Articles/14983/Remote-Debugging-using-GDB)
4.Flash 簡介
============
- 簡介
------
- 快閃記憶體(Flash Memory、閃存),主要用於一般姓資料儲存,以及在電腦及其他數位產品間交換傳輸資料。如記憶卡、隨身碟等。快閃記憶體是一種特殊的、以大區塊抹寫的EEPROM(電子抹除式可複寫唯讀記憶體)。
- 快閃記憶體晶片的低階介面通常與透過支援外界的定址匯流排行隨機存取的DRAM、ROM、EEPROM等記憶體不同。 NOR Flash本身為讀取操作(支援隨機存取)提供外部定址匯流排;至於解鎖、抹除與寫入則須以區塊-區塊(Block-by-block)的方式進行,典型的區塊大小為64、128或256位元組。NAND Flash所有的動作都必須以區塊性基礎(Block-wise fashion)執行,包含讀、寫、解鎖與抹除。
- NOR Flash Structure :
.. image:: /NOR flash.JPG
- NAND Flash Structure :
.. image:: /NAND flash.JPG
**關於NAND Flash 與 NOR Flash的比較可參考**(http://www.8051faq.com.cn/manager/download/20077633203664115781250.PDF)。
- Flash 操作
-------------
在做抹除與寫入動作之前,必須先設定Flash control register(FLASH_CR),然而在Reset之後,FLASH_CR是不可寫入的。因此必須透過以下方法解鎖:
1. 在Flash key register(FLASH_KEYR)中寫入0x45670123。
2. 在Flash key register(FLASH_KEYR)中寫入0xCDEF89AB。
**必須連續執行1與2才會解鎖**
此外,FLASH_CR在FLASH_SR的BSY值為1時是同樣不可寫入的。
**抹除步驟:**
- **區塊抹除(Sector Erase)**:
1. 檢查Flash status register(FLASH_SR)中BSY(Busy) bit是否為0。(0代表目前沒有其他的Flash操作,1代表有其他Flash操作正在進行中)
2. 設定FLASH_CR中SER(Sector Erase) bit告知啟用區塊抹除,並設定SNB(Sector number) bit告知欲抹除的區塊。
::
0000 sector 0
0001 sector 1
...
1011 sector 11
不得超過此範圍。
3. 設定FLASH_CR中的STRT(Start) bit。
4. 等待FLASH_SR中的BSY清空。
- **大量抹除(Mass Erase)**:
1. 檢查FLASH_SR中BSY bit是否為0。
2. 設定FLASH_CR中的MER(Mass Erase) bit。
3. 設定FLASH_CR中的STRT bit。
4. 等待FLASH_SR中的BSY清空。
**寫入步驟:**
1. 檢查FLASH_SR中BSY bit是否為0。
2. 設定FLASH_CR中的PG(Programming)。
3. 在指定的位置(主要記憶體區塊或OTP區塊)執行資料寫入的動作。(關於記憶體區塊將於下一節介紹)
- 以下是各種型態單次寫入時所需的大小
- **Byte : x8**
- **Half-word : x16**
- **Word : x32**
- **Double-word : x64**
- 而寫入之前必須於FLASH_CR中指定對應的PSIZE,如下表所示:
.. image:: /parallelism.JPG
**當bit寫入由1寫成0時,不需要先Erase;但若將0寫為1時,則需要先Erase才能寫。**
4. 等待FLASH_SR中的BSY清空。
5.flash 記憶體架構介紹
============
.. image:: /Flash_system_architecture.JPG
圖中一些縮寫的解釋如下:
- I-Code bus : Instruction bus.這條bus由Cortex-M4F連至BusMatrix,核心透過這個bus取出指令。
- D-Code bus : Data bus.這條bus由Cortex-M4F 與 64-Kbyte CCM data RAM 連至BusMatrix,核心透過這個bus讀取字母(literal)與除錯。
- AHB : Advanced High-performance Bus.
- APB : Advanced Peripheral Bus.
關於AHB與APB差異可參考(http://www.differencebetween.net/technology/difference-between-ahb-and-apb/)
- DMA : Direct Memory Access. DMA提供周邊裝置與記憶體、記憶體與記憶體間高速的傳輸,而不須經由CPU的動作。
- CCM : Core Coupled Memory.給core專用的全速64KB RAM,在沒有經過BusMatrix的情況下與core直接連結。
- FLITF : Flash memory interface.
Bus Matrix:
.. image:: /bus_matrix.JPG
Flash模組的組成如下:
- Main memory : 4個16Kbytes Sector、1個64Kbytes Sector及7個128Kbytes Sector,一共1024Kbytes.
- System memory : bootloader code 放置的地方,30Kbytes.
- OTP (One-Time Programmable) : 一次性寫入的空間,共528Kbytes,可參考(http://forum.eepw.com.cn/thread/120354/1)
- Option byte : 用來設定讀寫保護、電壓level、軟硬體看門狗與Standby or Stop模式下的重置,共16Kbytes.
.. image:: /flash module organization.JPG
6.flash register
============
7.example(範例流程)
============
- 7.1 FLASH_UNLOCK
- 7.2 GREEN LED ON
::
FLASH_Unlock();
STM_EVAL_LEDOn(LED4);
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
- 7.3 WRITE FROM SECTOR 2 TO SECTOR 5 AS "12345678"
- 7.4 BLUE LED ON
- 7.5 FINISHED WRITE PROCESS
- 7.6 BLUE LED OFF
::
while (Address < FLASH_USER_END_ADDR){
STM_EVAL_LEDOn(LED6);
if (FLASH_ProgramWord(Address, DATA_32) == FLASH_COMPLETE) Address = Address + 4;
else{
/* Error occurred while writing data in Flash memory.
User can add here some code to deal with this error */
STM_EVAL_LEDOn(LED3);
}
STM_EVAL_LEDOff(LED6);
}
- 7.7 FLASH_LOCK
- 7.8 GREEN LED OFF
::
FLASH_Lock();
STM_EVAL_LEDOff(LED4);
8.ref
============