搜索
bottom↓
回复: 14

开源一个HEX转BIN代码

[复制链接]

出10入23汤圆

发表于 2014-1-1 01:44:11 | 显示全部楼层 |阅读模式
代码自己写的,在Ubuntu下GCC编译通过,经少量AVR的HEX测试无误,如有纰漏错误,请自行判断纠正!!!!!!!!!!!!!!
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. typedef signed char int8_t;
  5. typedef unsigned char uint8_t;
  6. typedef signed short int16_t;
  7. typedef unsigned short uint16_t;
  8. typedef signed int int32_t;
  9. typedef unsigned int uint32_t;
  10. typedef float flt_t;
  11. typedef double lflt_t;

  12. #define _not_hex_(src) ((('0' > src) || ('9' < src)) && (('a' > src) || ('f' < src)) && (('A' > src) || ('F' < src)))

  13. #define _hex_trans_eq_(src,dst) \
  14. { \
  15.         if (_not_hex_(src)) \
  16.         { \
  17.                 return HEX_ERR; \
  18.         } \
  19.         if (('0' <= (src)) && ('9' >= (src))) \
  20.         { \
  21.                 dst = (src) - '0'; \
  22.         } \
  23.         else if (('a' <= (src)) && ('f' >= (src))) \
  24.         { \
  25.                 dst = (src) - 'a' + 10; \
  26.         } \
  27.         else if (('A' <= (src)) && ('F' >= (src))) \
  28.         { \
  29.                 dst = (src) - 'A' + 10; \
  30.         } \
  31. }

  32. #define _hex_trans_or_(src,dst) \
  33. { \
  34.         if (_not_hex_(src)) \
  35.         { \
  36.                 return HEX_ERR; \
  37.         } \
  38.         if (('0' <= (src)) && ('9' >= (src))) \
  39.         { \
  40.                 dst |= (src) - '0'; \
  41.         } \
  42.         else if (('a' <= (src)) && ('f' >= (src))) \
  43.         { \
  44.                 dst |= (src) - 'a' + 10; \
  45.         } \
  46.         else if (('A' <= (src)) && ('F' >= (src))) \
  47.         { \
  48.                 dst |= (src) - 'A' + 10; \
  49.         } \
  50. }

  51. #define _hex_trans_or_shift_(src,dst) \
  52. { \
  53.         dst <<= 4; \
  54.         _hex_trans_or_(src,dst); \
  55. }

  56. enum RESULT{HEX_ERR = -1, HEX_DATA_OK = 0, HEX_END_OK = 1, HEX_LBA_OK = 2, HEX_SEG_OK = 3};

  57. int8_t _hex2bin_(const uint8_t* src, uint8_t* dst, uint8_t* data_type, uint8_t* data_len, uint16_t* data_addr)
  58. {
  59.         uint8_t check_sum, i;
  60.         // 如果源code长度小于11,表明源code有误!
  61.         if (11 > strlen((const char*)src))
  62.         {
  63.                 return HEX_ERR;
  64.         }

  65.         // 校验起始字节是否为':',如果不为':',表明源code有误!
  66.         if (':' != *src++)
  67.         {
  68.                 return HEX_ERR;
  69.         }

  70.         // 得到数据长度的高4位
  71.         _hex_trans_eq_(*src, *data_len);
  72.         src++;
  73.         // 得到数据长度的低4位
  74.         _hex_trans_or_shift_(*src, *data_len);
  75.         src++;
  76.         // 校验和
  77.         check_sum = *data_len;

  78.         // 得到数据地址
  79.         _hex_trans_eq_(*src, *data_addr);
  80.         src++;
  81.         _hex_trans_or_shift_(*src, *data_addr);
  82.         src++;
  83.         // 校验和
  84.         check_sum += *data_addr;
  85.         _hex_trans_or_shift_(*src, *data_addr);
  86.         src++;
  87.         _hex_trans_or_shift_(*src, *data_addr);
  88.         src++;
  89.         // 校验和
  90.         check_sum += *data_addr;

  91.         // 得到数据类型
  92.         _hex_trans_eq_(*src, *data_type);
  93.         src++;
  94.         _hex_trans_or_shift_(*src, *data_type);
  95.         src++;
  96.         // 校验和
  97.         check_sum += *data_type;

  98.         switch (*data_type)
  99.         {
  100.         case 0: // 数据记录
  101.                 for (i = *data_len; i; i--, dst++)
  102.                 {
  103.                         _hex_trans_eq_(*src, *dst);
  104.                         src++;
  105.                         _hex_trans_or_shift_(*src, *dst);
  106.                         src++;
  107.                         // 校验和
  108.                         check_sum += *dst;
  109.                 }
  110.                 // 校验
  111.                 _hex_trans_eq_(*src, i);
  112.                 src++;
  113.                 _hex_trans_or_shift_(*src, i);
  114.                 check_sum += i;
  115.                 return check_sum? HEX_ERR : HEX_DATA_OK;
  116.         case 1: // 文件结束记录
  117.                 if (*data_addr)
  118.                 {
  119.                         return HEX_ERR;
  120.                 }
  121.                 // 校验
  122.                 _hex_trans_eq_(*src, i);
  123.                 src++;
  124.                 _hex_trans_or_shift_(*src, i);
  125.                 check_sum += i;
  126.                 return check_sum? HEX_ERR : HEX_END_OK;
  127.         case 2: // 扩展段地址记录
  128.                 if (*data_addr)
  129.                 {
  130.                         return HEX_ERR;
  131.                 }
  132.                 // 得到扩展段地址
  133.                 _hex_trans_eq_(*src, *data_addr);
  134.                 src++;
  135.                 _hex_trans_or_shift_(*src, *data_addr);
  136.                 src++;
  137.                 // 校验和
  138.                 check_sum += *data_addr;
  139.                 _hex_trans_or_shift_(*src, *data_addr);
  140.                 src++;
  141.                 _hex_trans_or_shift_(*src, *data_addr);
  142.                 src++;
  143.                 // 校验和
  144.                 check_sum += *data_addr;
  145.                 return check_sum? HEX_ERR : HEX_SEG_OK;
  146.         case 4: // 扩展线性地址记录
  147.                 if (*data_addr)
  148.                 {
  149.                         return HEX_ERR;
  150.                 }
  151.                 // 得到扩展段地址
  152.                 // 得到数据地址
  153.                 _hex_trans_eq_(*src, *data_addr);
  154.                 src++;
  155.                 _hex_trans_or_shift_(*src, *data_addr);
  156.                 src++;
  157.                 // 校验和
  158.                 check_sum += *data_addr;
  159.                 _hex_trans_or_shift_(*src, *data_addr);
  160.                 src++;
  161.                 _hex_trans_or_shift_(*src, *data_addr);
  162.                 src++;
  163.                 // 校验和
  164.                 check_sum += *data_addr;
  165.                 return check_sum? HEX_ERR : HEX_LBA_OK;
  166.         default:
  167.                 return HEX_ERR;
  168.         }
  169.         return HEX_ERR;
  170. }

  171. int8_t hex2bin(const int8_t* src_file_path, const int8_t* dst_file_path)
  172. {
  173.         uint8_t buffer_hex[1024], buffer_bin[256];
  174.         uint8_t data_type, len_bin;
  175.         uint16_t addr_low;
  176.         uint32_t addr_high = 0;
  177.         FILE* src_file;
  178.         FILE* dst_file;
  179.         src_file = fopen((const char*)src_file_path, "r");
  180.         if (!src_file)
  181.         {
  182.                 return -1;
  183.         }
  184.         dst_file = fopen((const char*)dst_file_path, "wb");
  185.         if (!dst_file)
  186.         {
  187.                 fclose(src_file);
  188.                 return -1;
  189.         }
  190.         for ( ; !feof(src_file); )
  191.         {
  192.                 if (NULL == fgets((char*)buffer_hex, 1024, src_file))
  193.                 {
  194.                         break;
  195.                 }
  196.                 if (HEX_ERR == _hex2bin_((const uint8_t*)buffer_hex, (uint8_t*)buffer_bin, &data_type, &len_bin, &addr_low))
  197.                 {
  198.                         break;
  199.                 }
  200.                 switch (data_type)
  201.                 {
  202.                 case 0: // 数据记录
  203.                         if (ftell(dst_file) != addr_low + addr_high)
  204.                         {
  205.                                 fseek(dst_file, addr_low + addr_high, SEEK_SET);
  206.                         }
  207.                         if (1 != fwrite((const uint8_t*)buffer_bin, len_bin, 1, dst_file))
  208.                         {
  209.                                 fclose(src_file);
  210.                                 fclose(dst_file);
  211.                                 return -1;
  212.                         }
  213.                         break;
  214.                 case 1: // 文件结束记录
  215.                         fclose(src_file);
  216.                         fclose(dst_file);
  217.                         return 0;
  218.                 case 2: // 扩展段地址记录
  219.                         addr_high = ((uint32_t)addr_low) << 2;
  220.                         break;
  221.                 case 4: // 扩展线性地址记录
  222.                         addr_high = ((uint32_t)addr_low) << 16;
  223.                         break;
  224.                 default:
  225.                         fclose(src_file);
  226.                         fclose(dst_file);
  227.                         return -1;
  228.                 }
  229.         }
  230.         fclose(src_file);
  231.         fclose(dst_file);
  232.         return 0;
  233. }

  234. int main(void)
  235. {
  236.         if (!hex2bin((const int8_t*)"avr-test.hex",(const int8_t*)"avr-test.bin"))
  237.                 printf("ok!\n");
  238.         return 0;
  239. }
