当前位置: 首页> 新闻> 会展 > 代码——IMX6UL烧录工具及其使用

代码——IMX6UL烧录工具及其使用

时间:2025/8/23 6:40:47来源:https://blog.csdn.net/m0_74349248/article/details/142344840 浏览次数:1次

一、简介

        在此感谢正点原子官方提供的IMX6UL烧录代码,本篇是在正点原子给的代码基础上修改的,增加了些许功能,可根据自己的需求更改。此外代码难免有疏漏之处,还望见谅

二、源代码的使用

1,库和工具的安装

        安装库和工具前,记得更新apt

sudo apt-get update
sudo apt-get upgrade

        由于使用的是C++并且使用CMake管理工程,所以需要有g++编译器和cmake。编译器一定是没有前缀的,不需要使用交叉编译器

sudo apt-get install g++
sudo apt-get install cmake

        代码中用到了Boost库,所以也要安装

sudo apt-get install boost

         由于使用到来pv命令,所以也要安装

sudo apt-get install pv

         可能还有一些库忘记说了,可自行根据报错提示查找

 

 2,项目的编译

        如果你使用的是CLion,那么只需要点击右上方的小锤子构建即可(不需要运行)

         如果没有CLion的话,可以使用终端来构建。首先需要创建一个目录(示例目录为imx_download),然后把项目文件添加进去(一共有三个)

        然后在当前目录下打开终端,输入命令,CMake一下,点表示当前目录

cmake .

        之后会在当前目录下生成Makefile

         然后再输入make命令,编译项目,即可生成程序(左上方带“?”的那个文件)

make

 

 

三、程序的使用

1,形式

        程序仿照一般工具的使用,通过 -【options】 【parameter】或者 --【options'】 【parameter】的形式来使用

        为了使用方便(开发不方便),就把所有代码写到了一个cpp文件

①在程序运行前需要赋予其权限(1次即可)

 chmod 777 ./imx_download 

 

 ②无参运行

        无参运行时如下图所示,这是由于下面代码所决定的,在main函数里有两个参数,一个是argc,另一个是argv。前者表示输入的参数个数,后者表示指向字符串的指针,与参数个数对应。

        传入的第一个参数是程序自身的名字,所以参数个数argc为1,第一个字符串argv[0]为程序的名字

③含参运行

        通过在选项后面追加参数来执行相应功能,这里是通过Boost库来完成的,之所以使用Boost库而不是进行普通的字符串检查,是为了减少工作量,不过编译出的程序有点大,足足近1MB

        如果你想要追加选项,可以仿照下面,括号内的第一个参数分成全称和缩写,比如"help,p",意为可以通过“-h”或者“--help”来使用

         具体执行“-h”或“--help”的代码在下面,通过count来判断有没有选项“help”来执行括号内代码。

        示例:

④具体烧录过程

        我把烧录分为了两种情况,同时添加了进度条和一切容错判断。

其一:指定bin文件,再指定SD设备

        原理很简单,程序会先动态创建一个缓冲区,把bin文件拷到缓冲区里面,不过前面空了3KB用于存放IVT DCD表信息。接下来就是根据所选的DDR大小把相应的表存入缓冲区的前面

        然后又创建了一个imx文件,再把缓冲区里的数据写入进去。

        最后通过dd命令把刚才的imx文件烧录到SD设备里,并且是从SD设备的第二个分区开始写入

        详情可自行查看代码,下面以烧录一个uboot为例,由于新建文件可能需要权限,所以在前面加了sudo。执行烧录SD卡的命令是下面代码,用了pv命令(显示进度条)和dd命令(烧录)。

        dd命令后面的不同参数代表了不同含义,bs=512是设置块大小为 512 字节、seek=2是从输出设备的第 2 个 512 字节块开始写入数据、iflag=dsync和oflag=dsync分别是使用同步 I/O 操作读取和写入数据、conv=fsync是在dd命令完成所有操作后强制将所有缓存的数据写入磁盘等等

        这里为了速度,把iflag=dsync和oflag=dsync都给禁了,把烧录速度从一百多KB每秒提到了2MB/s以上,下面拿了一个104MB的文件测试了一下速度

其二:未指定bin文件,指定SD设备

        原理同上,只不过少了添加表头信息的步骤。

        烧录时指定SD设备但没指定bin文件时,会自动在当前目录下搜寻所有.imx文件并列出来,然后由用户输入指定文件编号进行烧录。如果当前目录只有一个.imx文件,则自动烧录到SD设备上

        为了防止烧录错,增加了下面判断,只不过这个只能判断所选块设备是否存在。如果需要的话,可自己设置一个“禁止名单”,当指定的SD卡在名单上时,就停止烧录

         更多功能就不一一列举了

 

 

四、源代码

        共有三个文件:imxdownload.himxdownload.cppCMakeLists.txt

