在工作中,我们有一个定期更改的Arduino草图。简而言之,它在串行端口上来回通信。在大多数情况下,我们的软件开发团队控制代码;但是,我们公司还有其他一些团队定期对草图进行最后一分钟的更改,以满足特定客户的需求。
这显然是非常有问题的,因为这意味着我们可能会在不同的地方部署不同版本的草图,而不会意识到这一点。我们的软件开发人员非常擅长使用源代码控制,但其他团队并不那么自律。
提出的一个想法是对版本号进行硬编码,以便某个串行命令通过报告预定义的版本号来响应。但问题是,如果他们决定进行其他更改,我们的其他团队可能同样无法更新版本号。
显然,最好的解决方案是切断其他团队的更新,但假设出于办公室政治原因这是不可能的,我想知道是否有任何方式可以通过编程方式"反映&# 34;在Arduino草图上。显然草图将占用一定数量的字节,而草图文件将具有唯一的文件哈希。我在想是否有某种方法可以将字节数,文件哈希值或上次修改时间作为预处理程序指令获取,这些指令可以注入到理想的代码中。像这样:
// pseudocode
const String SKETCH_FILE_HASH = #filehash;
const int SKETCH_FILE_SIZE = #filesize;
const int SKETCH_LAST_UPDATED = #modified;
但据我所知,这与此有关。有没有办法为Arduino代码编写自定义预处理程序指令或宏?特别是可以检查草图文件本身的那些?这甚至可能吗?或者是否有某种方式已经存在以编程方式跟踪某种方式的变化?
答案 0 :(得分:1)
冒险回答。
SKETCH_FILE_HASH
:你必须在外部预先计算并作为标志传递。我想你正在使用arduino IDE,这是不可行的SKETCH_FILE_SIZE
:同样的回答SKETCH_LAST_UPDATED
:您可以使用__TIME__
获取包含编译时间的字符串。我会做什么,考虑到政治部分。
svn:id
用于颠覆,几乎所有VCS都提供此功能)嵌入像
这样的代码#ifndef BUILD_TYPE
#define BUILD_TYPE "Unsupported"
#endif
在您的持续构建过程中,使用-DBUILD_TYPE="HEAD"
或"Release"
对不起,我没有看到魔法棒解决你的解决方案。我已经投入大量资金进行培训,为什么版本控制可以拯救你(似乎你已经有了战争故事)
答案 1 :(得分:0)
我自己正在看这个问题,并发现了这个:
https://gist.github.com/jcw/1985789#file-bootcheck-ino
这是查找引导加载程序;但我认为像这样的东西可以用来确定整个代码的某种签名。
我做了一个快速实验,在那里我添加了类似的内容:
Serial.print("Other...");
Serial.println(CalculateChecksum(0, 2048));
在void setup()中,并且 能够根据更改一小段代码(字符串)获得CRC的不同值。
这不是一个明确的解决方案;我尝试了CalculateChecksum(0,32767),依此类推,如果我定义了一个类似int a = 101的整数;并将其更改为int a = 102;校验和是一样的。只有当我更改了一个字符串(即添加一个空格)时,这个值才会改变。
我对Arduino中分配内存的方式不太清楚;我知道有程序存储器(32,256字节)和全局变量存储器(2048字节),所以我确信有一些方法可以做到这一点。
在另一个实验中,我使用了pgm_read_byte()函数,如果我创建一个简单的内存转储函数:
void MemoryDump (word addr, word size) {
word dataval = ~0;
// prog_uint8_t* p = (prog_uint8_t*) addr;
uint8_t* p = (uint8_t*) addr;
for (word i = 0; i < size; ++i)
{
dataval = pgm_read_byte(p++);
Serial.print(i);
Serial.print(" ->");
Serial.print(dataval,HEX);
Serial.print(" ");
Serial.print(dataval);
Serial.print(" ");
if(dataval>32)
{
Serial.print(char(dataval));
}
else
{
Serial.print("***");
}
Serial.print("\n");
}
}
...我输入了一句话: Serial.println(F( “12345fghijklmnopqrstuvwxyz”));
因为F()将字符串放在程序存储器中,你会在那里看到它。
如上所述,读取SRAM是一个问题:
http://forum.arduino.cc/index.php?topic=220125.0
我不是编译器之神,所以我不知道像a = 101这样的东西;查看编译器/ IDE,或者为什么这与程序存储区没有什么不同。
最后一点:
http://playground.arduino.cc/Code/AvailableMemory
这些函数可以访问SRAM,所以通过一些调整,你可以在那个内存上做一个CRC,但这似乎有点问题,因为你必须做一个用SRAM中的变量计算!但是如果代码是相同的,即使进行这样的计算,它也许是可能的。再次,我在这里深水,所以如果一个AVR上帝对此有疑问,请用一个丑陋的事实破坏这个理论!