历史上的今天
返回首页

历史上的今天

今天是:2024年10月29日(星期二)

正在发生

2021年10月29日 | Linux之ARM(IMX6U)裸机汇编LED驱动实验--烧写bin文件到SD卡运行

2021-10-29 来源:eefocus

代码烧写

I.MX6U 虽然内部有 96K 的 ROM,但是这 96K 的 ROM 是 NXP自己用的,不向用户开放。所以相当于说 I.MX6U 是没有内部 flash 的,但是我们的代码得有地方存放啊,为此,I.MX6U 支持从外置的 NOR Flash、NAND Flash、SD/EMMC、SPI NOR Flash和 QSPI Flash 这些存储介质中启动,所以我们可以将代码烧写到这些存储介质中中。在这些存储介质中,除了 SD 卡以外,其他的一般都是焊接到了板子上的,我们没法直接烧写。但是 SD卡是活动的,是可以从板子上插拔的,我们可以将 SD 卡插到电脑上,在电脑上使用软件将.bin文件烧写到 SD 卡中,然后再插到板子上就可以了。其他的几种存储介质是我们量产的时候用到的,量产的时候代码就不可能放到 SD 卡里面了,毕竟 SD 是活动的,不牢固,而其他的都是焊接到板子上的,很牢固。


因此,我们在调试裸机和 Uboot 的时候是将代码下载到 SD 中,因为方便嘛,当调试完成以后量产的时候要将裸机或者 Uboot 烧写到 SPI NOR Flash、EMMC、NAND 等这些存储介质中的。那么,如何将我们前面编译出来的 led.bin 烧写到 SD 卡中呢?肯定有人会认为直接复制led.bin 到 SD 卡中不就行了,错!编译出来的可执行文件是怎么存放到 SD 中的,存放的位置是什么?这个 NXP 是有详细规定的!我们必须按照 NXP 的规定来将代码烧写到 SD 卡中,否则代码是绝对运行不起来的。


2.烧写的工具

把imxdownload.c生成可执行程序

在这里插入图片描述

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

 *             如烧写u-boot.bin到/dev/sdd中即可使用如下所示命令:

 *             sudo ./imxdownload u-boot.bin /dev/sdd

 */


/*

 * 输出一些信息

 */

void message_print(void)

{

printf("I.MX6ULL bin download softwarern");

printf("Edit by:zuozhongkairn");

printf("Date:2019/6/10rn");

printf("Version:V1.1rn");

printf("log:V1.0 initial version,just support 512MB DDR3rn");

printf("    V1.1 and support 256MB DDR3rn");

}


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为512MB,1为256MB,2为128MB...... */


message_print();


if((argc != 3) && (argc != 4)){

printf("Error Usage! Reference Below:rn");

printf("sudo ./%s <-512m or -256m> rn", 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("Can't Open file %srn", argv[1]);

return -1;

}

/* 获取bin文件长度 */

fseek(fp, 0L, SEEK_END);

filelen = ftell(fp);

fseek(fp, 0L, SEEK_SET);

printf("file %s size = %dBytesrn", argv[1], filelen);

/* 读取bin文件到缓冲区buf中 */

buf = malloc(filelen + BIN_OFFSET);

if(buf == NULL){

printf("Mem Malloc Failed!rn");

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:rn");

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("rn");

}

free(buf);

return 0;

#endif

/* 添加IVT DCD等表信息到bin文件里面 */

if(ddrsize == 0) { /* 512MB */

printf("Board DDR SIZE: 512MBrn");

memcpy(buf, imx6_512mb_ivtdcd_table, sizeof(imx6_512mb_ivtdcd_table));

}

else if (ddrsize == 1) { /* 256MB */

printf("Board DDR SIZE: 256MBrn");

memcpy(buf, imx6_256mb_ivtdcd_table, sizeof(imx6_256mb_ivtdcd_table));

}


/* 现在我们已经在buf中构建好了可以用于下载的bin文件,将buf中的数据保存到

* 到一个文件中,文件命名为load.imx

*/

printf("Delete Old load.imxrn");

system("rm -rf load.imx"); /* 先删除旧的load.imx文件 */

printf("Create New load.imxrn");

system("touch load.imx"); /* 创建新的load.imx文件 */

fp = fopen("load.imx", "wb"); /* 打开laod.imx */

if(fp == NULL){

printf("Cant't Open load.imx!!!rn");

free(buf);

return -1;

}

nbytes = fwrite(buf, 1, filelen + BIN_OFFSET, fp);

if(nbytes != (filelen + BIN_OFFSET)){

printf("File Write Error!rn");

free(buf);

fclose(fp);

return -1;

}

free(buf);

fclose(fp);

/* 构建烧写的shell命令 */

cmdbuf = malloc(SHELLCMD_LEN);

sprintf(cmdbuf, "sudo dd iflag=dsync oflag=dsync if=load.imx of=%s bs=512 seek=2",argv[2]);

printf("Download load.imx to %s  ......rn", argv[2]);

/* 执行上面的shell命令 */

system(cmdbuf);

free(cmdbuf);

return 0;

}


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,

推荐阅读

史海拾趣

Devar Inc公司的发展小趣事

Devar Inc公司自创立之初,就致力于在增强现实(AR)领域取得突破。经过多年的研发,公司成功推出了世界上首个用于AR的生成式AI神经网络。这项技术允许用户通过简单的文本提示创建3D对象和其他AR资产,极大地简化了AR内容的创作过程。Devar的AR平台结合了神经网络和云解决方案,让用户能够轻松创建并分享AR内容,开启了AR创作的新时代。

