IMX6ULL裸机开发学习2-使用C语言点亮LED指示灯

本章节接着上一章<IMX6ULL裸机开发学习1-汇编点亮led>进行升级改造代码。

编程环境搭建:

开发板:野火Imx6ull mini板

编程环境:Ubuntu18.04 + VScode

开始进入代码内容:

C语言需要运行起来,少不了汇编准备好运行的环境。

汇编代码start.S如下:

/*******************
*文件名:   start.S
*作者    :     桂志威
*邮箱    :  motion_gui@126.com
*日期    :2022 - 02 -13
*描述    :裸机实验测试2 C语言点亮led
 ********************/

 .global    _start      @全局标号

 /*****
 *描述 : _start函数
  */
  _start :

 /*****
 *1.配置CPU 进入SVC模式
  */
  mrs r0,   cpsr                       @拷贝CPSR状态寄存器到R0中
  bic r0,   r0,   #0x1f              @清楚CPU模式位BIT4-BIT0
  orr r0,   r0,   #0x13             @配置BIT4-0为SVC模式
  msr cpsr,   r0                       @将寄存器R0数据写回到CPSR中


 /*****
 *2.设置堆栈指针并跳转C语言main函数
  */
  ldr sp,   =0x80200000       @设置堆栈0x80200000->0x80000000  2M空间
  b   main                                 @跳转到C语言main函数


  

有了上述代码,就能和stm32一样写代码了。

C代码部分来个头文件led.h,将CPU相关寄存器地址指针给定义出来:

/*******************
*文件名:  led.h
*作者    :     桂志威
*邮箱    :  motion_gui@126.com
*日期    :2022 - 02 -13
*描述    :led灯程序头文件,存放寄存器指针
 ********************/
#ifndef _H_LED_H
#define _H_LED_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复用相关寄存器地址定义
 * IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 地址229_0014h
 * IOMUXC_SNVS_SW_PAD_CTL_PAD_SNVS_TAMPER3 地址 229_0058h
*/
#define SW_MUX_GPIO5_IO3           *((volatile unsigned int *)0x02290014)
#define SW_PAD_GPIO5_IO3           *((volatile unsigned int *)0x02290058)

/**
 * GPIO5相关寄存器地址定义
 * 
*/
#define GPIO5_DR                 *((volatile unsigned int *)0x020AC000)
#define GPIO5_GDIR            *((volatile unsigned int *)0x020AC004)

/**
 * GPIO5_IO3相关操作宏
 * 开漏输出控制
*/
#define LED_ON()                      (GPIO5_DR &= ~(1<<3))
#define LED_OFF()                    (GPIO5_DR |= (1<<3))


#endif // !_H_LED_H

可执行代码片段:

/*******************
*文件名:  led.c
*作者    :     桂志威
*邮箱    :  motion_gui@126.com
*日期    :2022 - 02 -13
*描述    :led灯程序可执行程序
 ********************/
#include "led.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 ;       
}

/**
 * Led初始化对应的GPIO
*/
void led_Init(void)
{
  /*****
  *1.GPIO5_IO03 复用功能配置GPIO
  *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 地址229_0014h
   */
  SW_MUX_GPIO5_IO3 = 0x5;        //AL5

  /*****
  *2.GPIO5_IO03 配置IO属性功能
  *IOMUXC_SNVS_SW_PAD_CTL_PAD_SNVS_TAMPER3 地址 229_0058h
  *BIT0 压摆率 0-慢速
  *BIT5-3 驱动能力R0/6  -110
  *BIT7-6 速度 100mhz-10
  * BIT11 开漏输出使能 1-开启
  *BIT12 上下拉功能使能 0-关闭上下拉
  *BIT13 保持功能0
  *BIT15-14 100K上下拉电阻 -00
  *BIT16 hys-0关闭
  *设置配置值:8B0-100010110000
   */
  SW_PAD_GPIO5_IO3 = 0x08B0;

/*****
*3.设置GPIO5_IO03 为输出
*GPIO5_GDIR   地址20A_C004
*GPIO5_DR       地址20A_C000
*/
    GPIO5_GDIR = 0x08;      

/*****
*4打开GPIO LED
*/
    LED_ON() ;

}

/****
 * 延时控制运行程序
 * 实现大致1ms的单位延时
*/
void delay_ms(volatile unsigned int nms)
{
    unsigned int nus;

    while(nms--)
    {
        //1 ms延时
           nus=0x7ff;
           while(nus--)
           {

           }
    }
}

/**
 * 主main入口程序
*/
int main(void)
{
    clk_enable();       //使能时钟
    led_Init();             //初始化led灯

    //led闪烁循环
    while(1)
    {
        LED_OFF();
        delay_ms(500);
        LED_ON();
        delay_ms(500);
    }
    return 0;
}

代码部分好了,接下来准备一下链接脚本,用于指定编译程序起始地址和顺序

SECTIONS{
            . = 0x87800000;
            .text :
            {
                start.o
                led.o
                *(.text)
            }
            .rodata ALIGN(4)    :   {*(.rodata*)}
            .data   ALIGN(4)    :   {  *(.data) }
            __bss_start = .;
            .bss   ALIGN(4)    :   {  *(.bss) *(COMMON)}
            __bss_end = .;
}

准备Makefile进行起飞编译吧:

objs := start.o led.o 

led.bin : $(objs)
	arm-linux-gnueabihf-ld	-Timxu.lds -o led.elf $^
	arm-linux-gnueabihf-objcopy -O binary -S  led.elf $@

%.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 led.bin led.elf led.dis *.imx

dump:
	arm-linux-gnueabihf-objdump -D -m arm led.elf > led.dis

dowmload:
	./imxdownload led.bin /dev/sdb

试试编译效果:

motiongui@motiongui-VirtualBox:~/work/imxAss/Ledc$ make
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o start.o start.S
arm-linux-gnueabihf-gcc -Wall -nostdlib -c -o led.o led.c
arm-linux-gnueabihf-ld  -Timxu.lds -o led.elf start.o led.o
arm-linux-gnueabihf-objcopy -O binary -S  led.elf led.bin
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值