at91的remap經(jīng)歷(N次Flash熱插拔經(jīng)歷)
小弟用的是AT91R40008,內(nèi)部有256KB的SRAM,以前沒有用過帶REMAP功能的ARM,這是第一次。
一開始,忘了設(shè)置FLASH remap之后的基址,remap之后,內(nèi)部的SRAM再也不能用了,還好Flash是PLCC封裝的,帶電熱插拔(小弟的電路板是自己設(shè)計(jì)的自己焊的平時(shí)跑著都不放心,熱插拔的時(shí)候心里怦怦直跳)。
第二次,事先設(shè)置好了FLASH remap之后的地址。沒想到,remap之后,還是當(dāng)機(jī)。這是恍然大悟,remap之后PC指向了SRAM,難怪會跑飛。不知為什么,這次加載到SRAM中的程序仍然運(yùn)行不起來,不想那么多了先把remap搞定,再次熱插拔。
為了保證remap之后,程序仍然能夠正常運(yùn)行,看來要把程序?qū)崿F(xiàn)復(fù)制到SRAM中,不過感覺這種辦法好苯。于是在網(wǎng)上找呀找,終于找到了另一種remap方法,如下:
InitTableEBI:
dcd EBI_CSR_0
dcd EBI_CSR_1
dcd EBI_CSR_2
dcd EBI_CSR_3
dcd EBI_CSR_4
dcd EBI_CSR_5
dcd EBI_CSR_6
dcd EBI_CSR_7
dcd 0x00000001 /* REMAP command */
dcd 0x00000006 /* 6 memory regions, standard read */
PtEBIBase:
dcd EBI_BASE /* EBI Base Address */
PtInitTableEBI DCD InitTableEBI
PtInitRemap DCD InitRemap
ldr r10 , PtInitTableEBI
mov r10 , r10 , LSL #12
mov r10 , r10 , LSR #12
R10的高12位必須清0,因?yàn)殒溄邮沁\(yùn)行域地址是FLASH remap之后的地址,而這時(shí)實(shí)際運(yùn)行在remap之前的地址處。
ldr r12,addr_after_remap
ldmia r10!, {r0-r9,r11}
stmia r11!, {r0-r9} /* 拷貝片選寄存器映像到存儲控制器和命令remap */
mov pc, r12
原理就是利用ARM流水線,最后一條指令在上一條指令之前完成,具體原理我也不清楚,查了一些資料都沒有解釋,不知哪位大蝦能說一說。不過在remap之前加載絕對地址時(shí)要注意絕對地址和實(shí)際地址不一樣呦。
事實(shí)上,通過上面的方法就可以實(shí)現(xiàn)remap了,不過小弟寫程序太馬虎了,又經(jīng)歷了幾次熱插拔才成功(不過我對我的板子越來越有信心了,看來那種熱插拔BIOS的言論也是危言聳聽):)。