实现目的
工作上遇到了一个问题,设备型号很多,有的时候改了一个公用的参数,就导致所有的型号对应的arduino项目都要重新.hex文件,很麻烦。想到vs上有利用cmd直接运行编译,那cmd应该也可以对Arduino进行编译,生成.hex文件。这样的话无论是写批处理还是写个程序就很方便了!再也不用改个玩意,面对几十个ino文件,一个一个重新编译然后导出.hex文件了
问题
查了很多博客,发现都是在cmd里使用arduino命令或arduino_debug命令,但是我在自己的arduino文件夹下并没有找到,只有Arduino IDE这个应用文件。
本人的Arduino IDE文件夹(版本2.0.3)
没有arduino和arduino_debug,添加环境变量之后当然也没有用啦!最后发现原来是版本问题,在1.8.5的版本下,就有这俩应用程序了。(一开始也在怀疑会不会是这个问题。。折腾了很久)
Arduino1.8.5
配置好环境之后,终于可以编译了,这里使用1.8.5编译2.0.3版本生成的ino文件也是没有问题的
当然,要生成.hex文件,还需要在1.8.5版本里更改preferences.txt文件
在最下面或者随便什么位置添加一行build.path=你需要生成的目录 就可以了
案例
写了一个类,方法CommandStr会输出.hex文件所在的位置,比较粗糙,暂时还没有优化,只是将输出的log读取然后寻找.hex文件存放的位置,假如之后有问题的话会优化一下
//Author:dev_wang
//使用之前必须安装Arduino1.8.5 保证根目录下存在Arduino.exe和Arduino_debug.exe
//添加Arduino.exe目录到环境变量中
//debug详细参数见:https://github.com/arduino/Arduino/blob/master/build/shared/manpage.adoc
//翻译参考文档:
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <istream>
class ArduinoCmdVerify
{
public:
ArduinoCmdVerify(const string port,const string ino_path);
~ArduinoCmdVerify();
string CommandStr();
private:
string _MegaVerifyStr;
};
//变动参数为端口和ino项目地址 放在构造函数里
ArduinoCmdVerify::ArduinoCmdVerify(const string port, const string ino_path)
{
_MegaVerifyStr = "arduino_debug --useprogrammer --verbose-build --preserve-temp-files --board arduino:avr:mega --port " + port + " --verify " + ino_path;
}
ArduinoCmdVerify::~ArduinoCmdVerify()
{
}
//控制台写入ino,生成hex文件 返回生成hex的一行语句
string ArduinoCmdVerify::CommandStr() {
//执行cmd 利用Arduino_debug进行编译
FILE* file;
vector<string>sdata;
char cmd[1024] = { 0 };
char data[1024] = { 0 };
memcpy(cmd, _MegaVerifyStr.c_str(), 200);
if ((file = _popen(cmd, "r")) != NULL)
{
while (fgets(data, 1024, file) != NULL)
{
//cout << data << endl;
sdata.push_back(data);
}
_pclose(file);
}
//寻找sdata中带有hex的语句 因为最后会输出调用库的内容 hex语句的位置不固定
vector<string> hex_vec;
for (auto str : sdata)
{
if (str.find(".hex") != std::string::npos)
{
hex_vec.push_back(str);
}
}
//提取出语句中的.hex文件的位置
stringstream ss(hex_vec[0]);
vector<string> tokens;
string token;
while (getline(ss, token, '\"')) {
if (!token.empty()) {
tokens.push_back(token);
}
}
//将最后的/换成\\,不然在批处理复制的时候会出问题
tokens[tokens.size() - 2].replace(tokens[tokens.size() - 2].find_last_of("/"), 1, "\\");
std::cout << tokens[tokens.size() - 2] << std::endl;
return tokens[tokens.size() - 2];
}
这样2.0.3的版本用来平时工作,1.8.5专门用来编译,分工合作,也没出现什么问题。