首页/新闻资讯/正文详情

Linux入门第二部分(ARM裸机篇) 第三章 汇编LED驱动实验

发布时间:2026/11/3 10:46:16 来源:云帆数科 栏目:资讯中心
Linux入门第二部分(ARM裸机篇) 第三章 汇编LED驱动实验
参考教程正点原子【第二期】手把手教你学Linux之ARMMX6U裸机篇_哔哩哔哩_bilibili一、I.MX6ULL IO命名与配置寄存器1、STM32引脚的命名与相关寄存器1在STM32中引脚的命名简单直观比如GPIOA对应有PA0~PA15一组有16个引脚。2在STM32中配置引脚电气属性上下拉、速度、推挽/开漏等的方法是写该引脚对应的GPIO外设寄存器。3STM32F1引脚的复用重映射可通过配置AFIO寄存器实现而F4/H7等系列则是使用GPIO_AFRH/GPIO_AFRL寄存器选择外设复用功能。2、I.MX6ULL引脚的命名与相关寄存器1在I.MX6ULL中一般引脚名的格式为“PAD_xxx”比如“PAD_BOOT_MODE0”。2在I.MX6ULL中每一个I/O引脚都配套两个GPIO外设寄存器①MUX复用寄存器选择这个PAD引脚复用哪一个功能。②PAD电气属性寄存器配置上下拉、速率、驱动能力、开漏、施密特等电气参数。3I.MX6U的GPIO一共有5组——GPIO1、GPIO2、GPIO3、GPIO4和GPIO5其中GPIO1有32个IOGPIO2有22个IOGPIO3有29个IOGPIO4有29个IOGPIO5有12个IO一共有124个GPIO引脚。二、原理分析与引脚配置说明1、LED原理图拆解1LED指示灯电路如下图所示它采用低电平驱动的方式需要给LED0施加低电平才能点亮它。2在原理图中索引“LED0”可以发现它接在“GPIO 3”上应该是“GPIO1_IO3”原理图标注不严谨。2、引脚配置说明1I.MX6ULL的时钟管理配置说明在章节Clock Controller Module(CCM)中其中CCM_CCGRx寄存器控制所有外设时钟的使能与否。①每个外设的时钟配置由2bit位组成定义如下②查看数据手册可知GPIO1的时钟使能控制由CCM_CCGR1寄存器的bit27-26决定为简单起见可直接将其配置为11无论什么时候都将该时钟使能。③由于本文主旨为学习ARM裸机开发不涉及低功耗策略所以为了更简单起见默认将CCM_CCGRx全部设置为0xFFFFFFFF即默认使能所有外设时钟。2在芯片手册找到GPIO1_IO03这个引脚的MUX复用寄存器在章节IOMUX Controller (IOMUXC)的IOMUXC Memory Map/Register Definition小节如下图所示如果希望把该引脚作为普通的GPIO引脚使用应该将MUX_MODE配置成ALT5。3在芯片手册找到GPIO1_IO03这个引脚的PAD电气属性寄存器在章节IOMUX Controller (IOMUXC)的IOMUXC Memory Map/Register Definition小节如下图所示。GPIO的功能图如下寄存器的每个配置项都对应着功能图的一个输入位段定义HYSbit16此位为0时禁止迟滞比较器为1时使能迟滞比较器迟滞比较器用于对输入波形整形PUSbit15:1400表示配置100K下拉电阻01表示配置47K上拉电阻10表示配置100K上拉电阻11表示配置22K上拉电阻PUEbit13当为0时使用状态保持器当为1时使用上下拉模式状态保持器在IO作为输入时才有用如果使用状态保持器当外部电路断电以后此IO口可以保持住以前的状态PKEbit12为0时禁止上下拉电阻/状态保持器为1时使能上下拉电阻和状态保持器ODEbit11此位为0时禁止开路输出当此位为1时使能开路输出功能SPEEDbit7:6当IO用作输出的时候此位用来设置IO速度00表示50M01和10表示100M11表示200MDSEbit5:3设置IO的驱动能力000表示驱动输出关闭其它7个枚举表示不同的驱动能力枚举值越大驱动能力越强SREbit0此位为0时是低压摆率为1时是高压摆率这里的压摆率指的是IO电平跳变所需要的时间比如从0到1需要的时间越短波形就越陡压摆率越高压摆率不是越高越高在高速通信中往往希望压摆率更高但也要注意是否满足EMC需求4I.MX6U一共有GPIO1~GPIO5共五组GPIO每组GPIO都有8个寄存器——DR、GDIR、PSR、ICR1、ICR2、EDGE_SEL、IMR和ISR把它们当作普通GPIO引脚使用时需要设置这些寄存器寄存器的每个位对应一个GPIO引脚。①DR数据寄存器用于保存IO引脚对应的电平值在输出模式下如果希望某组GPIO的一个引脚输出对应的电平值就在DR寄存器对应位写入该电平值即可在输入模式下可以通过访问DR寄存器的某个位获取对应IO引脚当前的电平值。如果希望GPIO1_IO03引脚输出低电平应该将GPIO1_DR的bit3配置成0。寄存器地址为基地址0H offest②GDIR方向寄存器用于设置GPIO引脚的工作方向可配置为输入模式或输出模式。如果希望把GPIO1_IO03引脚作为输出引脚使用应该将GPIO1_GDIR的bit3配置成OUTPUT。寄存器地址为基地址4H offest③PSR状态寄存器是只读寄存器只有在访问时该寄存器才会对输入信号进行采样所以每次访问它时都需要两个等待状态以进行同步。寄存器地址为基地址8H offest④ICR1和ICR2都是中断控制寄存器ICR1用于配置低16个GPIOICR2用于配置高16个GPIO下图仅示出ICR1寄存器ICR15的定义其它位段定义可以此类推00表示低电平触发01表示高电平触发10表示上升沿触发11表示下降沿触发。ICR1寄存器地址为基地址CH offestICR2寄存器地址为基地址10H offest⑤IMR中断屏蔽寄存器用于控制GPIO的中断禁止或使能。寄存器地址为基地址14H offest⑥ISR中断状态寄存器用于保存GPIO中断标志位当GPIO发生中断时其对应的标志位会被置位不过它不会自动清除所以在中断处理完成后需要在程序中手动清除中断标志位方法是向需要清除的位写1清零。寄存器地址为基地址18H offest⑦EDFE_SEL边沿选择寄存器用于设置边沿中断它会覆盖ICR1和ICR2的设置。寄存器地址为基地址1CH offest⑧寄存器的地址可参考数据手册的GPIO memory map下图仅示出GPIO1相关寄存器的地址。在数据手册中任意一个外设寄存器的介绍页面都会标有该寄存器的地址三、驱动程序编写与编译1、使用汇编语言配置引脚1在第一章中搭建开发环境时在用户目录下建立了一个linux文件夹现在在这个文件夹中新建一个名为“IMX6ULL”的文件夹该文件夹用于存放I.MX6ULL相关的工程文件然后在该文件夹下继续新建一个名为“Board_Drivers”的文件夹用于存放项目工程。2在Board_Drivers文件夹中新建文件夹“1_leds”然后在该文件夹中新建led.s文件本小节的LED驱动汇编代码将写在该文件中。3在led.s文件中先将程序基本框架搭起来如下所示.global _start 全局标号 _start: 驱动代码待编写 loop: b loop 死循环相当于C语言的while(1)4添加汇编代码使能所有外设时钟如下所示 使能所有外设时钟 ldr r1, 0xffffffff 往r1中写入0xffffffff ldr r0, 0x020c4068 将CCGR0的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 ldr r0, 0x020c406c 将CCGR1的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 ldr r0, 0x020c4070 将CCGR2的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 ldr r0, 0x020c4074 将CCGR3的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 ldr r0, 0x020c4078 将CCGR4的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 ldr r0, 0x020c407c 将CCGR5的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 ldr r0, 0x020c4080 将CCGR6的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器5添加汇编代码配置GPIO1_IO03的复用寄存器如下所示 配置IO复用将IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的MUX_MODE配置为ALT5 即配置GPIO1_IO03复用为普通GPIO ldr r1, 0x5 往r1中写入0x5 ldr r0, 0x020e0068 将IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器6添加汇编代码配置GPIO1_IO03的电气属性寄存器如下所示 配置IO电气属性操作IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 bit0 0 —— 压摆率配置为低速率 bit5:3 110 —— R0/6驱动能力 bit7:6 10 —— 100MHz的速率 bit11 0 —— 关闭开路输出 bit12 1 —— 使能上下拉电阻和状态保持器 bit13 0 —— 使用状态保持器 bit15:14 00 —— 100K下拉电阻 bit16 0 —— 关闭迟滞比较器 ldr r1, 0x10b0 往r1中写入0x10b0 ldr r0, 0x020e02f4 将IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器7添加汇编代码配置GPIO1_IO03的GPIO功能寄存器如下所示 配置GPIO功能 ldr r1, 0x8 往r1中写入0x8设置GPIO1_GPIO03为输出模式 ldr r0, 0x0209c004 将GPIO1_GDIR的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 ldr r1, 0x0 往r1中写入0x0设置GPIO1_GPIO03输出低电平0 ldr r0, 0x0209c000 将GPIO1_DR的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器【LED灯被点亮】8最终led.s的文件内容如下所示.global _start 全局标号 _start: 使能所有外设时钟 ldr r1, 0xffffffff 往r1中写入0xffffffff ldr r0, 0x020c4068 将CCGR0的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 ldr r0, 0x020c406c 将CCGR1的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 ldr r0, 0x020c4070 将CCGR2的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 ldr r0, 0x020c4074 将CCGR3的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 ldr r0, 0x020c4078 将CCGR4的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 ldr r0, 0x020c407c 将CCGR5的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 ldr r0, 0x020c4080 将CCGR6的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 配置IO复用将IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的MUX_MODE配置为ALT5 即配置GPIO1_IO03复用为普通GPIO ldr r1, 0x5 往r1中写入0x5 ldr r0, 0x020e0068 将IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 配置IO电气属性操作IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 bit0 0 —— 压摆率配置为低速率 bit5:3 110 —— R0/6驱动能力 bit7:6 10 —— 100MHz的速率 bit11 0 —— 关闭开路输出 bit12 1 —— 使能上下拉电阻和状态保持器 bit13 0 —— 使用状态保持器 bit15:14 00 —— 100K下拉电阻 bit16 0 —— 关闭迟滞比较器 ldr r1, 0x10b0 往r1中写入0x10b0 ldr r0, 0x020e02f4 将IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 配置GPIO功能 ldr r1, 0x8 往r1中写入0x8设置GPIO1_GPIO03为输出模式 ldr r0, 0x0209c004 将GPIO1_GDIR的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器 ldr r1, 0x0 往r1中写入0x0设置GPIO1_GPIO03输出低电平0 ldr r0, 0x0209c000 将GPIO1_DR的地址写入r0 str r1, [r0] 将r1中的数据写入r0指向的寄存器【LED灯被点亮】 loop: b loop 死循环相当于C语言的while(1)2、程序编译与链接1该程序编写完成后需要编译出能够在ARM开发板上运行的可执行文件因此需要使用交叉编译器arm-linux-gnueabihf-gcc由于本节只有一个源文件整个编译流程比较简单。2首先将led.s编译为对应的.o文件命令为“arm-linux-gnueabihf-gcc -g -c led.s -o led.o”文件名视具体情况替换其中“-g”选项用于产生调试信息供GDB使用“-c”选项指定编译源文件但是不链接“-o”选项指定编译产生文件的名字执行该命令后当前目录下将产生一个led.o文件。3arm-linux-gnueabihf-ld用于将众多的.o文件链接到一个指定的链接位置这个指定位置就是上电后第一条运行代码的地址不一定是第一条代码存储的地址。①对于6ULL来说链接起始地址应该指向RAM地址几乎所有Cortex-A芯片内部都没有Flash。②本文所有裸机例程如无特殊说明可执行文件都是烧写到SD卡中上电以后I.MX6U的内部boot rom程序芯片出厂自带一段固化在芯片内部的小程序会将可执行文件拷贝到链接地址处这个链接地址可以在I.MX6U的内部128KB RAM中0X900000~0X91FFFF也可以在外部的DDR中本文所有裸机例程的链接地址都在DDR中链接起始地址为0X87800000。③I.MX上电的时候DDR没有初始化由于DDR是外部内存那么外部内存中的.bin文件不能直接运行需要添加一个头部这个头部叫IVT镜像向量表DCD设备配置数据DCD里写了DDR控制器寄存器配置DDR初始化参数Boot ROM自动从SD卡/eMMC读出这个头部按照DCD里面的参数把DDR初始化再把.bin代码拷贝到DDR中最后跳过去执行所拷贝的代码。基于这一点.bin的代码实际被拷贝到DDR里的地址必须与链接起始地址一致位置无关代码除外。④确定链接地址为0X87800000后可以使用命令“arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf”链接文件名视具体情况替换生成.elf格式的可执行文件“-o”选项指定编译产生文件的名字执行该命令后当前目录下将产生一个led.elf文件。4最终烧写到SD卡中的可执行文件需要是.bin格式的对此可使用arm-linux-gnueabihf-objcopy工具命令为“arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin”文件名视具体情况替换“-O”选项指定以何种格式输出文件“binary”表示二进制格式“-S”选项表示不要复制源文件中的重定位信息和符号信息“-g”选项表示不复制源文件中的调试信息执行该命令后当前目录下将产生一个led.bin文件。5大多数情况下都是用C语言写代码有时候需要查看其汇编代码来调试代码这时需要进行反汇编一般可以将.elf文件反汇编命令为“arm-linux-gnueabihf-objdump -D led.elf led.dis”文件名视具体情况替换“-D”选项表示反汇编所有段反汇编完成以后在当前目录下出现一个名为led.dis文件。3、Makefile文件编写1每次编译程序都要运行上面的指令当项目工程越来越大时纯敲指令的方式会特别麻烦为了简化编译步骤可以使用上一部分介绍的Makefile文件。2在工程根目录下创建一个名为“Makefile”的文件然后在文件中输入以下内容后续只需要在工程根目录执行一次“make”就可以完成程序的编译。led.bin:led.s arm-linux-gnueabihf-gcc -g -c led.s -o led.o arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin arm-linux-gnueabihf-objdump -D led.elf led.dis clean: rm -rf *.o led.bin led.elf led.dis # 执行“make clean”可清除编译结果文件四、程序烧写1、imxdownload1本文例程使用正点原子开发的imxdownload制作.bin文件的头部以及实现SD卡烧写该软件或者说脚本仅适用于NXP的I.MX6U系列芯片。2imxdownload的源码如下可在Ubuntu中直接用gcc编译器编译出可执行文件类型为文件无后缀。①imxdownload.h文件#ifndef _IMXDOWNLOAD_H #define _IMXDOWNLOAD_H /* IMX6U IVT DCD表信息 暂时定义为1K Bytes此表是读取的u-boot.imx前1K Bytes * imx6_ivedcd_table[9]是指明代码长度的本应该根据实际的代码长度来修改 * 这里为了方便就直接定义为2M Bytes即 */ const int imx6_512mb_ivtdcd_table[256] { 0X402000D1,0X87800000,0X00000000,0X877FF42C,0X877FF420,0X877FF400,0X00000000,0X00000000, 0X877FF000,0X00200000,0X00000000,0X40E801D2,0X04E401CC,0X68400C02,0XFFFFFFFF,0X6C400C02, 0XFFFFFFFF,0X70400C02,0XFFFFFFFF,0X74400C02,0XFFFFFFFF,0X78400C02,0XFFFFFFFF,0X7C400C02, 0XFFFFFFFF,0X80400C02,0XFFFFFFFF,0XB4040E02,0X00000C00,0XAC040E02,0X00000000,0X7C020E02, 0X30000000,0X50020E02,0X30000000,0X4C020E02,0X30000000,0X90040E02,0X30000000,0X88020E02, 0X30000C00,0X70020E02,0X00000000,0X60020E02,0X30000000,0X64020E02,0X30000000,0XA0040E02, 0X30000000,0X94040E02,0X00000200,0X80020E02,0X30000000,0X84020E02,0X30000000,0XB0040E02, 0X00000200,0X98040E02,0X30000000,0XA4040E02,0X30000000,0X44020E02,0X30000000,0X48020E02, 0X30000000,0X1C001B02,0X00800000,0X00081B02,0X030039A1,0X0C081B02,0X0B000300,0X3C081B02, 0X44014801,0X48081B02,0X302C4040,0X50081B02,0X343E4040,0X1C081B02,0X33333333,0X20081B02, 0X33333333,0X2C081B02,0X333333F3,0X30081B02,0X333333F3,0XC0081B02,0X09409400,0XB8081B02, 0X00080000,0X04001B02,0X2D000200,0X08001B02,0X3030331B,0X0C001B02,0XF3526B67,0X10001B02, 0X630B6DB6,0X14001B02,0XDB00FF01,0X18001B02,0X40172000,0X1C001B02,0X00800000,0X2C001B02, 0XD2260000,0X30001B02,0X23106B00,0X40001B02,0X4F000000,0X00001B02,0X00001884,0X90081B02, 0X00004000,0X1C001B02,0X32800002,0X1C001B02,0X33800000,0X1C001B02,0X31800400,0X1C001B02, 0X30802015,0X1C001B02,0X40800004,0X20001B02,0X00080000,0X18081B02,0X27020000,0X04001B02, 0X2D550200,0X04041B02,0X06100100,0X1C001B02,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000 }; const int imx6_256mb_ivtdcd_table[256] { 0X402000D1,0X87800000,0X00000000,0X877FF42C,0X877FF420,0X877FF400,0X00000000,0X00000000, 0X877FF000,0X00076000,0X00000000,0X40E801D2,0X04E401CC,0X68400C02,0XFFFFFFFF,0X6C400C02, 0XFFFFFFFF,0X70400C02,0XFFFFFFFF,0X74400C02,0XFFFFFFFF,0X78400C02,0XFFFFFFFF,0X7C400C02, 0XFFFFFFFF,0X80400C02,0XFFFFFFFF,0XB4040E02,0X00000C00,0XAC040E02,0X00000000,0X7C020E02, 0X30000000,0X50020E02,0X30000000,0X4C020E02,0X30000000,0X90040E02,0X30000000,0X88020E02, 0X30000C00,0X70020E02,0X00000000,0X60020E02,0X30000000,0X64020E02,0X30000000,0XA0040E02, 0X30000000,0X94040E02,0X00000200,0X80020E02,0X30000000,0X84020E02,0X30000000,0XB0040E02, 0X00000200,0X98040E02,0X30000000,0XA4040E02,0X30000000,0X44020E02,0X30000000,0X48020E02, 0X30000000,0X1C001B02,0X00800000,0X00081B02,0X030039A1,0X0C081B02,0X04000000,0X3C081B02, 0X3C013C01,0X48081B02,0X38324040,0X50081B02,0X28304040,0X1C081B02,0X33333333,0X20081B02, 0X33333333,0X2C081B02,0X333333F3,0X30081B02,0X333333F3,0XC0081B02,0X09409400,0XB8081B02, 0X00080000,0X04001B02,0X2D000200,0X08001B02,0X3030331B,0X0C001B02,0XF352433F,0X10001B02, 0X630B6DB6,0X14001B02,0XDB00FF01,0X18001B02,0X40172000,0X1C001B02,0X00800000,0X2C001B02, 0XD2260000,0X30001B02,0X23104300,0X40001B02,0X47000000,0X00001B02,0X00001883,0X90081B02, 0X00004000,0X1C001B02,0X32800002,0X1C001B02,0X33800000,0X1C001B02,0X31800400,0X1C001B02, 0X30802015,0X1C001B02,0X40800004,0X20001B02,0X00080000,0X18081B02,0X27020000,0X04001B02, 0X2D550200,0X04041B02,0X06100100,0X1C001B02,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, 0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000, }; #endif②imxdownload.c文件#include stdio.h #include stdlib.h #include string.h #include imxdownload.h #define SHELLCMD_LEN (200) #define BIN_OFFSET (3072) /* 此宏指明是否打印u-boot.imx的IVT DCD表信息不同的开发板其IVT和DCD * 表的数据是不同的因此需要获取所使用的开发板的IVT和DCD表信息最 * 简单的方法就是读取开发板配套资料里面的u-boot.imx的前1KB数据理论上 * 应该读取3KB的数据但是表信息远远没有3K这么多因此读1KB即可 */ #define PRINT_TAB 0 /* * 介绍 此软件是针对NXP的IMX6U系列芯片的软件用来烧写bin文件到SD卡里面 * 本软件会自动添加IVT、DCD等信息到原始的bin文件里面主要用于裸机和uboot的烧写。 * 使用方法 1、编译好原始的二进制bin文件如u-boot.bin等并将编译好的.bin文件和本 * 软件放置到同一个目录下 * 2、执行命令sudo ./imxdownload soucre_bin sd_device * 如烧写u-boot.bin到/dev/sdd中即可使用如下所示命令: * sudo ./imxdownload u-boot.bin /dev/sdd */ /* * 输出一些信息 */ void message_print(void) { printf(I.MX6ULL bin download software\r\n); printf(Edit by:zuozhongkai\r\n); printf(Date:2019/6/10\r\n); printf(Version:V1.1\r\n); printf(log:V1.0 initial version,just support 512MB DDR3\r\n); printf( V1.1 and support 256MB DDR3\r\n); } int main(int argc, char *argv[]) { FILE *fp; unsigned char *buf; unsigned char *cmdbuf; int nbytes, filelen; int i 0, j 0; int ddrsize 0; /* 0为512MB1为256MB2为128MB...... */ message_print(); if((argc ! 3) (argc ! 4)){ printf(Error Usage! Reference Below:\r\n); printf(sudo ./%s -512m or -256m source_bin sd_device\r\n, argv[0]); return -1; } /* 查找参数获取DDR容量 */ for(i 0; i argc; i) { char *param argv[i]; if(param[0] ! -) continue; if(strcmp(param, -256m) 0) /* 256MB */ ddrsize 1; else if(strcmp(param, -512m) 0) /* 512MB */ ddrsize 0; } if(argc 3) /* 三个参数也就是不输入DDR容量的话默认为512MB */ ddrsize 0; /* 打开bin文件 */ fp fopen(argv[1], rb); /* 以二进制只读方式打开bin文件 */ if(fp NULL){ printf(Cant Open file %s\r\n, argv[1]); return -1; } /* 获取bin文件长度 */ fseek(fp, 0L, SEEK_END); filelen ftell(fp); fseek(fp, 0L, SEEK_SET); printf(file %s size %dBytes\r\n, argv[1], filelen); /* 读取bin文件到缓冲区buf中 */ buf malloc(filelen BIN_OFFSET); if(buf NULL){ printf(Mem Malloc Failed!\r\n); fclose(fp); return -1; } memset(buf, 0, filelen BIN_OFFSET); /* 清零 */ /* 读取bin源码文件 */ fread(buf BIN_OFFSET, 1, filelen, fp); /* 关闭文件 */ fclose(fp); #if PRINT_TAB printf(IVT DCD Table:\r\n); for(i 0; i 1024/32; i){ for(j 0; j 8; j) { printf(0X%08X,,*(int *)(buf BIN_OFFSET (((i * 8) j) * 4))); } printf(\r\n); } free(buf); return 0; #endif /* 添加IVT DCD等表信息到bin文件里面 */ if(ddrsize 0) { /* 512MB */ printf(Board DDR SIZE: 512MB\r\n); memcpy(buf, imx6_512mb_ivtdcd_table, sizeof(imx6_512mb_ivtdcd_table)); } else if (ddrsize 1) { /* 256MB */ printf(Board DDR SIZE: 256MB\r\n); memcpy(buf, imx6_256mb_ivtdcd_table, sizeof(imx6_256mb_ivtdcd_table)); } /* 现在已经在buf中构建好了可以用于下载的bin文件将buf中的数据保存到 * 到一个文件中文件命名为load.imx */ printf(Delete Old load.imx\r\n); system(rm -rf load.imx); /* 先删除旧的load.imx文件 */ printf(Create New load.imx\r\n); system(touch load.imx); /* 创建新的load.imx文件 */ fp fopen(load.imx, wb); /* 打开laod.imx */ if(fp NULL){ printf(Cantt Open load.imx!!!\r\n); free(buf); return -1; } nbytes fwrite(buf, 1, filelen BIN_OFFSET, fp); if(nbytes ! (filelen BIN_OFFSET)){ printf(File Write Error!\r\n); free(buf); fclose(fp); return -1; } free(buf); fclose(fp); /* 构建烧写的shell命令 */ cmdbuf malloc(SHELLCMD_LEN); sprintf(cmdbuf, sudo dd iflagdsync oflagdsync ifload.imx of%s bs512 seek2,argv[2]); printf(Download load.imx to %s ......\r\n, argv[2]); /* 执行上面的shell命令 */ system(cmdbuf); free(cmdbuf); return 0; }2、IVTDCD的制作与软件烧写步骤1将imxdownload拷贝到工程的根目录下也就是和led.bin处于同一个文件夹下并赋予其可执行权限。2准备一张全新的SD卡烧写过程中会格式化SD卡必须保证SD卡中没有重要文件通过读卡器将它接入虚拟机Ubuntu可通过在dev文件夹中运行“ls /dev/sd*”确认SD卡是否成功接入虚拟机。3需要注意的是将固件烧写到SD卡中并不是直接把.bin文件拷贝进去而是将.bin文件烧写到SD卡的绝对地址上而且对于I.MX而言所烧写的.bin文件还需要在烧写前添加头部不过这一系列操作都可以由imxdownload一步完成。4使用imxdownload向SD卡烧写.bin文件命令格式如下烧写完成以后会在当前工程目录下生成一个load.imx的文件这个文件就是所谓的头部二进制代码文件也是最终烧写到SD卡中的文件。./imxdownload .bin file SD Card# ./imxdownload led.bin /dev/sdb 将led.bin文件烧写到/dev/sdb设备中5将SD卡插到开发板的SD卡槽中然后设置拨码开关为SD卡启动模式拨码开关设置如下图所示设置好后按下开发板的复位键如果代码运行正常LED0会被点亮。

