目录
一、代码部分:
汇编(start.s):
.global _start
_start:
ldr pc, =_reset_handler
ldr pc, =_software_handler
ldr pc, =_undef_handler
ldr pc, =_prefetch_abort_handler
ldr pc, =_data_abort_handler
nop
ldr pc, =_irq_handler
ldr pc, =_fiq_handler
_software_handler:
b _software_handler
_undef_handler:
b _undef_handler
_prefetch_abort_handler:
b _prefetch_abort_handler
_data_abort_handler:
b _data_abort_handler
_irq_handler:
b _irq_handler
_fiq_handler:
b _fiq_handler
_reset_handler:
/*DDR 0x80000000 ~ 0xA0000000*/
cpsid i /*disable irq*/
ldr sp, =0x81000000 /*init system mode stack 16M */
cps #0x12 /*change to irq mode */
ldr sp, =0x82000000 /*init irq mode stack 16M */
cps #0x1f /* change to system mode */
ldr sp, =0x83000000 /*init irq mode stack 16M */
cpsie i /* enable irq */
bl main
code_end:
b code_end
这里只写中断向量表部分,用C来写main函数实现我们的功能
main.c代码:
#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 (*((volatile unsigned long *)0x20E0068U))
#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 (*((volatile unsigned long *)0x20E02F4U))
#define GPIO1_DR (*((volatile unsigned long *)0x209C000U))
#define GPIO1_GDIR (*((volatile unsigned long *)0x209C004))
static void led_init(void)
{
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 &= ~(0x1f);
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 |= 0x05;
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 |= 0x10b0;
GPIO1_GDIR |= (1 << 3);
GPIO1_DR |= (1 << 3);
}
static void led_on(void)
{
GPIO1_DR &= ~(1 << 3);
}
static void led_off(void)
{
GPIO1_DR |= (1 << 3);
}
static void led_delay(unsigned int num)
{
while (num--)
{
}
}
int main(void)
{
led_init();
beep_init();
while (1)
{
led_on();
led_delay(0x80000);
led_off();
beep_off();
led_delay(0x80000);
}
return 0;
}
注意:
汇编的代码中,切换工作模式后一定要初始化栈!!!
二、makefile
写个makefile链接一下即可:
CC=arm-linux-gnueabihf-gcc
LD=arm-linux-gnueabihf-ld
OBJCOPY=arm-linux-gnueabihf-objcopy
OBJDUMP= arm-linux-gnueabihf-objdump
TARGET = start
OBJ = start.o main.o
$(TARGET).bin:$(OBJ)
$(LD) -Ttext 0x87800000 $(OBJ) -o $(TARGET).elf
$(OBJCOPY) -O binary -S -g $(TARGET).elf $@
$(OBJDUMP) -D $(TARGET).elf > $(TARGET).dis
%.o:%.S
$(CC) -c -g $^ -o $@
%.o:%.c
$(CC) -c -g $^ -o $@
clean:
rm $(TARGET).bin $(TARGET).elf $(TARGET).dis *.o
load:
./imxdownload $(TARGET).bin /dev/sdb
注意:
1.Makefile的目标要用.o这一步(只编译不链接),用.c的话会重复很多编译过程
2.Makefile中的OBJ中,一定是start.o在前面,main.c在后面,因为程序运行时如果先链接的是main,会先执行main 的代码再执行start\
3.%.s中的%是通配符,是make自己的语法,*.o中的*是shell命令的通配符
三、SDK
用c语言实现LED后我们发现,还是像汇编一样要去找地址很麻烦,这里,我们使用别人写好的头文件,即SDK
SDK 是 Software Development Kit 的缩写,中文意思是 软件开发工具包。
一个典型的 SDK 通常包含以下内容:
-
库文件:别人写好的、可以直接调用的功能代码(如"扫码功能"、"地图显示")。
-
文档:教你怎么使用这些代码的说明书。
-
代码示例:现成的演示程序。
-
调试工具:用于排查问题的辅助工具。
这里我们再加一个beep的功能,看手册找到引脚然后直接调用SDK的库函数就行了
1.led

2.beep

3.delay

4.main

5.makefile

6.整体框架

四.总结
1.包含头文件时要加路径
2.makefile文件的.o依赖的.c的路径要写出如:
led.o:led/led.c
(CC) -c -g ^ -o $@
3.这里用到的函数:
IOMUXC_SetPinMux()是设置引脚功能的,最后一个参数是探针(手册上的SION位)
IOMUXC_SetPinConfig()是设置电气特性的,最后一个参数是设置电气属性
