一、IMX6ULL启动代码
.global _start
_start:
ldr pc, =_reset_handler
ldr pc, =_undefine_handler
ldr pc, =_svc_handler
ldr pc, =_prefetch_abort_handler
ldr pc, =_data_abort_handler
ldr pc, =_reserved_handler
ldr pc, =_irq_handler
ldr pc, =_fiq_handler
_undefine_handler:
ldr pc, =_undefine_handler
_svc_handler:
ldr pc, =_svc_handler
_prefetch_abort_handler:
ldr pc, =_prefetch_abort_handler
_data_abort_handler:
ldr pc, =_data_abort_handler
_reserved_handler:
ldr pc, =_reserved_handler
_irq_handler:
ldr pc, =_irq_handler
_fiq_handler:
ldr pc, =_fiq_handler
_reset_handler:
mrs r0, cpsr
bic r0, r0, #0x1F
orr r0, r0, #0x12 //irq
msr cpsr, r0
ldr sp, =0x86000000 //起始地址80000000,ram大小为512mb(20000000) 80000000~A0000000-1
mrs r0, cpsr
bic r0, r0, #0x1F
orr r0, r0, #0x1F //system
msr cpsr, r0
ldr sp, =0x84000000 //给irq分配的栈指针空间
二、点灯的步骤
1)初始化时钟
2)设置引脚功能复用(GPIO)
3)引脚电气属性(功率、电阻)
4)设置外设引脚的输入输出方向
5)设置数据寄存器拉低/拉高电平
三、初始化系统时钟
ARM内核为了低功耗,刚开始是全部关闭(通过cg门)
把这七个寄存器全部打开,值全部设置为默认值,初始化系统时钟
四、功能复用
设置为gpio1
五、电气属性
默认值就行,因为是输出
六、外设引脚GDRI
设置输入输出
七、数据寄存器DR
八、点灯代码
1.代码结构
bsp为各种.c.h文件,im6ull为内核文件,obj是生成文件的保存路径,project是主函数以及启动文件
2.bsp
1)led.c
#include "led.h"
#include "fsl_iomuxc.h"
#include "MCIMX6Y2.h"
void init_led(void)
{
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0);
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03, 0x10B0);
GPIO1->GDIR |= (1 << 3);
}
void led_on(void)
{
GPIO1->DR &= ~(1 << 3);
}
void led_off(void)
{
GPIO1->DR |= (1 << 3);
}
void led_nor(void)
{
GPIO1->DR ^= (1 << 3);
}
2)led.h
#ifndef _LED_H_
#define _LED_H_
extern void init_led(void);
extern void led_on(void);
extern void led_off(void);
extern void led_nor(void);
#endif
3.project
1)main.c
#include "MCIMX6Y2.h"
#include "fsl_iomuxc.h"
#include "led.h"
void enable_clocks(void)
{
CCM->CCGR0 = 0xFFFFFFFF;
CCM->CCGR1 = 0xFFFFFFFF;
CCM->CCGR2 = 0xFFFFFFFF;
CCM->CCGR3 = 0xFFFFFFFF;
CCM->CCGR4 = 0xFFFFFFFF;
CCM->CCGR5 = 0xFFFFFFFF;
CCM->CCGR6 = 0xFFFFFFFF;
}
void delay(unsigned int n)
{
while(n--);
}
int main(void)
{
enable_clocks();
init_led();
while(1)
{
led_nor();
delay(0xFFFFF);
}
return 0;
}
2)start.S
.global _start
_start:
ldr pc, =_reset_handler
ldr pc, =_undefine_handler
ldr pc, =_svc_handler
ldr pc, =_prefetch_abort_handler
ldr pc, =_data_abort_handler
ldr pc, =_reserved_handler
ldr pc, =_irq_handler
ldr pc, =_fiq_handler
_undefine_handler:
ldr pc, =_undefine_handler
_svc_handler:
ldr pc, =_svc_handler
_prefetch_abort_handler:
ldr pc, =_prefetch_abort_handler
_data_abort_handler:
ldr pc, =_data_abort_handler
_reserved_handler:
ldr pc, =_reserved_handler
_irq_handler:
ldr pc, =_irq_handler
_fiq_handler:
ldr pc, =_fiq_handler
_reset_handler:
mrs r0, cpsr
bic r0, r0, #0x1F
orr r0, r0, #0x12 //irq
msr cpsr, r0
ldr sp, =0x80600000
mrs r0, cpsr
bic r0, r0, #0x1F
orr r0, r0, #0x1F //system
msr cpsr, r0
ldr sp, =0x80400000
bl _bss_clear
b main
_bss_clear:
ldr r0, =__bss_start
ldr r2, =__bss_end
loop:
mov r1, #0
str r1, [r0]
add r0, r0, #4
cmp r0, r2
blt loop
bx lr
finished:
b finished
4.Makefile
target = led
cross_compiler = arm-linux-gnueabihf-
cc = $(cross_compiler)gcc
ld = $(cross_compiler)ld
objcopy = $(cross_compiler)objcopy
objdump = $(cross_compiler)objdump
incdirs = bsp imx6ull
srcdirs = bsp project
include = $(patsubst %, -I%, $(incdirs))
cfiles = $(foreach dir, $(srcdirs), $(wildcard $(dir)/*.c))
sfiles = $(foreach dir, $(srcdirs), $(wildcard $(dir)/*.S))
cfilenodir = $(notdir $(cfiles))
sfilenodir = $(notdir $(sfiles))
cobjs = $(patsubst %, obj/%, $(cfilenodir:.c=.o))
sobjs = $(patsubst %, obj/%, $(sfilenodir:.S=.o))
objs = $(cobjs) $(sobjs)
VPATH = $(srcdirs)
$(target).bin : $(objs)
$(ld) -Timx6ull.lds -o$(target).elf $^
$(objcopy) -O binary -S -g $(target).elf $@
$(objdump) -D $(target).elf > $(target).dis
$(sobjs) : obj/%.o : %.S
@mkdir -p obj
$(cc) -Wall -nostdlib -c $(include) -o $@ $<
$(cobjs) : obj/%.o : %.c
@mkdir -p obj
$(cc) -Wall -nostdlib -c $(include) -o $@ $<
.PHONY : clean
clean:
rm -rf $(objs) $(target).elf $(target).bin $(target).dis