复制代码

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2014-1-1 01:46:58 | 显示全部楼层
原来大伙都还没睡啊~

出10入23汤圆

 楼主| 发表于 2014-1-1 01:59:43 | 显示全部楼层
一匹狼 发表于 2014-1-1 01:46
原来大伙都还没睡啊~

刚写完,还没验证几下

出0入0汤圆

发表于 2014-1-1 08:11:29 | 显示全部楼层
不错,顶一下

出0入0汤圆

发表于 2014-1-1 08:26:32 | 显示全部楼层
看看。
谢。


出0入0汤圆

发表于 2014-1-1 10:14:31 | 显示全部楼层
这个是必须要啊

出0入0汤圆

发表于 2014-1-1 10:49:05 | 显示全部楼层
这个必须顶。

出0入0汤圆

发表于 2014-1-17 16:08:08 | 显示全部楼层
顶顶,学习

出0入0汤圆

发表于 2014-1-17 16:28:49 | 显示全部楼层
为何这么吊 这么叼

出0入0汤圆

发表于 2014-1-17 16:31:18 | 显示全部楼层
变通变法时用编程器软件读入HEX,另存BIN

出0入0汤圆

发表于 2014-1-17 16:33:22 | 显示全部楼层
可以把将待转换的文件通过main的参数传进来,这样会方便很多啊。。。。。

出0入0汤圆

发表于 2014-1-17 16:34:06 | 显示全部楼层
HEX的format你都兼容?好像只是。。。

出10入23汤圆

 楼主| 发表于 2014-1-19 10:37:17 | 显示全部楼层
wns245249509 发表于 2014-1-17 16:33
可以把将待转换的文件通过main的参数传进来,这样会方便很多啊。。。。。

是的,但是文件名空格问题不好解决

出10入23汤圆

 楼主| 发表于 2014-1-19 10:39:27 | 显示全部楼层
bygreencn 发表于 2014-1-17 16:34
HEX的format你都兼容?好像只是。。。

这个暂时没有验证,只验证了WINAVR生成的几个文件,其他的还没试
这个是照着网上HEX的文件描诉写的(参考百度百科),描述支持哪几种,这个就支持哪几种

出0入0汤圆

发表于 2015-2-1 00:04:00 来自手机 | 显示全部楼层
不错,谢谢。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 03:42

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表