刚开始学习I.MX6Ull的裸机开发,这里来记录一下今天的学习,本文章适合想要开始学习Linux驱动开发的朋友,内容简单,利用的是正点原子的视频与开发板,只是讲了开发步骤,对细节感兴趣的也可以去看看正点原子的视频。
一、ARM汇编基础与STM32单片机不同,stm32开发板的启动文件中已经将SP指针初始化、DDR初始化。正点原子的Linux开发板并没有初始化这些,所以C语言环境还没准备好,不能直接运行C语言代码,我们利用汇编语言将C语言环境搭建好后就可以执行C语言代码了。这里刚开始只介绍了两个常用并且十分重要的指令,LDR、STR。他们是存储器访问指令,由于ARM不能直接的访问存储器,所以一般是我们将需要配置的值先保存到寄存器中,然后借助存储器访问指令将通用寄存器的的配置数据写入到I.MX6LL寄存器中。
1、LDR指令
1 LDR R0, =0x0209C004 @将寄存器地址 0x0209C004 加载到 R0 中,即 R0=0x0209C004 2 LDR R1, [R0] @读取地址 0x0209C004 中的数据到 R1 寄存器中
2、STR指令
1 LDR R0, =0x0209C004 @将寄存器地址 0x0209C004 加载到 R0 中,即 R0=0x0209C004 2 LDR R1, =0x20000002 @R1 保存要写入到寄存器的值,即 R1=0x20000002 3 STR R1, [R0] @将 R1 中的值写入到 R0 中所保存的地址中
需要注意的是这两个指令都是 *** 控32位数据。如果需要按照字节与半字进行 *** 作的话需要给LDR、STR后面分别加上B或者H。LDRB、LDRH。
二、汇编LED灯实验点灯是单片机的灵魂,就如各种编程的hello world一样,下面就是正点原子提供给我们的点灯代码。
利用STM32点灯的时候我们是先进行初始化,初始化就包括了使能端口时钟、端口配置、设置高低电平控制灯的开关。Linux开发板也是如此,只不过用汇编控制寄存器的方式来实现。首先我们先看他和STM32GPIO口的命名有什么不同,STM32 中的 IO 都是 PA0~15、PB0~15 这样命名的,而I.MX6ULL 的 IO 命名规则是IOMUXC_SW_MUX_CTL_PAD_xx_IOxx。根据这两个xx也可以判断出引脚是什么功能,如GPIO1_IO01、UART1_TX_DATA、JTAG_MOD。之后我们再看I.MX6ULL的点灯过程。由于板上的LED内部已经连接了GPIO1_IO03,所以我们直接对GPIO1_IO03进行配置即可:1、使能 GPIO1 时钟 2、设置 GPIO1_IO03 的复用功能 3、配置 GPIO1_IO03 4、设置 GPIO。与STM32的初始化并没有太大的区别。下面就是具体初始化的代码,都是通过控制寄存器上每个位来实现初始化。
.global _start _start: ldr r0, =0x020C4068 ldr r1, =0xFFFFFFFF str r1, [r0] ldr r0, =0x020C406C str r1, [r0] ldr r0, =0x020C4070 str r1, [r0] ldr r0, =0x020C4074 str r1, [r0] ldr r0, =0x020C4078 str r1, [r0] ldr r0, =0x020C407C str r1, [r0] ldr r0, =0x020C4080 str r1, [r0] ldr r0, =0x020E0068 ldr r1, =0X5 str r1,[r0] ldr r0, =0x020E02F4 ldr r1, =0x10B0 str r1,[r0] ldr r0, =0x0209C004 ldr r1, =0x0000008 str r1,[r0] ldr r0, =0x0209C000 ldr r1, =0 str r1,[r0] loop: b loop
以上代码就是I.MX6ULL的点灯程序,只使用的LDR、STR两个指令,对没有汇编基础的小新也是很友好的。第 2 行定义了一个全局标号_start,_start相当于内存地址,代码就是从_start 这个标号开始顺序往下执行的,很像C语言的函数。
三、编译下载代码验证这里就利用到了交叉编译工具。
1、arm-linux-gnueabihf-gcc -g -c led.s -o led.o
命令就是将 led.s 编译为 led.o,其中“-g”选项是产生调试信息,GDB 能够使用这些 调试信息进行代码调试。“-c”选项是编译源文件,但是不链接。“-o”选项是指定编译产生的文 件名字,这里我们指定 led.s 编译完成以后的文件名字为 led.o。执行上述命令以后就会编译生成一个 led.o 文件。
2、arm-linux-gnueabihf-ld -Ttext 0x87800000 led.o -o led.elf
链接文件,就是将所有.o文件链接到一个指定的链接位置。上述命令中-Ttext 就是指定链接地址,“-o”选项指定链接生成的 elf 文件名,这里我们命名 为 led.elf。上述命令执行完以后就会在工程目录下多一个 led.elf 文件。
3、arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
格式准换,由于led.elf 文件也不是我们最终烧写到 SD 卡中的可执行文件,我们要烧写的.bin 文件,因此还需要将 led.elf 文件转换为.bin 文件。就是上述命令。上述命令中,“-O”选项指定以什么格式输出,后面的“binary”表示以二进制格式输出, 选项“-S”表示不要复制源文件中的重定位信息和符号信息,“-g”表示不复制源文件中的调试信息。
以上的步骤其实可以写成一个Makefile文件,make一下就可以执行完,很方便。以后会写一个关于Makefile的博客,这里就不提了。
4、此时的.bin文件并不能直接的烧入到I.MX6U,因为其内部没有flash,96K的ROM我们用户也不可以调用。所以我们可以从外置的存储介质来烧入代码。我使用的是SD卡。这个步骤需要使用正点原子提供的imxdownload裸机烧写软件。将他copy到工程根目录下与led.bin在一起,之后还要修改imxdownload的文件权限,利用Linux的一个命令chmod给文件可执行的权限。最后执行./imxdownload led.bin /dev/sdd 执行后文件夹多了一个load.imx文件,他其实就是imxdownload给led.bin文件加了一些数据头以后生成的。这里有些是Linux的基础知识,不懂得话一定要先学会使用Linux在开始Linux驱动的学习。
下来就可以在裸机上验证了,记得把BOOT_CFG调成以下状态:
设置好后按下复位键,等初始化完成后就可以看到灯亮了。
这里只是记录了点灯的过程,让新人们有个大概的思路,细节还是要看正点原子的文档,讲的很好。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)