《嵌入式硬件(八):基于IMX6ULL的点灯操作》
一、IMX6ULL启动代码
.global _start_start:ldr pc, =_reset_handlerldr pc, =_undefine_handlerldr pc, =_svc_handlerldr pc, =_prefetch_abort_handlerldr pc, =_data_abort_handlerldr pc, =_reserved_handlerldr pc, =_irq_handlerldr 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, cpsrbic r0, r0, #0x1Forr r0, r0, #0x12 //irqmsr cpsr, r0ldr sp, =0x86000000 //起始地址80000000,ram大小为512mb(20000000) 80000000~A0000000-1mrs r0, cpsrbic r0, r0, #0x1Forr r0, r0, #0x1F //systemmsr 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_handlerldr pc, =_undefine_handlerldr pc, =_svc_handlerldr pc, =_prefetch_abort_handlerldr pc, =_data_abort_handlerldr pc, =_reserved_handlerldr pc, =_irq_handlerldr 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, cpsrbic r0, r0, #0x1Forr r0, r0, #0x12 //irqmsr cpsr, r0ldr sp, =0x80600000mrs r0, cpsrbic r0, r0, #0x1Forr r0, r0, #0x1F //systemmsr cpsr, r0 ldr sp, =0x80400000bl _bss_clearb main_bss_clear:ldr r0, =__bss_startldr r2, =__bss_end
loop:mov r1, #0str r1, [r0]add r0, r0, #4cmp r0, r2blt loopbx lrfinished:b finished
4.Makefile
target = ledcross_compiler = arm-linux-gnueabihf-cc = $(cross_compiler)gcc
ld = $(cross_compiler)ld
objcopy = $(cross_compiler)objcopy
objdump = $(cross_compiler)objdumpincdirs = bsp imx6ull
srcdirs = bsp projectinclude = $(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