历史上的今天
今天是: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> 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,
史海拾趣
|
Android平台代码很多,关系也很复杂,通常我们调试程序的时候是无法跟踪到Android framework code里的,如果能调试跟踪Android source code将给我们这些初学者带来很多便利,本文将给出一个调试跟踪Android source code 的方法。 1.首先,得到Andr ...… 查看全部问答> |
|
错误内容: 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 ...… 查看全部问答> |
|
正在用ATmega48在做一个东西,需要在不需要的时候进入掉电模式,然后通过INT0进行喊醒。 现在的问题是:需要用低电平持续一段时间才可以喊醒,那么就必须设置INT0为低电平触发,但是我设成低电平触发后,紧接着进入掉电模式,我并没有给唤醒信号 ...… 查看全部问答> |
|
嘿各位! 在CE5.0上通过GPRS连接上网,当设置APN为CMNET的时候,WWW和WAP网站都能上,但是如果设置为CMWAP用我们的浏览器(仿照iesimple做的)就不能浏览网站,如果用微软自带的浏览器(iesample),设置代理服务器地址为10.0.0.172就 ...… 查看全部问答> |
|
请大家帮忙看下这段mega128串口程序有什么问题,ICCAVR下的,没法接收数据啊 [code]#include #include //================================== void port_init(void) { PORTA = 0xFF; DDRA = 0x00; PORTB = 0xFF; DDRB ...… 查看全部问答> |
|
要求:熟练掌握Windows XP驱动程序编程技术,试工期间工资2000元/月,地址是上海宝山区泰和西路2945号,有意向者请留下联系方式。… 查看全部问答> |
|
公司让我用EVC做个图形程序。 就是,一个对话框内,一个随时间变化而温度发生变化的曲线,横坐标是时间t,纵坐标是温度T,我自己理解就是正弦曲线那种。 小弟刚刚学习EVC图形编程,别说动的曲线,静止曲线都还不会做。所以,没什么思路! 所以请 ...… 查看全部问答> |