相关推荐

一句“做个有禅意的庭院”,AI给你一坨飘着的方块:5类最容易翻车的提示词,附对照改法
一句“做个有禅意的庭院”,AI给你一坨飘着的方块:5类最容易翻车的提示词,附对照改法

一句“做个有禅意的庭院”,AI给你一坨飘着的方块:5类最容易翻车的提示词,附对照改法 最近 3D 圈子里有个小模型挺火,本地跑、只有 2.5G,输入一句话,就能给你吐出整个 3D 场景,双击打开就能转着圈… · 2026/11/3 10:46:16

超级具身智能(SEI):FRA架构下云边端协同计算与资源动态调度机制
超级具身智能(SEI):FRA架构下云边端协同计算与资源动态调度机制

前沿技术探索:FRA核心定义与设计理念 FRA(Factorized Robotic Agent, FRA,亦称:因式分解机器人智能体)是一套因式化数实融合一体化新型智能系统,核心设计理念是全链路系统解耦,将机器人作业的感知、推理、动作执行三大核心能力拆解为独立平行子模块,整合为统一、闭环、… · 2026/11/3 10:45:15

彻底砍掉LeetCode面试!
彻底砍掉LeetCode面试!

最近一周AI科技圈又发生了啥? OpenAI宣布ChatGPT Pro使用额度翻倍 OpenAI核心产品负责人Tibo宣布,所有ChatGPT Pro及Business Premium用户的使用限额即日起翻倍,属于其"28天持续改进"计划的第25天更新。此前9月底Pro 200新订用户用… · 2026/11/3 10:45:15

