【I.MX6ULL学习笔记·六】C语言点灯

在上一章的学习中,我学会了用汇编点灯,以及代码的烧录过程。值得记录的一点是,最终烧录到SD卡中的文件是led.imx,而.imx文件是由.bin文件前添加了IVT,BootData,DCD三个数据块合成的。这三个数据块有固定的格式,其中IVT中包含了镜像程序的入口点,指向DCD的指针和一些做其他用途的指针。BootData是启动数据,包含了镜像要拷贝到哪个地址,拷贝的大小是多少,而DCD是设备配置信息。将他们结合起来的.imx文件最终才能烧写到SD卡中。

C语言版LED灯实验

使用汇编完成C语言环境的初始化,然后从汇编跳转到C语言

首先在工程文件夹创建三个文件请添加图片描述
在start.S文件中编写汇编代码,使其可以跳转到main函数

.global _start   /*全局标号 */
 /*函数从此处开始运行 */
 _start:
    mrs r0,cpsr  /*将特殊寄存器cpsr中的数据传递给r0 */
    bic r0, r0, #0x1f /*将r0的低5位清零,也就是cpsr的M0~M4 */
    orr r0 ,r0, #0x13 /*r0或上0x13,表示SVC模式 */
    msr cpsr, r0 /*将r0的数据写入到cpsr_c */
    ldr sp, =0X80200000 /*设置栈指针 */
    b main /*跳转到main函数 */

我们在使用SDRAM和DDR之前需要初始化,这些是在上面提到的DCD中初始化完成
main.h

#ifndef _MAIN。H
#define _MAIN_H
/*
* CCM 相关寄存器地址
*/


 #define CCM_CCGR0 *((volatile unsigned int *)0X020C4068)
 #define CCM_CCGR1 *((volatile unsigned int *)0X020C406C)
 #define CCM_CCGR2 *((volatile unsigned int *)0X020C4070)
 #define CCM_CCGR3 *((volatile unsigned int *)0X020C4074)
 #define CCM_CCGR4 *((volatile unsigned int *)0X020C4078)
 #define CCM_CCGR5 *((volatile unsigned int *)0X020C407C)
 #define CCM_CCGR6 *((volatile unsigned int *)0X020C4080)
 /*
 IOMUX 相关寄存器地址
*/
 #define SW_MUX_GPIO1_IO03 *((volatile unsigned int *)0X020E0068)
 #define SW_PAD_GPIO1_IO03 *((volatile unsigned int *)0X020E02F4)
 /*
* GPIO1 相关寄存器地址
*/
 #define GPIO1_DR *((volatile unsigned int *)0X0209C000)
 #define GPIO1_GDIR *((volatile unsigned int *)0X0209C004)
 #define GPIO1_PSR *((volatile unsigned int *)0X0209C008)
 #define GPIO1_ICR1 *((volatile unsigned int *)0X0209C00C)
 #define GPIO1_ICR2 *((volatile unsigned int *)0X0209C010)
 #define GPIO1_IMR *((volatile unsigned int *)0X0209C014)
 #define GPIO1_ISR *((volatile unsigned int *)0X0209C018)
 #define GPIO1_EDGE_SEL *((volatile unsigned int *)0X0209C01C)

 #endif

main.c

