C# 生成命令行程序 将hex格式烧录程序转换成bin烧录格式

1.程序

cs 复制代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Hex2Bin
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length < 2 || args.Length > 3)
            {
                ShowHelp();
                return;
            }

            string inputFile = args[0];
            string outputFile = args[1];
            long startOffset = 0;
            long endOffset = long.MaxValue;

            // 处理可选的偏移参数
            if (args.Length == 3)
            {
                if (!long.TryParse(args[2], System.Globalization.NumberStyles.HexNumber, null, out startOffset))
                {
                    Console.WriteLine("错误:无效的偏移地址格式");
                    return;
                }
                endOffset = long.MaxValue;
            }

            try
            {
                ConvertHexToBin(inputFile, outputFile, startOffset, endOffset);
                Console.WriteLine($"转换成功!输出文件:{outputFile}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"错误:{ex.Message}");
            }
        }

        static void ShowHelp()
        {
            Console.WriteLine("Hex2Bin - Intel HEX 转 BIN 格式转换工具");
            Console.WriteLine("用法:Hex2Bin <输入文件.hex> <输出文件.bin> [起始偏移地址]");
            Console.WriteLine("示例:");
            Console.WriteLine("  Hex2Bin firmware.hex firmware.bin");
            Console.WriteLine("  Hex2Bin firmware.hex firmware.bin 1000    // 从0x1000开始提取");
        }

        static void ConvertHexToBin(string hexFile, string binFile, long startOffset, long endOffset)
        {
            var dataSegments = new Dictionary<long, byte>();
            long minAddr = long.MaxValue;
            long maxAddr = long.MinValue;
            long currentSegmentAddr = 0;
            long extendedLinearAddr = 0;
            long extendedSegmentAddr = 0;

            string[] lines = File.ReadAllLines(hexFile);
            
            foreach (string line in lines)
            {
                if (string.IsNullOrWhiteSpace(line) || line[0] != ':')
                    continue;

                // 解析HEX行
                byte byteCount = Convert.ToByte(line.Substring(1, 2), 16);
                ushort address = Convert.ToUInt16(line.Substring(3, 4), 16);
                byte recordType = Convert.ToByte(line.Substring(7, 2), 16);
                string dataString = line.Substring(9, byteCount * 2);
                byte checksum = Convert.ToByte(line.Substring(9 + byteCount * 2, 2), 16);

                // 验证校验和
                byte calcChecksum = 0;
                calcChecksum += byteCount;
                calcChecksum += (byte)(address >> 8);
                calcChecksum += (byte)(address & 0xFF);
                calcChecksum += recordType;
                for (int i = 0; i < byteCount; i++)
                {
                    calcChecksum += Convert.ToByte(dataString.Substring(i * 2, 2), 16);
                }
                calcChecksum = (byte)((~calcChecksum + 1) & 0xFF);
                
                if (calcChecksum != checksum)
                {
                    throw new Exception($"校验和错误:行 {line}");
                }

                // 计算实际地址
                long actualAddress;
                switch (recordType)
                {
                    case 0x00: // 数据记录
                        actualAddress = extendedLinearAddr + address;
                        if (extendedSegmentAddr != 0)
                            actualAddress = (extendedSegmentAddr << 4) + address;
                        
                        // 存储数据
                        for (int i = 0; i < byteCount; i++)
                        {
                            byte data = Convert.ToByte(dataString.Substring(i * 2, 2), 16);
                            long addr = actualAddress + i;
                            
                            if (addr >= startOffset && addr <= endOffset)
                            {
                                if (!dataSegments.ContainsKey(addr))
                                    dataSegments[addr] = data;
                                
                                if (addr < minAddr) minAddr = addr;
                                if (addr > maxAddr) maxAddr = addr;
                            }
                        }
                        break;
                        
                    case 0x01: // EOF
                        break;
                        
                    case 0x02: // 扩展段地址
                        extendedSegmentAddr = Convert.ToUInt16(dataString, 16);
                        break;
                        
                    case 0x03: // 起始段地址
                        // 忽略
                        break;
                        
                    case 0x04: // 扩展线性地址
                        extendedLinearAddr = Convert.ToUInt32(dataString, 16) << 16;
                        extendedSegmentAddr = 0;
                        break;
                        
                    case 0x05: // 起始线性地址
                        // 忽略
                        break;
                }
            }

            if (dataSegments.Count == 0)
            {
                throw new Exception("没有找到有效的数据记录");
            }

            // 创建连续的数据缓冲区
            long totalSize = maxAddr - minAddr + 1;
            byte[] binData = new byte[totalSize];
            
            // 填充数据
            foreach (var kvp in dataSegments)
            {
                binData[kvp.Key - minAddr] = kvp.Value;
            }

            // 写入BIN文件
            File.WriteAllBytes(binFile, binData);
            
            Console.WriteLine($"转换统计:");
            Console.WriteLine($"  起始地址:0x{minAddr:X8}");
            Console.WriteLine($"  结束地址:0x{maxAddr:X8}");
            Console.WriteLine($"  数据大小:{totalSize} 字节");
        }
    }
}

2. 使用方法

cs 复制代码
# 基本用法
Hex2Bin.exe input.hex output.bin

# 指定起始地址(十六进制)
Hex2Bin.exe input.hex output.bin 1000

# 显示帮助
Hex2Bin.exe

3.程序特点

  1. 支持标准Intel HEX格式

    • 数据记录(00)

    • 文件结束记录(01)

    • 扩展段地址(02)

    • 扩展线性地址(04)

    • 起始地址记录(03, 05)

  2. 校验和验证:每行HEX数据都会验证校验和

  3. 地址范围过滤:可选的起始地址参数

  4. 内存高效:使用字典存储非连续数据段

4.使用示例

假设有HEX文件内容:

bash 复制代码
:100000000102030405060708090A0B0C0D0E0F101A
:100010001112131415161718191A1B1C1D1E1F2029
:00000001FF

转换后的BIN文件将包含地址0x0000-0x001F的32字节数据。

这个工具适用于嵌入式开发中常见的固件格式转换需求。

相关推荐
Devlab7 小时前
LVGL设计大师——网页版anyui来了!!
嵌入式硬件·物联网·低代码·ui·iot
2603_965148117 小时前
如何解析JSON数据?API返回的商品信息处理教程
开发语言·数据库·python·自动化·json·api
波波0077 小时前
C# 15 重磅新特性: 带标签 break 与 continue:重新定义嵌套循环控制流
服务器·前端·c#
知无不研9 小时前
lambda表达式的使用(3)
开发语言·c++·lambda
cfm_291410 小时前
SpringAI + Ollama 本地大模型
java·开发语言·人工智能·语言模型
Dr.kangder10 小时前
嵌入式面试总结(十五)——异常处理
单片机·面试·职场和发展·系统架构·嵌入式
wujian831111 小时前
怎么用千问生成word文档:从「格式崩」到「一键过」,AI导出鸭打通最后半厘米
人工智能·ai·c#·word·豆包·deepseek·ai导出鸭
C++ 老炮儿的技术栈11 小时前
基于Qt实现轻量化本地音乐播放器
开发语言·c++·qt·c·播放器·音乐
qq_4480111611 小时前
C语言中的柔性数组
c语言·开发语言·柔性数组
小白学大数据11 小时前
长周期爬虫的数据一致性:断点续爬 + 事务回滚保障采集质量
开发语言·爬虫·测试工具