70亿参数重塑音频智能:Kimi-Audio开源模型开启多模态交互新纪元
70亿参数重塑音频智能:Kimi-Audio开源模型开启多模态交互新纪元

70亿参数重塑音频智能:Kimi-Audio开源模型开启多模态交互新纪元 【免费下载链接】Kimi-Audio-7B 我们推出 Kimi-Audio,一个在音频理解、生成与对话方面表现卓越的开源音频基础模型。本仓库提供 Kimi-Audio-7B 的模型检查点。 项目地址: https://ai.git… · 2026/11/3 18:44:26

项目02--JsonRpc
项目02--JsonRpc

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 18:44:26

210亿参数仅激活30亿:ERNIE-4.5轻量化模型如何重塑企业AI格局
210亿参数仅激活30亿:ERNIE-4.5轻量化模型如何重塑企业AI格局

210亿参数仅激活30亿:ERNIE-4.5轻量化模型如何重塑企业AI格局 导语:用1/3成本实现92%复杂推理准确率,百度ERNIE-4.5-21B-A3B-Thinking重新定义企业级AI效率标准 行业现状:大模型落地的"三重困境" 2025年全球AI市场呈… · 2026/11/3 18:43:23

字节跳动发布ByteFF-Pol模型:AI驱动分子模拟革新,重塑计算化学产业格局
字节跳动发布ByteFF-Pol模型:AI驱动分子模拟革新,重塑计算化学产业格局

字节跳动发布ByteFF-Pol模型:AI驱动分子模拟革新,重塑计算化学产业格局 【免费下载链接】byteff2 项目地址: https://ai.gitcode.com/hf_mirrors/ByteDance-Seed/byteff2 2025年11月10日,字节跳动正式推出基于图神经网络(… · 2026/11/3 18:43:23

如何用8GB显卡玩转4K视频生成:阿里WanVideo_comfy完整指南
如何用8GB显卡玩转4K视频生成:阿里WanVideo_comfy完整指南

如何用8GB显卡玩转4K视频生成:阿里WanVideo_comfy完整指南 在AI视频生成领域,专业工具普遍存在"高门槛、高成本、高复杂度"的三高问题,让普通创作者望而却步。阿里巴巴通义万相团队开源的WanVideo_comfy项目通过ComfyUI生态实现电… · 2026/11/3 18:43:23

WanVideo_comfy:8GB显存玩转电影级视频生成,ComfyUI生态终极解决方案
WanVideo_comfy:8GB显存玩转电影级视频生成,ComfyUI生态终极解决方案

WanVideo_comfy:8GB显存玩转电影级视频生成,ComfyUI生态终极解决方案 2025年AI视频生成领域迎来重大技术突破,阿里巴巴通义万相开源的WanVideo_comfy项目通过创新量化技术和模块化设计,将14B参数的大型模型压缩至消费级GPU可运行的… · 2026/11/3 18:43:23

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46

STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码