给Arduino 设计一个序列号

之前看到很多朋友询问过如何实现“序列号”的功能。就是对于每一个 Arduino 都有独立的编码,这样可以实现一些身份识别之类的功能。
最容易实现的就是每次都修改程序中的定义。但是这样用起来耗时很长,并且必须有源程序才行,琢磨了一下,提出一种软件的实现方法,欢迎大家一起讨论。
本文是纯软件的序列号实现,因此通用性会很好,这里使用 Arduino Uno 来实现。
第一个问题是:如何在命令行下进行刷写。首先将IDE中的上传调试功能打开

image001

这样你可以看到IDE具体使用了什么上传命令(Arduino IDE 只是一个外壳,具体的编译和上传是由其他程序实现的。IDE只是调用和重定向了运行的结果)

image002

具体的话,上面图片中的烧写代码如下:

C:\Users\labz\Documents\arduino\hardware\tools\avr/bin/avrdude -CC:\Users\ labz \Documents\arduino\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM18 -b115200 -D -Uflash:w:C:\Users\ labz \AppData\Local\Temp\build3ee88a1b99cef46fdbee27900bbb7d73.tmp/Blink.ino.hex:i

知道了这一行命令,我们可以直接在CMD窗口中输入这个命令从而完成上传的动作。
第二步,直接修改生成的 HEX文件。这里制作一个带有序列号的DEMO。我们定义程序的序列号为 20170101,从串口输出这个编号以便检查,代码如下:

String sign="LABZ";
String number="20170101";

// the setup function runs once when you press reset or power the board
void setup() {
  Serial.begin(9600);
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
  Serial.print(number);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(2000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}

 

运行结果如下
image003

我们的目标就是直接用工具修改这个序列号,然后上传到 Arduino 上。同样是根据前面的命令行,我们可以知道上传的HEX文件位置:
image004

用文本编辑软件即可打开这个文件,搜索 4C 41 42 5A (ASCII:LABZ, 这就是为什么我们要在代码中定义String Sign,它能帮助我们定位后面的序列号的位置。其实不用这个作为定位手段直接搜索代码中定义的序列号也是可以的)。

仔细查看,后面的数据 32 30 31 37 30 36 就是我们的序列号 “2017”。之后又遇到的问题是,这个HEX文件是有简单的格式的。根据【参考1】,我们可以得知每行最后一个数值是这一行的校验和。例如

:100CE400FB000F019B014C41425A00323031373036
image005

其中的最后一个 36 是校验和计算方法如下:

10+0C+E4+00+FB+00+0F+01+9B+01+4C+41+42+5A+00+32+30+31+37+30=0x4CA 校验和的意思是加上一个值之后最后2位会变成00,0xCA+0x36=0x100

假设,我们的目标是将序列号修改为 19731023 = 30 39 37 33 31 30 32 33

经过分析,我们修改如下
:100CE400FB000F019B014C41425A0031393733312B
:040CF4003032330067
其中最后的校验和是通过前面的数值计算得到的。当然,更简单的办法是根据第一步,直接烧写,烧录程序会提醒你的校验和不匹配。例如,我使用错误的检验和,0x36 在烧写的时候收到提示,当前计算结果为 0x2B:

image006

修改完成之后,再次查看,序列号就是我新定义的了。
image007

可以看出,使用手工修改还是比较麻烦的,但是掌握了方法,编写自动化的工具也就是分分钟的事情了。
参考:
1. http://www.manysj.com/thread-13501-1-1.html HEX文件格式详解

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注