给Arduino 设计一个序列号-Arduino中文社区 - Powered by Discuz! Archiver

Zoologist 发表于 2017-1-2 18:32

给Arduino 设计一个序列号

之前看到很多朋友询问过如何实现“序列号”的功能。就是对于每一个 Arduino 都有独立的编码,这样可以实现一些身份识别之类的功能。最容易实现的就是每次都修改程序中的定义。但是这样用起来耗时很长,并且必须有源程序才行,琢磨了一下,提出一种软件的实现方法,欢迎大家一起讨论。本文是纯软件的序列号实现,因此通用性会很好,这里使用 Arduino Uno 来实现。第一个问题是:如何在命令行下进行刷写。首先将IDE中的上传调试功能打开                              这样你可以看到IDE具体使用了什么上传命令(Arduino IDE 只是一个外壳,具体的编译和上传是由其他程序实现的。IDE只是调用和重定向了运行的结果) 具体的话,上面图片中的烧写代码如下:
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
}
运行结果如下
我们的目标就是直接用工具修改这个序列号,然后上传到 Arduino 上。同样是根据前面的命令行,我们可以知道上传的HEX文件位置: 用文本编辑软件即可打开这个文件,搜索 4C 41 42 5A (ASCII:LABZ, 这就是为什么我们要在代码中定义StringSign,它能帮助我们定位后面的序列号的位置。其实不用这个作为定位手段直接搜索代码中定义的序列号也是可以的)。 仔细查看,后面的数据 32 30 31 37 30 36 就是我们的序列号 “2017”。之后又遇到的问题是,这个HEX文件是有简单的格式的。根据【参考1】,我们可以得知每行最后一个数值是这一行的校验和。例如
:100CE400FB000F019B014C41425A00323031373036
其中的最后一个 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: 修改完成之后,再次查看,序列号就是我新定义的了。
可以看出,使用手工修改还是比较麻烦的,但是掌握了方法,编写自动化的工具也就是分分钟的事情了。参考:1. http://www.manysj.com/thread-13501-1-1.htmlHEX文件格式详解

奈何col 发表于 2017-1-2 18:59

每一个AVR都有一个唯一的sn码,datasheet上有读出的方法,这个可以把利用上

Zoologist 发表于 2017-1-2 21:38

奈何col 发表于 2017-1-2 18:59
每一个AVR都有一个唯一的sn码,datasheet上有读出的方法,这个可以把利用上

翻了一下 datasheet 没有找到唉~

具体叫什么名字?
页: [1]
查看完整版本: 给Arduino 设计一个序列号