1,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 unsigned 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 unsigned 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

2,imxdownload.cpp

// 可以自行决定用C++还是Linux命令来完成数据流的复制
// 如果选择后者,那么需要安装pv,命令为:sudo apt-get install pv#include "imxdownload.h"
#include <boost/program_options.hpp>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <memory>
#include <regex>
#include <string>#define BIN_OFFSET (3072)#define DDR_512MB 0
#define DDR_256MB 1// 0: 默认使用C++进行数据流的传输 1: 使用Linux命令行进行数据流的传输
// 不过目前C++方式还不能使用,只有后者可以
#define DOWNLOAD_MODE 1namespace po = boost::program_options;
namespace fs = std::filesystem;// 使用文件系统命名空间bool isBinFile(const std::string &filename)
{return filename.substr(filename.find_last_of('.') + 1) == "bin";
}// 显示进度条
void showProgress(double progress, int totalLength = 50)
{int pos = static_cast<int>(progress * totalLength);std::cout << "\r[" << std::string(pos, '=') << std::string(totalLength - pos, ' ') << "] "<< std::fixed << std::setprecision(2) << (progress * 100) << "%";std::cout.flush();
}int main(int argc, char *argv[])
{std::cout << "I.MX6ULL烧写工具(源于正点原子)\r\n\n";// clang-format offpo::options_description desc("允许的选项");desc.add_options()("help,h", "显示帮助信息")("verbose,v", "显示详细信息")("print,p", "打印IVT DCD表信息")("name,n", po::value<std::string>()->default_value("load"), "指定生成文件的名称")("ddr-size,d", po::value<int>()->default_value(-1),"设置 DDR 大小 (512m or 256m)")("source-bin,b", po::value<std::string>(), "指定源二进制文件")("sd-device,s", po::value<std::string>(), "指定 SD 设备");// clang-format onpo::variables_map vm;try{po::store(po::parse_command_line(argc, argv, desc), vm);po::notify(vm);}catch (const std::exception &e){std::cerr << "错误: " << e.what() << std::endl;std::cout << desc << "\n";// 显示帮助信息return -1;}// 参数为空时if (argc == 1){std::cout << "更新时间:2024-9-19 04:04\n";}bool verbose = vm.count("verbose") > 0;if (verbose){std::cout << "该程序通过参数进行操作,详情请输入-h或者--help\n";std::cout << "1: 不指定SD卡设备时,不会进行烧录\n";std::cout << "2: 不指定bin文件时会自动搜寻当前目录下的唯一imx文件\n";std::cout << "3: 可以自定义生成文件名称\n";}if (vm.count("help")){std::cout << desc << "\n";// 显示所有选项}int ddrSize = vm["ddr-size"].as<int>();std::string sourceFileName;std::string sdDevice;std::string outputFileName = vm["name"].as<std::string>() + ".imx";// 若未指定SD设备,则不进行烧录;// 若指定SD设备未指定二进制文件,则会在当前目录中寻找唯一的一个*.imxbool sourceBinSpecified = vm.count("source-bin");bool sdDeviceSpecified = vm.count("sd-device");bool isImxFileSpecified = false;// 是否找到了唯一的imx文件if (sourceBinSpecified){sourceFileName = vm["source-bin"].as<std::string>();std::cout << "指定二进制文件: " << sourceFileName << std::endl;// 检查文件扩展名是否为 .binif (!isBinFile(sourceFileName)){std::cout << "警告: 指定的文件不是 .bin 文件。是否继续使用此文件? (y/n): ";char response;std::cin >> response;if (response != 'y' && response != 'Y'){std::cerr << "取消操作。" << std::endl;return -1;}}if (!sdDeviceSpecified){std::cout << "由于未指定SD卡设备,将不进行烧录" << std::endl;}}else if (sdDeviceSpecified){// 查找当前目录下所有的 .imx 文件std::vector<std::string> imxFiles;for (const auto &entry: fs::directory_iterator(".")){if (entry.path().extension() == ".imx"){imxFiles.push_back(entry.path().string());}}if (imxFiles.empty()){std::cerr << "找不到任何 .imx 文件,请指定 --source-bin 参数" << std::endl;std::cout << "详情请输入 --help 或 -h 进行查看" << "\n";return -1;}else if (imxFiles.size() > 1){std::cout << "找到多个 .imx 文件,请选择一个:" << std::endl;for (size_t i = 0; i < imxFiles.size(); ++i){imxFiles[i] = imxFiles[i].substr(2);// 去掉 ./std::cout << i + 1 << ": " << imxFiles[i] << std::endl;}int choice;std::cout << "请输入文件编号: ";std::cin >> choice;if (choice < 1 || choice > static_cast<int>(imxFiles.size())){std::cerr << "无效的选择,请重新运行程序并正确选择文件。" << std::endl;return -1;}isImxFileSpecified = true;outputFileName = imxFiles[choice - 1];sourceFileName = outputFileName;std::cout << "选择了文件: " << outputFileName << std::endl;}else{isImxFileSpecified = true;outputFileName = imxFiles[0].substr(2);// 去掉 ./sourceFileName = outputFileName;std::cout << "找到唯一的imx 文件: " << outputFileName << std::endl;}}// 检查SD卡设备if (sdDeviceSpecified){sdDevice = vm["sd-device"].as<std::string>();// 检查设备是否符合 /dev/sd* 的格式std::regex sdRegex("^/dev/sd[a-z]+$");if (!std::regex_match(sdDevice, sdRegex)){std::cout << "警告: " << sdDevice << " 指定SD设备可能未挂载到/dev上。是否继续? (y/n): ";std::cout << "当前SD设备有:" << std::endl;system("ls /dev/sd*");char response;std::cin >> response;if (response != 'y' && response != 'Y'){std::cerr << "取消操作。" << std::endl;return -1;}}// 检查SD设备是否存在FILE *pipe = popen(("ls /dev/ | grep -w " + sdDevice.substr(5)).c_str(), "r");if (pipe == nullptr){std::cerr << "无法执行ls命令来检查设备 " << sdDevice << "。" << std::endl;return -1;}std::cout << "当前SD设备有:" << std::endl;system("ls /dev/sd*");char buffer[256];if (fgets(buffer, 255, pipe) == nullptr){pclose(pipe);std::cout << "警告: " << sdDevice << " 不存在。" << std::endl;std::cout << "是否继续? (y/n): ";char response;std::cin >> response;if (response != 'y' && response != 'Y'){std::cerr << "取消操作。" << std::endl;return -1;}}pclose(pipe);}else{// 未指定则不进行后续操作return 0;}if (ddrSize == -1){std::cout << "DDR 大小未指定,默认使用 512MB"<< std::endl;ddrSize = DDR_512MB;}/*** 若指定bin文件,则将其转为imx文件*/long fileLen;long outputFileSize;std::ifstream sourceFile(sourceFileName, std::ios::binary);/* 打开bin文件 */if (!sourceFile.is_open()){std::cerr << "无法打开文件 " << sourceFileName<< std::endl;return -1;}/* 获取资源文件长度 */sourceFile.seekg(0, std::ios::end);fileLen = static_cast<int>(sourceFile.tellg());sourceFile.seekg(0, std::ios::beg);std::cout << "文件 " << sourceFileName<< " 大小 = " << fileLen << " 字节";if (!isImxFileSpecified){std::cout << " 烧录镜像总大小 = " << fileLen + BIN_OFFSET << " 字节"<< std::endl;/* 读取bin文件到缓冲区buf中 */outputFileSize = fileLen + BIN_OFFSET;}else{std::cout << " 烧录镜像总大小 = " << fileLen << " 字节"<< std::endl;/* 读取bin文件到缓冲区buf中 */outputFileSize = fileLen;}// 创建一个buf缓冲区,用于存储生成的imx文件std::unique_ptr<unsigned char[]> buf(new unsigned char[outputFileSize]);if (buf == nullptr){std::cerr << "内存分配失败!" << std::endl;return -1;}memset(buf.get(), 0, outputFileSize); /* 清零 *//* 读取bin文件到缓冲区buf中 */if (!isImxFileSpecified){/* 读取bin源码文件 */// 将bin文件读入buf中,且偏移buf起始地址BIN_OFFSETsourceFile.read(reinterpret_cast<char *>(buf.get() + BIN_OFFSET), fileLen);}else// 直接将imx文件直接拷贝到buf中{sourceFile.read(reinterpret_cast<char *>(buf.get()), fileLen);}sourceFile.close();// 打印IVT DCD表if (vm.count("print")){std::cout << "IVT DCD Table:" << std::endl;for (int i = 0; i < 1024 / 32; i++){for (int j = 0; j < 8; j++){std::cout << "0X" << std::hex<< *(int *) (buf.get() + BIN_OFFSET + (((i * 8) + j) * 4))<< ",";}std::cout << std::endl;}return 0;}/* 添加IVT DCD等表信息到bin文件里面 */if (!isImxFileSpecified){switch (ddrSize){default:std::cout << "内存参数输入错误!将默认为512MB"<< std::endl;ddrSize = DDR_512MB;case DDR_256MB:std::cout << "Board DDR SIZE: 256MB"<< std::endl;// 假设 imx6_256mb_ivtdcd_table 已定义memcpy(buf.get(), imx6_256mb_ivtdcd_table, sizeof(imx6_256mb_ivtdcd_table));break;case DDR_512MB:std::cout << "Board DDR SIZE: 512MB"<< std::endl;// 假设 imx6_512mb_ivtdcd_table 已定义memcpy(buf.get(), imx6_512mb_ivtdcd_table, sizeof(imx6_512mb_ivtdcd_table));break;}/* 现在我们已经在buf中构建好了可以用于下载的bin文件,将buf中的数据保存到* 到一个文件中,文件默认命名为load.imx*/std::cout << "准备创建 " << outputFileName << " 文件..." << std::endl;std::ofstream outputFile(outputFileName, std::ios::binary);if (!outputFile.is_open()){std::cerr << "打开 " << outputFileName << " 失败!" << std::endl;std::cout << "可能是权限不够,尝试用sudo命令来执行本程序\r\n";return -1;}/* 把缓冲区数据写入imx文件中 */outputFile.write(reinterpret_cast<const char *>(buf.get()), outputFileSize);if (!outputFile){std::cerr << "文件写入错误!" << std::endl;return -1;}outputFile.close();}// 再次判定,防止后续开发中遗忘了检测// 只有当用户指定了 `-s` 参数时才执行烧录
#if !DOWNLOAD_MODEif (vm.count("sd-device")){std::cout << "开始烧录 load.imx 到 " << sdDevice << " ..." << std::endl;/* 使用C++方式模拟dd命令行为 */std::ifstream inFile(outputFileName, std::ios::binary);if (!inFile.is_open()){std::cerr << "打开 load.imx 失败!" << std::endl;return -1;}std::ofstream outDevice(sdDevice, std::ios::binary | std::ios::out);if (!outDevice.is_open()){std::cerr << "打开设备 " << sdDevice << " 失败!C++模式下需要您有正确的权限并且设备可用。" << std::endl<< "参考命令为sudo ./imxdownload -[options] [parameter]" << std::endl;inFile.close();return -1;}const int bufferSize = 512;// 模拟512字节的块大小unsigned char buffer[bufferSize];long totalBytesRead = 0;long totalBytesToRead = fileLen + BIN_OFFSET;while (inFile.read(reinterpret_cast<char *>(buffer), bufferSize)){long bytesRead = inFile.gcount();totalBytesRead += bytesRead;outDevice.write(reinterpret_cast<const char *>(buffer), bytesRead);double progress = static_cast<double>(totalBytesRead) / totalBytesToRead;showProgress(progress);// 显示进度条}if (inFile.eof()){std::cout << std::endl<< "烧录完成。" << std::endl;}else{std::cerr << "读取文件时发生错误。" << std::endl;std::cout << "可能是权限不够,尝试用sudo命令来执行本程序\r\n";std::cout<<"例如:sudo ./imx_download -s /dev/sdx\r\n";}inFile.close();outDevice.close();}
#elseif (vm.count("sd-device")){/* 构建烧写的shell命令 */std::string cmd = "pv " + outputFileName + " | sudo dd of=" + sdDevice;// pv前面也加sudo,那么进度条就不会显示了
//        cmd+=" iflag=dsync oflag=dsync";  // 如果数据在传输中出现问题,请尝试取消本行注释,不过传输速度会下降至一百多kb每秒cmd += " bs=512 seek=2  conv=fsync && sync";std::cout << "\n开始烧录 " << outputFileName << " 到 " << sdDevice<< " ..." << std::endl;/* 执行上面的shell命令,并捕获输出 */int result = system((cmd + " 2>&1").c_str());// 将错误输出也重定向到标准输出if (result == 0){std::cout << "烧录成功" << std::endl;}else{std::cerr << "烧录失败,返回值: " << result << std::endl;
//            std::cout << "可能是权限不够,尝试用sudo命令来执行本程序\r\n";
//            std::cout<<"例如:sudo ./imx_download -s /dev/sdx\r\n";}}#endifreturn 0;
}

3,CMakeLists.txt

        注意CMake版本,这里设置的最低版本是3.28,根据自己需要设置

#cmake_minimum_required(VERSION 3.29)
#project(imxdownload)
#
## 查找 Boost 库
#find_package(Boost REQUIRED program_options)
#
#set(CMAKE_CXX_STANDARD 20)
#
#add_executable(imx_download imxdownload.h imxdownload.cpp)
#target_link_libraries(${PROJECT_NAME} PRIVATE ${Boost_LIBRARIES})cmake_minimum_required(VERSION 3.28)
project(imx_download VERSION 1.0)# 查找 Boost 库
find_package(Boost REQUIRED program_options)# 设置源文件
set(SOURCE_FILESimxdownload.cpp
)# 添加可执行文件,并链接 Boost 库
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} PRIVATE ${Boost_LIBRARIES})# 设置编译标志
#if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
#    target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17)
#endif()# 其他配置...

关键字:代码——IMX6UL烧录工具及其使用

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: