exynos4412祼机LED闪灯-⼀闪⼀闪亮晶晶
⼀闪⼀闪亮晶晶,满天都是⼩星星……
今天,我为你摘下⼀颗星,闪给你看……只有⼀颗喔……
《》⼀⽂中讲过,bootloader的作⽤主要是初始化操作系统启动所需的环境,并引导操作系统。
现在不需要操作系统,我们仅需要让LED闪灯,能不能把引导操作系统,变成引导我们的裸机程序main呢?
我们的u-boot,其实就是⼀个⼤的裸机程序,只要把它改成我们的led闪灯程序就⾏了。
《》⼀⽂中讲到,最终烧录⼊sd卡的u-boot,是这样得来的:
cat E4412.S.BL1.SSCR.EVT1.1.bin E4412.BL2.TZ.SSCR.EVT1.1.bin all00_padding.bin u-boot.bin
E4412.TZ.SSCR.EVT1.1.bin > u-boot-iTOP-4412.bin
这句⽣成最终的 u-boot-iTOP-4412.bin ⽂件,是我们最终烧录进板卡的 bootloader。
其中,
4412.S.BL1.SSCR.EVT1.1.bin ⼤⼩ 8k,是由三星提供的 BL1;
E4412.BL2.TZ.SSCR.EVT1.1.bin+all00_padding.bin,总共16K,是由三星提供的 BL2;
u-boot.bin ⼤⼩328k,是⾃个源码编译⽣成的,如果我们的源码不够328k,sdfuse_q/add_padding会⾃动补⾜(在Makefile中有⼀句@./sdfuse_q/add_padding),所以,u-boot.bin不管怎么编译,都是 328k;
所以,我们只要把我们的led闪灯程序,编译成led.bin,再把
4412.S.BL1.SSCR.EVT1.1.bin+ E4412.BL2.TZ.SSCR.EVT1.1.bin+all00_padding.bin+led.bin+E4412.TZ.SSCR.EVT1.1.bin拼成我们最终.bin,再写进SD卡⾥⾯就⾏了。
编写程序前,应该先
1、查看原理图,确定LED灯所对应的IO⼝;
2、查看芯⽚资料,确定如何初始化IO,以及控制IO⾼和低(灯亮和灯灭);
1、查看原理图,确定LED灯所对应的IO⼝;
LED3对应的IO⼝是GPK1_1,从电路图可以看出,VDD50_EN⾼电平时,三极管通,LED3亮,低电平时,三极管不通,LED3灭。
2、查看芯⽚资料,确定如何初始化IO,以及控制IO⾼和低(灯亮和灯灭);
GPK1CON寄存器的地址是0x1100_0000+0x0000_0060,对应的IO⼝GPK1_1在[7:4]位,应配置为0x1(output),所以,初始化GPK1_1可以:
*(volatile unsigned long *)0x11000060 &= (~0xf0);
*(volatile unsigned long *)0x11000060 |= (0x1<<4);
GPK1DAT寄存器的地址是0x1100_0000+0x0000_0064,对应的IO⼝GPK1_1在[1]位,配置为1时,⾼电平,灯亮,配置为0时,低电平,灯灭,所以,控制灯可以:
*(volatile unsigned long *)0x11000064 |= (0x2); // IO⾼,灯亮
*(volatile unsigned long *)0x11000064 &= (~0x2); // IO低,灯灭
知道如何初始化,以及如何操作IO⼝,使灯亮灭后,可以开始编写闪灯程序了,编写闪灯程序分⼏个步骤:
1、main⽂件,由C语⾔编写,主要负责初始化led,以及闪灯;
2、start⽂件,由汇编语⾔编写,主要负责设置堆栈,并跳转⾄main;
3、Makefile,主要负责make,不熟悉的同学,请移步《》;
4、./build.sh,linux shell⽂件,由⼀些命令组成,主要负责编译,把led.bin补⾜ 328k,拼bl1+bl2+led.
bin,等等;
5、mkuboot,linux shell⽂件,由⼀些命令组成,主要负责把最终的bin⽂件,写进SD卡⾥;
1、main⽂件,由C语⾔编写,主要负责初始化led,以及闪灯;
#define GPK1CON (*(volatile unsigned long*)0x11000060)
#define GPK1DAT (*(volatile unsigned long*)0x11000064)
enum
{
OFF,
ON,
};
static void user_delay(unsigned int val)
{
unsigned i, j;
for(i=0; i<val; i++)
for(j=0; j<val; j++){;;;;;;;;;;;;;;;}
}
int main(void)
{
unsigned char ledStat = OFF;
// 初始化GPIO⼝,初始化为输出
GPK1CON &= (~0xf0);
GPK1CON |= 0x10;
GPK1DAT |= 0x2;
// 闪灯
while(1)
{
if(ledStat==OFF)
{
ledStat = ON;
GPK1DAT |= 0x2;
}
else
{
ledStat = OFF;
GPK1DAT &= (~0x2);
}
user_delay(1000);
}
return 0;
}
2、start⽂件,由汇编语⾔编写,主要负责设置堆栈,并跳转⾄main;.text
.globl _start
_start:
b reset
reset:
/* i don't know why init GPX0CONF?*/
/* but if you don't init it, it will reset system every few seconds */
ldr r0, =0x11000c08
ldr r1, =0x0
str r1, [r0]
ldr sp, = 0x02050000 // 设置堆栈
bl main // 跳转⾄⼊⼝函数 main
3、Makefile,主要负责make,不熟悉的同学,请移步《》;
.PHONY: led.bin
led.bin:start.o led.o
arm-none-linux-gnueabi-ld -Ttext 0x0 -o led.elf $^
arm-none-linux-gnueabi-objcopy -O binary led.elf led.bin
arm-none-linux-gnueabi-objdump -D led.elf > led.dis
.PHONY: %.o
%.o:%.S
arm-none-linux-gnueabi-gcc -g -c -o $@ $< -nostdlib
%.o:%.c
arm-none-linux-gnueabi-gcc -g -c -o $@ $< -nostdlib
makefile phony.PHONY: clean
clean:
rm *.o *.elf *.bin *.dis -f
4、./build.sh,linux shell⽂件,由⼀些命令组成,主要负责编译,把led.bin补⾜ 328k,拼bl1+bl2+led.bin,等等; 需要把 ./add_padding 拷进去,⽤于补⾜ led.bin 328k⼤⼩;
需要把4412.S.BL1.SSCR.EVT1.1.bin、E4412.BL2.TZ.SSCR.EVT1.1.bin、all00_padding.bin、
E4412.TZ.SSCR.EVT1.1.bin 拷进去,⽤来拼成最终烧录的⽂件;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论