Alientek I.MX6UL Linux- 第十章 C语言版LED实验

  主要内容,弄清楚进入C语言环境需要两部分文件,汇编文件和C语言文件,汇编文件主要作用是用来初始化C语言环境的,比如DDR和设置堆栈指针SP等等。

汇编文件(示例代码10.3.1.2 start.s文件代码)

汇编文件主要内容:
其一设置处理器模式为SVC(超级管理员模式)主要操作特殊寄存器CPSR;
其二设置栈指针为0x80200000;
其三跳转到C语言的Main函数。

/*************************************************************** Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved. 
文件名 : start.s 
作者 : 左忠凯 
版本 : V1.0 
描述 : I.MX6U-ALPHA/I.MX6ULL开发板启动文件,完成C环境初始化, C环境初始化完成以后跳转到C代码。 
其他 : 无 
日志 : 初版 2019/1/3 左忠凯修改 **************************************************************/
.global _start   /*全局标号*/
/*
 *描述: _start函数,程序从此函数开始执行,此函数主要功能是设置C运行环境
 */
 _start:
 /*进入SVC模式*
 mrs r0,cpsr
 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函数*/

头文件(示例代码10.3.2.1 main.h文件代码 )

#ifndef __MAIN_H 
#define __MAIN_H 
/******************************************************************
 Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved. 
 文件名 : main.h 
 作者 : 左忠凯 
 版本 : V1.0 
 描述 : 时钟GPIO1_IO03相关寄存器地址定义。 
 其他 : 无
 日志 : 初版V1.0 2019/1/3 左忠凯创建 
 *****************************************************************/
  /* 
   * 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

源文件(示例代码10.3.2.2 main.c文件代码)

/************************************************************** 
Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved. 
文件名 : main.c 
作者 : 左忠凯 
版本 : V1.0 
描述 : I.MX6U开发板裸机实验2 C语言点灯
	  使用C语言来点亮开发板上的LED灯,学习和掌握如何用C语言来 
	  完成对I.MX6U处理器的GPIO初始化和控制。 
其他 : 无 
日志 : 初版V1.0 2019/1/3 左忠凯创建 **************************************************************/
	#include "main.h" 
	/* 
	 * @description : 使能I.MX6U所有外设时钟 
	 *  @param : 无 
	 * @return : 无
	 */ 
		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; 
		} 
		 /*
		  * @description : 初始化LED对应的GPIO
		  * @param : 无
		  * @return : 无
		  */ 
		  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; 
		    } 
    /* 
     * @description : 打开LED灯 
     * @param : 无
     * @return : 无
     */ 
		void led_on(void)
		{ 
			/* 
			* 将GPIO1_DR的bit3清零 
			*/ 
			GPIO1_DR &= ~(1<<3);
		 }
    /* 
     * @description :  关闭LED灯 
     * @param : 无
     * @return : 无
     */ 
		void led_off(void) 
		{ 
		  /* 
		   * 将GPIO1_DR的bit3置1 
		   * /
		  GPIO1_DR |= (1<<3);
		 } 
       /*
        * @description : 短时间延时函数 
        * @param - n : 要延时循环次数(空操作循环次数,模式延时) 
        * @return : 无 
        */ 
       void delay_short(volatile unsigned int n)
       { 
      	 while(n--){}
       } 
       /*
        *@description : 延时函数,在396Mhz的主频下延时时间大约为1ms86 
        *@param - n: 要延时的ms数87 
        *@return: 无88 */
        void delay(volatile unsigned int n)
        { 
	        while(n--) 
	        { 
	       	 delay_short(0x7ff);
	        } 
        } 
        /* 
         *@description : mian函数
         *@param: 无
         * @return: 无
         */
         int main(void) 
         { 
	          clk_enable();
	          /* 使能所有的时钟*/ 
	          led_init(); /* 初始化led*/
	          while(1) /* 死循环*/
	          { 
		          led_off(); /* 关闭LED*/
		          delay(500); /* 延时大约500ms*/ 
		          led_on(); /* 打开LED*/
		          delay(500); /* 延时大约500ms*/
	          } 
	          return 0;
          }

Makefile文件(示例代码10.4.1.1 main.c文件代码)

将C文件和S文件编译成目标文件,再将目标文件链接到地址0X87800000,生成bin文件。

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 -O2 -o $@ $< 
 %.o:%.S 
	  arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $< 
 %.o:%.c 
	  arm-linux-gnueabihf-gcc -Wall -nostdlib -c -O2 -o $@ $< 
 clean: 
	 rm -rf *.o ledc.bin ledc.elf ledc.dis

imx6ul.lds文件(示例代码10.4.2.2 imx6ul.lds链接脚本代码)

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

你可能感兴趣的:(Alientek I.MX6UL Linux- 第十章 C语言版LED实验)