nor flash的一般操作与分析
是現在市場上兩種主要的非易失閃存技術。Intel于1988年首先開發出NOR Flash 技術,徹底改變了原先由EPROM(Electrically Programmable Read-Only-Memory電可編程序只讀存儲器)和EEPROM(電可擦只讀存儲器Electrically Erasable Programmable Read - Only Memory)一統天下的局面。緊接著,1989年,東芝公司發表了NAND Flash 結構,強調降低每比特的成本,有更高的性能,并且像磁盤一樣可以通過接口輕松升級。NOR Flash 的特點是芯片內執行(XIP ,eXecute In Place),這樣應用程序可以直接在Flash閃存內運行,不必再把代碼讀到系統RAM。
這樣我們知道程序能直接在norlash執行的原因在XIP
那:什么是XIP?工作原理又是怎么樣的?
XIP eXecute In Place
eXecute In Place,即芯片內執行,指應用程序可以直接在flash閃存內運行,不必再把代碼讀到系統RAM中。flash內執行是指nor flash 不需要初始化,可以直接在flash內執行代碼。但往往只執行部分代碼,比如初始化RAM.
(注:片內執行不是說程序在存儲器內執行哦,CPU的基本功能就是取指、譯碼和執行。norflash能在芯片內執行,就是指CPU的取指模塊能夠直接從norflash中把指令取出來,供后面的譯碼和執行模塊使用)
--------------------- 本文來自 yjzh_td 的CSDN 博客 ,全文地址請點擊:https://blog.csdn.net/yjzh_td/article/details/72870044?utm_source=copy
轉:https://blog.csdn.net/thisway_diy/article/details/79397638
Nor Flash的連接線有地址線,數據線,片選信號讀寫信號等,Nor Flash的接口屬于內存類接口,Nor Flash可以向內存一樣讀,但是不能像內存一樣寫,需要做一些特殊的操作才能進行寫操作,讀只需像內存一樣讀很簡單。
Nor Flash原理圖如圖:
Flash介紹
常用的Flash類型有Nor Flash和NAND Flash兩種。
Nor Flash由Intel公司在1988年發明,以替代當時在市場上占據主要地位的EPROM和E2PROM。NAND Flash由Toshiba公司在1989年發明。兩者的主要差別如下表:
| - | Nor | NAND |
|---|---|---|
| XIP(代碼可以直接運行) | Yes | no |
| 性能(擦除) | 非常慢(5s) | 快(3ms) |
| 性能(寫) | 慢 | 快 |
| 性能(讀) | 快 | 快 |
| 可靠性 | 較高,位反轉的比例小于NAND Flash的10% | 比較低,位反轉比較常見,必須有校驗措施,比如TNR必須有壞塊管理措施 |
| 可擦除次數 | 10000 ~ 100000 | 100000 ~ 1000000 |
| 生命周期 | 低于NAND Flash的10% | 是Nor Flash的10倍以上 |
| 接口 | 與RAM接口相同 | I/O接口 |
| 易用性 | 容易 | 復雜 |
| 主要用途 | 常用于保存代碼和關鍵數 | 用于保存數據 |
| 價格 | 高 | 低 |
Nor Flash支持XIP,即代碼可以直接在Nor Flash上執行,無需復制到內存中。這是由于NorF lash的接口與RAM完全相同,可以隨機訪問任意地址的數據。Nor Flash進行讀操作的效率非常高,但是擦除和寫操作的效率很低,另外,Nor Flash的容量一般比較小。NAND Flash進行擦除和寫操作的效率更高,并且容量更大。一般而言,Nor Flash用于存儲程序,NAND Flash用于存儲數據。基于NAND Flash的設備通常也要搭配Nor Flash以存儲程字。
Flash存儲器件由擦除單元(也稱為塊)組成,當要寫某個塊時,需要確保這個塊己經
被擦除。Nor Flash的塊大小范圍為64kB、128kB:NAND Flash的塊大小范圍為8kB,64kB,擦/寫一個Nor Flash塊需4s,而擦/寫一個NAND Flash塊僅需2ms。Nor Flash的塊太大,不僅增加了擦寫時間,對于給定的寫操作,Nor Flash也需要更多的擦除操作——特別是小文件,比如一個文件只有IkB,但是為了保存它卻需要擦除人小為64kB—128kB的Nor Flash塊。
Nor Flash的接口與RAM完全相同,可以隨意訪問任意地址的數據。而NAND Flash的
接口僅僅包含幾個I/O引腳,需要串行地訪問。NAND Flash一般以512字節為單位進行讀寫。這使得Nor Flash適合于運行程序,而NAND Flash更適合于存儲數據。
容量相同的情況下,NAND Flash的體積更小,對于空間有嚴格要求的系統,NAND Flash可以節省更多空間。市場上Nor Flash的容量通常為IMB~4MB(也有32MB的Nor Flash),NAND Flash的容量為8MB~512MB。容量的差別也使得Nor Flash多用于存儲程序,NAND Flash多用于存儲數據。
對于Flash存儲器件的可靠性需要考慮3點:位反轉、壞塊和可擦除次數。所有Flash器件都遭遇位反轉的問題:由于Flash固有的電器特性,在讀寫數據過程中,偶然會產生一位或幾位數據錯誤(這種概率很低),而NAND Flash出現的概率遠大于Nor Flash,當位反轉發生在關鍵的代碼、數據上時,有可能導致系統崩潰。當僅僅是報告位反轉,重新讀取即可:如果確實發生了位反轉,則必須有相應的錯誤檢測/恢復措施。在NAND Flash上發生位反轉的概率史高,推薦使用EDC/ECC進行錯誤檢測和恢復。NAND Flash上面會有壞塊隨機分布在使用前需要將壞塊掃描出來,確保不再使用它們,否則會使產品含有嚴重的故障。NAND Flash每塊的可擦除次數通常在100000次左右,是Nor Flash的10倍。另外,因為NAND Flash的塊大小通常是NorF lash的1/8,所以NAND Flash的壽命遠遠超過Nor Flash。
嵌入式Linux對Nor、NAND Flash的軟件支持都很成熟。在Nor Flash上常用jffs2文
件系統,而在NAND Flash常用yaffs文件系統。在更底層,有MTD驅動程序實現對它們的讀、寫、擦除操仵,它也實現了EDC/ECC校驗。
Nor Flash的操作
下面我們使用u-boot來體驗Nor Flash的操作(開發板設置Nor啟動,進入u-boot)。
1).使用OpenJTAG燒寫UBOOT到Nor Flash
那么我們怎么用u-boot來操作呢?
Nor Flash手冊里會有一個命令的表格,如圖:
下面簡單的舉一些例子:
復位(reset):往任何一個地址寫入F0。
讀ID(ReadSiliconID):很多的Nor Flash可以配置成位寬16bit(Word),位寬8bit(Byte)。對于我們使用的jz2440開發板使用是位寬16bit,怎樣讀ID呢?
根據前面得圖可知,往Nor Flash的555地址寫AA,再往2AA的地址寫入55,再往555的地址寫入90,然后就可以讀ADI地址,就可以讀到DDI數據了。
實例1
讀數據:
在u-boot上執行:md.b0
結果(和我們燒進去的數據完全一樣):
00000000:170000ea14f09fe514f09fe514f09fe5................
00000010:14f09fe514f09fe514f09fe514f09fe5................
00000020:6001f833c001f8332002f8337002f833`..3...3..3...3
00000030:e002f8330004f8332004f833efbeadde...3...3..3....
- 1
- 2
- 3
- 4
可以得出結論:u-boot可以像讀內存一樣來讀nor flash
實例2
讀ID(參考Nor手冊)
- 往地址555H寫入AAH(解鎖)
- 往地址2AAH寫入55H(解鎖)
- 往地址555H寫入90H(命令)
- 讀0地址得到廠家ID(C2H)
- 讀1地址得到設備ID(22DAH或225BH)
- 退出讀ID狀態:給任意地址寫F0H就可以了。
下圖為2440和Nor Flash的簡易連接圖:
2440的A1接到Nor的A0所以2440發出的地址是,Nor Flash收到的地址左移一位。比如:2440發出(555H<<1)地址,Nor Flash才能收到555H這個地址。
下面對在Nor Flash的操作,2440的操作,U-BOOT上的操作進行比較,如下表:
| Nor Flash的操作 | 2440的操作 | U-BOOT上的操作 |
|---|---|---|
| 往地址555H寫入AAH(解鎖) | 往地址AAAH寫入AAH(解鎖) | mw.waaaaa |
| 往地址2AAH寫入55H(解鎖) | 往地址554H寫入55H(解鎖) | mw.w 554 55 |
| 往地址555H寫入90H(命令) | 往地址AAAH寫入90H(命令) | mw.w aaa 90 |
| 讀0地址得到廠家ID(C2H) | 讀0地址得到廠家ID(C2H) | md.w 0 1 (1:表示都一次) |
| 讀1地址得到設備ID(22DAH或225BH) | 讀2地址得到設備ID(22DAH或225BH) | md.w 2 1 (1:表示都一次) |
| 退出讀ID狀態:給任意地址寫F0H就可以了 | 退出讀ID狀態:給任意地址寫F0H就可以了 | mw.w 0 f0 |
1).當執行過
md.w 0 1
結果(輸出廠家ID):
00000000:00c2..(00c2就是廠家ID)
2).當執行過
md.w 2 1
結果(輸出設備ID):
00000002:2249I”(2249就是設備ID)
3).當執行
mw.w 0 f0
就退出讀ID的狀態,
執行:
md.b0
結果:
00000000:17.(讀到的就是Nor Flash地址·0的數據)
Nor Flash的兩種規范
通常內核里面要識別一個 Nor Flash 有兩種方法:
一種是 jedec 探測,就是在內核里面事先定義一個數組,該數組里面放有不同廠家各個芯片的一些參數,探測的時候將 flash 的 ID 和數組里面的 ID 一一比較,如果發現相同的,就使用該數組的參數。
jedec 探測的優點就是簡單,缺點是如果內核要支持的 flash 種類很多,這個數組就會很龐大。內核里面用 jedec 探測一個芯片時,是先通過發命令來獲取 flash 的 ID,然后和數組比較,但是 flash.c 中連 ID 都是自己通過宏配置的。
一種是 CFI(common flash interface)探測,就是直接發各種命令來讀取芯片的信息,比如 ID、容量等,芯片本身就包含了電壓有多大,容量有有多少等信息。
下面對在Nor Flash上操作,2440上操作,U-BOOT上操作cfi 探測(讀取芯片信息)進行比較參考芯片手冊。
| Nor Flash上操作cfi | 2440上操作cfi | U-BOOT上操作cfi |
|---|---|---|
| 往55H地址寫入98H | 往AAH地址寫入98H | mw.w aa 98 |
| 讀地址10H得到0051 | 讀地址20H得到0051 | md.w 20 1 |
| 讀地址11H得到0052 | 讀地址22H得到0052 | md.w 22 1 |
| 讀地址12H得到0059 | 讀地址24H得到0059 | md.w 24 1 |
| 讀地址27H得到容量 | 讀地址4EH得到容量 | md.w 4e 1 |
Nor Flash寫數據
我們在Nor Flash的10000的地址讀數據,
md.w 100000 1
結果:
00100000:ffff..
在Nor flash的10000的地址寫數據下0x1234,
mw.w 100000 1234
然后在這個地址讀數據,
md.w 100000 1
結果:
00100000:ffff(這個地址上的數據沒有被修改,寫操作無效)。
怎樣把數據寫進Nor Flash進去呢?
寫數據之前必須保證,要寫的地址是擦除的。
下面是Nor Flash的寫操作,如下表:
| Nor Flash上操作寫操作 | 2440上操作寫操作 | U-BOOT上操作寫操作 |
|---|---|---|
| 往地址555H寫AAH(解鎖) | 往地址AAAH寫AAH(解鎖) | mw.w aaa aa |
| 往地址2AAH寫55H(解鎖) | 往地址554H寫55H(解鎖) | mw.w 554 55 |
| 往地址555H寫A0H | 往地址AAAH寫A0H | mw.w aaa a0 |
| 往地址PA寫PD | 往地址0x100000寫1234h | mw.w 100000 1234 |
1).U-BOOT執行完上述指令后,0x1234,就被寫到0x100000地址處,
執行:
md.w1000001
結果(1234被寫進去):
00100000:1234 4
從這里可以看出來U-BOOT的操作不是很復雜。
2).我們再次往0x100000地址處,寫入0x5678,執行如下命令:
mw.w aaa aa
mw.w 554 55
mw.w aaa a0
mw.w 100000 5678
查看0x100000地址處的數據
md.w 100000 1
結果:
00100000:12300.
0x100000地址處的數據不是0x5678,寫操作失敗,失敗的原因是,原來的數據已經是0x1234不是全0xffff,再次寫操作失敗,(Nor Flash只有先擦出,才能燒寫)。
先擦除(參考Nor Flash芯片手冊)
Nor Flash操作 u-boot操作
555H AAH mw.w aaa aa
2AAH 55H mw.w 554 55
555H 80H mw.w aaa 80
555H AAH mw.w aaa aa
2AAH 55H mw.w 554 55
SA 30H //往扇區地址寫入30 mw.w 100000 30
執行完上述指令后測試
執行:
md.w 100000 1
結果:
00100000:ffff..
已被擦除,這個時候再次燒寫就不會有問題了。
再燒寫
mw.w aaa aa
mw.w 554 55
mw.w aaa a0
mw.w 100000 5678
測試燒寫結果
執行:
md.w 100000 1
結果:
00100000:5678 xV
數據被燒寫進去,燒寫成功。
總結:我們燒寫時,如果上面的數據,不是0ffff,沒有被擦除過,我們就要先擦出,擦除完后,才可以燒寫,擦除燒寫的命令可以從芯片手冊里面獲得。
= 第002節Nor Flash編程識別 =
本節實例的目的目的:識別nor flash
發送命令函數
nor_cmd函數代碼如下,往NOR Flash某個地址發送指令,
16
17 /* offset是基于NOR的角度看到 */
18 void nor_cmd(unsigned int offset, unsigned int cmd)
19 {
20 nor_write_word(NOR_FLASH_BASE, offset, cmd);
21 }
- 1
- 2
- 3
- 4
- 5
- 6
讀取函數
nor_read_word函數是從NOR Flash 讀取兩個字節(本開發板位寬16bit),讀取數據的地址,是基于2440,所以讀取NOR Flash某個地址上的數據時,需要把NOR Flash對應的地址左移一位(地址乘以2)。
23 unsigned int nor_read_word(unsigned int base, unsigned int offset)
24 {
25 volatile unsigned short *p = (volatile unsigned short *)(base + (offset << 1));
26 return *p;
27 }
- 1
- 2
- 3
- 4
- 5
讀取地址中的數據
向nor_dat函數中寫入NOR Flash某個地址,返回該NOR Flash地址上的數據。
29 unsigned int nor_dat(unsigned int offset)
30 {
31 return nor_read_word(NOR_FLASH_BASE, offset);
32 }
- 1
- 2
- 3
- 4
進入NOR FLASH的CFI模式,讀取各類信息
do_scan_nor_flash函數代碼如下,該函數的功能:進入CFI模式讀取NOR Flash中的廠家ID,設備ID,容量等信息。
50/* 進入NOR FLASH的CFI模式
51 * 讀取各類信息
52 */
53 void do_scan_nor_flash(void)
54 {
55 char str[4];
56 unsigned int size;
57 int regions, i;
58 int region_info_base;
59 int block_addr, blocks, block_size, j;
60 int cnt;
61
62 int vendor, device;
63
64 /* 打印廠家ID、設備ID */
65 nor_cmd(0x555, 0xaa); /* 解鎖 */
66 nor_cmd(0x2aa, 0x55);
67 nor_cmd(0x555, 0x90); /* read id */
68 vendor = nor_dat(0);
69 device = nor_dat(1);
70 nor_cmd(0, 0xf0); /* reset */
71
72 nor_cmd(0x55, 0x98); /* 進入cfi模式 */
073
74 str[0] = nor_dat(0x10);
75 str[1] = nor_dat(0x11);
76 str[2] = nor_dat(0x12);
77 str[3] = '\0';
78 printf("str = %s", str);
79
80 /* 打印容量 */
81 size = 1<<(nor_dat(0x27));
82 printf("v=0x%x,d=0x%x,s=0x%x,%dM",vendor,device,size,size/(1024*1024));
83
84 /* 打印各個扇區的起始地址 */
85 /* 名詞解釋:
86 * erase block region : 里面含有1個或多個block, 它們的大小一樣
87 * 一個nor flash含有1個或多個region
88 * 一個region含有1個或多個block(扇區)
89
90 * Erase block region information:
91 * 前2字節+1 : 表示該region有多少個block
92 * 后2字節*256 : 表示block的大小
93 */
94
95 regions = nor_dat(0x2c);
96 region_info_base = 0x2d;
97 block_addr = 0;
98 printf("Block/Sector start Address:");
99 cnt = 0;
100 for (i = 0; i < regions; i++)
101 {
102 blocks = 1 + nor_dat(region_info_base) + (nor_dat(region_info_base+1)<<8);
103 block_size=256*(nor_dat(region_info_base+2)+(nor_dat(region_info_base+3)<<8));
104 region_info_base += 4;
105
106 //printf("…………");
107
108 for (j = 0; j < blocks; j++)
109 {
110 /* 打印每個block的起始地址 */
111 //printf("0x%08x ", block_addr);
112 printHex(block_addr);
113 putchar(' ');
114 cnt++;
115 block_addr += block_size;
116 if (cnt % 5 == 0)
117 printf("\n\r");
118 }
119 }
120 printf("\n\r");
121 /* 退出CFI模式 */
122 nor_cmd(0, 0xf0);
123 }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
第65,66行 這兩步是解鎖,解鎖之后就進入讀ID狀態,就可以讀取廠家和設備ID了。
第68行 是把讀取到的廠家ID的值,復制給vendor變量。
第69行 是把讀取到的設備ID的值,復制給device變量。
第70行 退出讀ID狀態: 給任意地址寫F0H。
第72行,往地址0x55地址寫入數據0x98,是進入cfi模式。
第74,75,76行是讀取NOR Flash地址0x10,0x11,x012中的字符,賦值給字符串str。
第81行,根據芯片手冊可知道,讀取NOR Flash地址0x27處的數據,得到的是NOR Flash容量大小2的冪數,所以把1左移讀取到的數據,就可得到NOR Flash的容量。
第95行讀取NOR Flash地址0x2c地址中的數據,可以得到NOR Flash中有多少region。
第102行根據Erase block region information:的信息可以知道讀取[2E,2D]這兩個字節的地址+1,可以得到一個region有多少block(參考芯片手冊)。代碼中的region_info_base變量的值是0x2d,0x2d是前兩個字節中的低字節,0x2e是前兩個字節中的高字節,所以需要左移8位,然后加上1就得到了一個region有多少block.。
第103行參考芯片手冊,讀取[30,2F]這兩個字節地址,然后乘上256就可以得到一個塊的大小。
第104行,地址加4,讀取下一個region有多少block和每個block的大小。
第112,115行,由于NOR Flash的基地址是0,所以第一個block的首地址是0,下一個block的首地址,就是上一個block的首地址加上block的大小。
第112行往0地址寫入0xf0,退出CFI模式。
Nor Flash的測試
nor_flash_test函數通過switch語句,分別處理識別NOR Flash,擦除NOR Flash某個扇區,編寫某個地址,讀某個地址。代碼如下:
232 void nor_flash_test(void)
233 {
234 char c;
235
236 while (1)
237 {
238 /* 打印菜單, 供我們選擇測試內容 */
239 printf("[s] Scan nor flash\n\r");
240 printf("[e] Erase nor flash\n\r");
241 printf("[w] Write nor flash\n\r");
242 printf("[r] Read nor flash\n\r");
243 printf("[q] quit\n\r");
244 printf("Enter selection: ");
245
246 c = getchar();
247 printf("%c", c);
248
249 /* 測試內容:
250 * 1. 識別nor flash
251 * 2. 擦除nor flash某個扇區
252 * 3. 編寫某個地址
253 * 4. 讀某個地址
254 */
255 switch (c)
256 {
257 case 'q':
258 case 'Q':
259 return;
260 break;
261
262 case 's':
263 case 'S':
264 do_scan_nor_flash();
265 break;
266
267 case 'e':
268 case 'E':
269 do_erase_nor_flash();
270 break;
271
272 case 'w':
273 case 'W':
274 do_write_nor_flash();
275 break;
276
277 case 'r':
278 case 'R':
279 do_read_nor_flash();
280 break;
281 default:
282 break;
283 }
284 }
285 }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
主函數
main函數代碼如下所示。把timer中斷去掉,否則: 測試NOR Flash時進入CFI等模式時, 如果發生了中斷,cpu必定讀NOR Flash,那么讀不到正確的指令,導致程序崩潰。
12 int main(void)
13 {
14 led_init();
15 //interrupt_init(); /* 初始化中斷控制器 */
16 key_eint_init(); /* 初始化按鍵, 設為中斷源 */
17 //timer_init();
18
19 puts("\n\rg_A = ");
20 printHex(g_A);
21 puts("\n\r");
22
23 nor_flash_test();
24
25 return 0;
26 }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
第003節Nor Flash編程擦寫讀
本實例的目的目的:擦除nor flash某個扇區,編寫某個地址,讀某個地址。
等待燒寫
等待燒寫完成 : 讀數據, Q6無變化時表示結束 (參考芯片手冊),
35 void wait_ready(unsigned int addr)
36 {
37 unsigned int val;
38 unsigned int pre;
39
40 pre = nor_dat(addr>>1);
41 val = nor_dat(addr>>1);
42 while ((val & (1<<6)) != (pre & (1<<6)))
43 {
44 pre = val;
45 val = nor_dat(addr>>1);
46 }
47}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
擦除NOR Flash 某個扇區
do_erase_nor_flash函數的代碼如下。參考芯片手冊,就可以知道擦除某個扇區,還是相對比較簡單的。
125 void do_erase_nor_flash(void)
126 {
127 unsigned int addr;
128
129 /* 獲得地址 */
130 printf("Enter the address of sector to erase: ");
131 addr = get_uint();
132
133 printf("erasing ...");
134 nor_cmd(0x555, 0xaa); /* 解鎖 */
135 nor_cmd(0x2aa, 0x55);
136 nor_cmd(0x555, 0x80); /* erase sector */
137
138 nor_cmd(0x555, 0xaa); /* 解鎖 */
139 nor_cmd(0x2aa, 0x55);
140 nor_cmd(addr>>1, 0x30); /* 發出扇區地址 */
141 wait_ready(addr);
142 }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
第131行,get_uint函數用于獲取輸入的地址。
第134,135這兩行是解鎖。
第136行是erase sector。
第138,139行是再次解鎖。
第140行是對發出的扇區地址。
第 141行等待擦除完成。
寫NOR Flash
do_write_nor_flash的代碼如下所示,開發板上的NOR Flash的位寬是16bit,所以可以把要寫的數據構造出16bit然后在寫進NOR Flash中。
144 void do_write_nor_flash(void)
145 {
146 unsigned int addr;
147 unsigned char str[100];
148 int i, j;
149 unsigned int val;
150
151 /* 獲得地址 */
152 printf("Enter the address of sector to write: ");
153 addr = get_uint();
154
155 printf("Enter the string to write: ");
156 gets(str);
157
158 printf("writing ...\n\r");
159
160 /* str[0],str[1]==>16bit
161 * str[2],str[3]==>16bit
162 */
163 i = 0;
164 j = 1;
165 while (str[i] && str[j])
166 {
167 val = str[i] + (str[j]<<8);
168
169 /* 燒寫 */
170 nor_cmd(0x555, 0xaa); /* 解鎖 */
171 nor_cmd(0x2aa, 0x55);
172 nor_cmd(0x555, 0xa0); /* program */
173 nor_cmd(addr>>1, val);
174 /* 等待燒寫完成 : 讀數據, Q6無變化時表示結束 */
175 wait_ready(addr);
176
177 i += 2;
178 j += 2;
179 addr += 2;
180 }
181
182 val = str[i];
183 /* 燒寫 */
184 nor_cmd(0x555, 0xaa); /* 解鎖 */
185 nor_cmd(0x2aa, 0x55);
186 nor_cmd(0x555, 0xa0); /* program */
187 nor_cmd(addr>>1, val);
188 /* 等待燒寫完成 : 讀數據, Q6無變化時表示結束 */
189 wait_ready(addr);
190 }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
第153行把通過get_uint獲得的地址賦值給addr變量,
第156行通過gets函數獲得輸入的字符串。
第168行兩個8位的數據,組合成一個16位的數據賦值給變量val。
讀NOR Flash
do_read_nor_flash函數代碼如下,由于NOR Flash是內存類接口,可以像內存一樣讀取。
191 void do_read_nor_flash(void)
192 {
193 unsigned int addr;
194 volatile unsigned char *p;
195 int i, j;
196 unsigned char c;
197 unsigned char str[16];
198
199 /* 獲得地址 */
200 printf("Enter the address to read: ");
201 addr = get_uint();
202
203 p = (volatile unsigned char *)addr;
204
205 printf("Data : \n\r");
206 /* 長度固定為64 */
207 for (i = 0; i < 4; i++)
208 {
209 /* 每行打印16個數據 */
210 for (j = 0; j < 16; j++)
211 {
212 /* 先打印數值 */
213 c = *p++;
214 str[j] = c;
215 printf("%02x ", c);
216 }
217
218 printf(" ; ");
219
220 for (j = 0; j < 16; j++)
221 {
222 /* 后打印字符 */
223 if (str[j] < 0x20 || str[j] > 0x7e) /* 不可視字符 */
224 putchar('.');
225 else
226 putchar(str[j]);
227 }
228 printf("\n\r");
229 }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
第201行中的get_uint函數,從串口中獲得輸入的地址。
第203行,強制類型轉化。
第207行~216行是對NOR Flash內容的讀取,輸出的內容為16進制的數據,由于NOR Flash是內存類接口,可以像內存一樣讀取。
第220行~227輸出NOR Flash的內容為字符型數據,其中的第223行用來判斷,輸出的字符是否為不可視字符,要是為不可視字符輸出點’.’,要是可視字符輸出字符。
---------------------
本文來自 韋東山 的CSDN 博客 ,全文地址請點擊:https://blog.csdn.net/thisway_diy/article/details/79397638?utm_source=copy
總結
以上是生活随笔為你收集整理的nor flash的一般操作与分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开始开指是什么感觉(开指是什么感觉)
- 下一篇: 中华职业学院是几本(中华职业学院)