ARM裸機(jī)開(kāi)發(fā)bootloader—點(diǎn)亮LED燈
a、原理圖分析
本文引用地址:http://cafeforensic.com/article/201611/318210.htmb、芯片手冊(cè)
c、思維導(dǎo)圖
d、編寫代碼
2、為什么要點(diǎn)亮led
在嵌入式軟件(bootloader、kernel)開(kāi)發(fā)初期,由于串口等硬件尚未進(jìn)行初始化,所以可以用來(lái)調(diào)試的手段很有限。這時(shí)通常運(yùn)用點(diǎn)亮led作為調(diào)試的重要手段。也就是說(shuō)不斷改動(dòng)led點(diǎn)亮程序的位置,來(lái)查看那段代碼出現(xiàn)了問(wèn)題,然后進(jìn)行針對(duì)性的修改。
下面我用6410為例進(jìn)行點(diǎn)亮led的介紹,其他的如2440和210流程相似。
a、原理圖分析
從led的原理圖我們可以看到,nLED_*低電平有效,也就是對(duì)應(yīng)的s3c6410GPK4-7低電平,這個(gè)時(shí)候要引出一個(gè)概念:GPIO
什么是GPIO
GPIO(General-Purpose Input/Output Ports):通用的輸入/輸出端口。在嵌入式系統(tǒng)中,cpu需要控制一些結(jié)構(gòu)簡(jiǎn)單的外部設(shè)備,它們通常只用兩種狀態(tài)(開(kāi)/關(guān))。如果用串口或USB去控制就顯得復(fù)雜了些,所以在嵌入式微處理器上就引入了一種“通用可編程I/O端口”,也就是GPIO。
一個(gè)GPIO端口至少需要兩個(gè)寄存器,一個(gè)是“控制寄存器”,用于選擇端口作為輸入還是輸出。另一個(gè)是存放數(shù)據(jù)的“數(shù)據(jù)寄存器”。
b、查看芯片手冊(cè)
在6410手冊(cè)上查找GPK端口
查看到手冊(cè)我們得知,將相應(yīng)的數(shù)據(jù)填入相應(yīng)的內(nèi)存地址就可以了。
c、思維導(dǎo)圖
總共分為兩步來(lái)走
1、設(shè)置GPIO控制器,把引腳設(shè)置為輸出
2、根據(jù)原理圖設(shè)置GPIO的數(shù)據(jù)寄存器
d、編寫led的驅(qū)動(dòng)程序
.text.global _start_start:b resetldr pc, _undefined_instructionldr pc, _software_interruptldr pc, _prefetch_abortldr pc, _data_abortldr pc, _not_usedldr pc, _irqldr pc, _fiq_undefined_instruction: .word undefined_instruction_software_interrupt: .word software_interrupt_prefetch_abort: .word prefetch_abort_data_abort: .word data_abort_not_used: .word not_used_irq: .word irq_fiq: .word fiqundefined_instruction:nopsoftware_interrupt:nopprefetch_abort:nopdata_abort:nopnot_used:nopirq:nopfiq:nopreset:bl set_peri_portbl set_svcbl disable_watchdogbl disable_interruptbl disable_mmubl light_ledset_peri_port:ldr r0, =0x70000000orr r0, r0, #0x13mcr p15,0,r0,c15,c2,4mov pc, lr set_svc:mrs r0, cpsrbic r0, r0, #0x1forr r0, r0, #0xd3msr cpsr, r0mov pc, lr#define pWTCON 0x7E004000disable_watchdog:ldr r0, =pWTCON /*mov的操作數(shù)最多為8位*/mov r1, #0x0str r1, [r0]mov pc, lrdisable_interrupt:mvn r1, #0x0ldr r0, =0x71200014str r1, [r0]ldr r0, =0x71300014str r1, [r0]mov pc, lrdisable_mmu:mcr p15, 0, r0, c7, c7, 0mrc p15, 0, r0, c1, c0, 0bic r0, r0, #0x00000007mcr p15, 0, r0, c1, c0, 0mov pc, lr#define GPKCON0 0x7f008800#define GPKDAT 0x7f008808light_led:ldr r0, =GPKCON0ldr r1, =0x11110000str r1, [r0]ldr r0, =GPKDATldr r1, =0xa0str r1, [r0]mov pc, lr運(yùn)行以后,led會(huì)兩亮兩滅。從程序中我們還會(huì)看到一個(gè)函數(shù)set_peri_port。這個(gè)函數(shù)是對(duì)外圍設(shè)備基地址初始化。原因是arm11的內(nèi)存與外圍接口分開(kāi)了,這個(gè)時(shí)候要用此函數(shù)把外圍寄存器映射到內(nèi)存中,整個(gè)的過(guò)程是通過(guò)CP15來(lái)完成的,也就是告訴CPU外設(shè)寄存器的基地址和地址空間實(shí)現(xiàn)映射。
set_peri_port:ldr r0, =0x70000000orr r0, r0, #0x13mcr p15, 0, r0, c15, c2, 40x70000000是SROM的基地址,這段代碼的功能就是告訴cpu外圍設(shè)備寄存器基地址為0x70000000,地址空間為256M(0x70000000-0x7fffffff)。
評(píng)論