Chiefdom Electronic Co Ltd公司的发展小趣事

面对全球市场的日益开放和竞争,Chiefdom Electronic Co Ltd积极寻求与其他行业巨头的战略合作。通过与全球知名的电子产品制造商、芯片供应商等建立紧密的合作关系,公司不仅获得了更多的技术和市场资源,还进一步提升了自身的品牌影响力和市场份额。这些合作不仅帮助公司拓展了业务领域,还为其在全球电子行业中树立了良好的口碑。

Cygnal Integrated Products Inc公司的发展小趣事

随着市场的不断变化和技术的不断进步,Cygnal意识到需要持续创新以保持竞争力。因此,公司投入大量资源进行研发,成功开发出了基于32位架构的新型微控制器。这款微控制器不仅性能强大,而且功耗极低,非常适合用于便携式设备和物联网应用。这一技术突破使Cygnal在行业中获得了领先地位。

First Sensor公司的发展小趣事

随着市场的不断发展和竞争的加剧,Cygnal意识到需要通过收购来加速其技术和市场的布局。经过一系列谈判和协商,Cygnal成功收购了另一家专注于嵌入式系统技术的公司。这次收购不仅为Cygnal带来了更多的技术和市场资源,还使其能够更好地满足客户的需求并提供更全面的解决方案。收购后,Cygnal通过内部整合和优化,将两家公司的优势融合在一起,形成了更强大的市场竞争力。

无锡友达公司的发展小趣事

面对电子行业的快速发展和智能化趋势,无锡友达积极响应,加快智能化转型和升级。公司不仅在产品设计和生产上引入智能化技术,还通过建立智能化管理系统,提升企业的运营效率和产品质量。此外,无锡友达还积极参与各类行业展会和交流活动,与业界同行共同探讨智能化转型的未来趋势。

Holy Stone公司的发展小趣事

经过多年的发展,Holy Stone成为国内少数涵盖主、被动双通路并拥有制造工厂的多元化公司。公司不仅代理多家国际知名半导体零组件,还通过自主研发和生产,为客户提供完整的解决方案及多样性零组件。这一双通路战略使得Holy Stone能够在激烈的市场竞争中保持领先地位,并成功实现全球布局。公司的产品广泛应用于消费电子、汽车电子等多个领域,满足了全球客户的多样化需求。

问答坊 | AI 解惑

KEIL PDF教程,二,三,四

KEIL PDF教程,二,三,四…

查看全部问答>

如何调试跟踪Android源代码 ZT

Android平台代码很多,关系也很复杂,通常我们调试程序的时候是无法跟踪到Android framework code里的,如果能调试跟踪Android source code将给我们这些初学者带来很多便利,本文将给出一个调试跟踪Android source code 的方法。 1.首先,得到Andr ...…

查看全部问答>

电源杂讯干扰的处理

电源杂讯干扰的处理 创易电子整理出品,创易更懂电子, http://52edk.taobao.com/ 全系列阻容感一本全掌控。…

查看全部问答>

问一个连接错误!大家来看看

错误内容: JiuArmDlg.obj : error LNK2001: unresolved external symbol CLSID_DataLinks JiuArmDlg.obj : error LNK2001: unresolved external symbol IID_IDBPromptInitialize ARMV4IDbg/JiuArm.exe : fatal error LNK1120: 2 unresolved ext ...…

查看全部问答>

AVR 关于 ATmega48 掉电喊醒的问题

正在用ATmega48在做一个东西,需要在不需要的时候进入掉电模式,然后通过INT0进行喊醒。 现在的问题是:需要用低电平持续一段时间才可以喊醒,那么就必须设置INT0为低电平触发,但是我设成低电平触发后,紧接着进入掉电模式,我并没有给唤醒信号 ...…

查看全部问答>

iesample与iesimple浏览器问题!

嘿各位!     在CE5.0上通过GPRS连接上网,当设置APN为CMNET的时候,WWW和WAP网站都能上,但是如果设置为CMWAP用我们的浏览器(仿照iesimple做的)就不能浏览网站,如果用微软自带的浏览器(iesample),设置代理服务器地址为10.0.0.172就 ...…

查看全部问答>

lc谐振,rc谐振,lrc谐振。。。频率响应等问题。

lc谐振,rc谐振,lrc谐振。。。频率响应等问题。…

查看全部问答>

mega128串口问题求教

请大家帮忙看下这段mega128串口程序有什么问题,ICCAVR下的,没法接收数据啊 [code]#include #include //================================== void port_init(void) { PORTA = 0xFF; DDRA  = 0x00; PORTB = 0xFF; DDRB ...…

查看全部问答>

招聘Windows XP程序员(上海宝山)

要求:熟练掌握Windows XP驱动程序编程技术,试工期间工资2000元/月,地址是上海宝山区泰和西路2945号,有意向者请留下联系方式。…

查看全部问答>

一个问题,大家帮帮我,谢谢ALL

公司让我用EVC做个图形程序。 就是,一个对话框内,一个随时间变化而温度发生变化的曲线,横坐标是时间t,纵坐标是温度T,我自己理解就是正弦曲线那种。 小弟刚刚学习EVC图形编程,别说动的曲线,静止曲线都还不会做。所以,没什么思路! 所以请 ...…

查看全部问答>