一、首先,看半导体厂商是否有对应的开发板,有的话就直接用厂商的,I.MX6ULL是有的,没有的话就要看芯片手册自己画PCB制作。
二、看芯片手册注意上电时序、串口 1 RXD 上拉、 启动方式。
三、1、尝试点灯,看芯片手册,看引脚寄存器的地址、功能,参照STM32的程序设计此芯片的程序。使能时钟、设置复用功能、哪个引脚、模式(上下拉、速度等)、输入输出、高低电平。
2、使用汇编语言进行编写,注意GNU汇编与intel汇编的区别,直接对芯片的地址进行操作
1 ldr r0, =0X020C4068 2 ldr r1, =0XFFFFFFFF 3 str r1, [r0]
使用交叉编译器arm-linux-gnueabihf-gcc,可能由于版本不一而不好用,尝试降低版本。
只编译但是不链接
1 arm-linux-gnueabihf-gcc -g -c led.s -o led.o
链接.o文件
2 arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
格式转换为二进制
3 arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
进行反汇编来查看其汇编代码来调试代码
4 arm-linux-gnueabihf-objdump -D led.elf > led.dis
也可直接使用Makefile,要注意使用Tab,不使用空格
1 led.bin:led.s 2 arm-linux-gnueabihf-gcc -g -c led.s -o led.o 3 arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf 4 arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin 5 arm-linux-gnueabihf-objdump -D led.elf > led.dis 6 clean: 7 rm -rf *.o led.bin led.elf led.dis
要注意第三行的链接地址的选择。这个链接地址是在DDR中
通过烧写工具将led.bin文件烧写进SD卡中,也可以其他方式,主要看选择的启动方式是怎样的。
四、以上是用汇编语言写的代码,我们大多数用C语言写,需要用汇编语言搭一个环境,就是SP指针
1 .global _start /* 全局标号 */ 2 3 /* 4 * 描述: _start 函数,程序从此函数开始执行,此函数主要功能是设置 C 5 * 运行环境。 6 */ 7 _start: 8 /* 进入 SVC 模式 */ 9 mrs r0, cpsr 10 bic r0, r0, #0x1f /* 将 r0 的低 5 位清零,也就是 cpsr 的 M0~M4 */ 11 orr r0, r0, #0x13 /* r0 或上 0x13,表示使用 SVC 模式 */ 12 msr cpsr, r0 /* 将 r0 的数据写入到 cpsr_c 中 */ 13 14 ldr sp, =0X80200000 /* 设置栈指针 */ 15 b main /* 跳转到 main 函数 */
main.h以宏定义的形式定义寄存器,
1 #define SW_MUX_GPIO1_IO03 *((volatile unsigned int *)0X020E0068)
main.c定义函数进行应用。
1 SW_MUX_GPIO1_IO03 = 0x5;
对以上的Makefile和链接进行升级
1 objs := start.o main.o 2 3 ledc.bin:$(objs) 4 arm-linux-gnueabihf-ld -Timx6ul.lds -o ledc.elf $^ 5 arm-linux-gnueabihf-objcopy -O binary -S ledc.elf $@ 6 arm-linux-gnueabihf-objdump -D -m arm ledc.elf > ledc.dis 7 8 %.o:%.s 9 arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $< 10 11 %.o:%.S 12 arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $< 13 14 %.o:%.c 15 arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $< 16 17 clean: 18 rm -rf *.o ledc.bin ledc.elf ledc.dis
在Makefile同目录下新建一个名为“imx6ul.lds”的文件,此为链接脚本。
1 SECTIONS{ 2 . = 0X87800000; 3 .text : 4 { 5 start.o 6 main.o 7 *(.text) 8 } 9 .rodata ALIGN(4) : {*(.rodata*)} 10 .data ALIGN(4) : { *(.data) } 11 __bss_start = .; 12 .bss ALIGN(4) : { *(.bss) *(COMMON) } 13 __bss_end = .; 14 }
五、如果半导体厂商提供SDK包,可以改一改,增删文件进行使用,如果没有,就要自己写SDK包。
六、由于文件个数比较多,要对程序进行分功能管理,使其美观、功能模块清晰、易于阅读。BSP(board support package)板级支持包。
七、编译和链接终极模板:
1、编译
1 CROSS_COMPILE ?= arm-linux-gnueabihf- #编译器名 2 TARGET ?= bsp #文件名或者例程名,注意更改 3 4 CC := $(CROSS_COMPILE)gcc 5 LD := $(CROSS_COMPILE)ld 6 OBJCOPY := $(CROSS_COMPILE)objcopy 7 OBJDUMP := $(CROSS_COMPILE)objdump 8 9 INCDIRS := imx6ul \ #头文件目录,添加新的 10 bsp/clk \ 11 bsp/led \ 12 bsp/delay 13 14 SRCDIRS := project \ #.c或.s目录,添加新的 15 bsp/clk \ 16 bsp/led \ 17 bsp/delay 18 19 INCLUDE := $(patsubst %, -I %, $(INCDIRS)) 20 SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S)) 21 CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c)) 22 23 SFILENDIR := $(notdir $(SFILES)) 24 CFILENDIR := $(notdir $(CFILES)) 25 26 SOBJS := $(patsubst %, obj/%, $(SFILENDIR:.S=.o)) 27 COBJS := $(patsubst %, obj/%, $(CFILENDIR:.c=.o)) 28 OBJS := $(SOBJS) $(COBJS) 29 30 VPATH := $(SRCDIRS) 31 32 .PHONY: clean 33 34 $(TARGET).bin : $(OBJS) 35 $(LD) -Timx6ul.lds -o $(TARGET).elf $^ 36 $(OBJCOPY) -O binary -S $(TARGET).elf $@ 37 $(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis 38 39 $(SOBJS) : obj/%.o : %.S 40 $(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $< 41 42 $(COBJS) : obj/%.o : %.c 43 $(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $< 44 clean: 45 rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)
2、链接
1 SECTIONS{ 2 . = 0X87800000; 3 .text : 4 { 5 obj/start.o 6 *(.text) 7 } 8 .rodata ALIGN(4) : {*(.rodata*)} 9 .data ALIGN(4) : { *(.data) } 10 __bss_start = .; 11 .bss ALIGN(4) : { *(.bss) *(COMMON) } 12 __bss_end = .; 13 }
标签:gnueabihf,led,芯片,elf,之后,拿到,linux,r0,arm From: https://www.cnblogs.com/linchangchao/p/17636238.html