#include "main.h"
void clk_enable(void)
{
    CCM_CCGR0 = 0xffffffff;
    CCM_CCGR1 = 0xffffffff;
    CCM_CCGR2 = 0xffffffff;
    CCM_CCGR3 = 0xffffffff;
    CCM_CCGR4 = 0xffffffff;
    CCM_CCGR5 = 0xffffffff;
    CCM_CCGR6 = 0xffffffff;
}
void led_init(void)
{
/*1.初始化IO复用,复用为GPIO1——IO03*/
    SW_MUX_GPIO1_IO03 =0x5;
/* 2、配置 GPIO1_IO03 的 IO 属性
 *bit 16:0 HYS 关闭
 *bit [15:14]: 00 默认下拉
 *bit [13]: 0 kepper 功能
 *bit [12]: 1 pull/keeper 使能
 *bit [11]: 0 关闭开路输出
 *bit [7:6]: 10 速度 100Mhz
 *bit [5:3]: 110 R0/6 驱动能力
 *bit [0]: 0 低转换率*/
    SW_PAD_GPIO1_IO03 = 0X10B0;
    /*3.初始化GPIO,GPIO1——IO03设置为输出*/
    GPIO1_GDIR = 0X0000008;
    /* 4、设置 GPIO1_IO03 输出低电平,打开 LED0 */
    GPIO1_DR=0x0;
}
void led_on(void)
{
    /*清除数据位*/
    GPIO1_DR &=~(1<<3);
}
void led_off(void)
{
    GPIO1_DR|=(1<<3);
}
void delay_short(volatile unsigned int n)
{
    while(n--){}

}
void delay(volatile unsigned int n)
{
    while(n--)
    {
        delay_short(0x7ff);
    }
}
int main(void)
{
    clk_enable();/*使能所有时钟*/
    led_init();
    while(1)
    {
        led_off();
        delay(500);
        led_on();
        delay(500);
    }
    return 0;
}

Makefile

objs :=start.o main.o
ledc.bin:$*(objs)
	arm-linux-gnueabihf-ld -Ttext 0X87800000 -o ledc.elf $^
	arm-linux-gnueabihf-objcopy -O binary -S ledc.elf $@   
	arm-linux-gnueabihf-objdump -D -m -arm ledc.elf >ledc.dis
%.o:.s
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<
%.o:.S
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<
%.o:.c
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<

clean:
	rm -rf *.o ledc.bin ledc.elf ledc.dis

链接脚本编写
该脚本用于描述文件该如何被链接在一起形成最终的可执行文件,一般编译出的代码都包含在text,data,bss,rodata四个段内
imx6ul.lds

SECTIONS{
    . = 0X87800000;/*. 叫做定位计数器,它给多少之后的代码都会以这个位置为起始点*/
    .text : /*段名,后面大括号里面写所有链接到此处的文件*/
    {
        start.o
        main.o
        *(.text)/*表示所有输入文件的.text段都要放到这里*/
    }
    .rodata ALIGN(4) : {*(.rodata*)}/*align表示四字节对齐*/
    .data ALIGN(4)  :{*(.data)}
    __bss_start= .;
    .bss ALIGN(4)   :{*(.bss)*(COMMON)}
    __bss_end = .;
}

修改Makefile

objs :=start.o main.o
ledc.bin:$*(objs)
	arm-linux-gnueabihf-ld -Timx6ul.lds -o ledc.elf $^
	arm-linux-gnueabihf-objcopy -O binary -S ledc.elf $@   
	arm-linux-gnueabihf-objdump -D -m -arm ledc.elf >ledc.dis
%.o:.s
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<
%.o:.S
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<
%.o:.c
	arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o $@ $<

clean:
	rm -rf *.o ledc.bin ledc.elf ledc.dis

博主在这里出现错误

arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o main.o main.c
arm-linux-gnueabihf-ld -Timx6ul.lds -o ledc.elf start.o main.o
arm-linux-gnueabihf-objcopy -O binary -S ledc.elf ledc.bin   
arm-linux-gnueabihf-objdump -D -m -arm ledc.elf > ledc.dis
arm-linux-gnueabihf-objdump: can't use supplied machine -arm
Makefile:4: recipe for target 'ledc.bin' failed
make: *** [ledc.bin] Error 1

在.bin文件出现问题,一般是因为链接脚本出现了问题,我回去检查了imx6ul.lds文件,发现是昨天写了没有保存(囧),改正后就运行成功了,接下来的操作跟汇编点灯一样,先把imxdownload粘贴到工程目录,然后更改其权限,烧录代码。

bj@bj-MS-7C83:~/imx6u/ledc$ chmod 777 imxdownload
bj@bj-MS-7C83:~/imx6u/ledc$ ./imxdownload ledc.bin /dev/sdb

灯闪烁,成功~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值