将固件文件放到项目的 res/raw下
由Mission Planner生成的固件需要删除一些东西,用记事本打开只留下圈中的那些,其他全部删除
刷新固件步骤与Mission Planner一致。
按钮点击事件:
protected void firmwareDialog1() {//刷新固件
try {
alertDialog = new AlertDialog.Builder(this).
setTitle("拔下控制板点击“确定”后再插入。\nAPP将在30秒内寻找控制板").
setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// ControlApi.getApi(getDrone()).shuagujian(3, actionListener); //通过mavlink命令重启飞控
alertDialog.dismiss();
Firmware firmware = new Firmware();
InputStream Firmware = getResources().openRawResource(R.raw.arducopter_quad1);
firmware.brushFirmware(getApplicationContext(), Firmware);
}
}).create();
if(!MainActivity.this.isFinishing()){
alertDialog.show();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
}
}
固件类:
public class Firmware {
Code code = new Code();
Bundle bundle = new Bundle();
public UsbConnection usbConnection;
public UsbCDCConnection usbCDCConnection ;
final int i_size = 968312;
public void brushFirmware(final Context context, final InputStream Firmware) {
usbCDCConnection = new UsbCDCConnection(context,usbConnection,115200);
usbConnection=new UsbConnection(context,115200);
Delay(5000);
new Thread(new Runnable() {
@Override
public void run() {
if (Trysync()) {//跟单片机握手
if (erase()) {//判断擦除固件是否成功
ProcessFirmware(Firmware);//烧固件
Reboot();//重启
Looper.prepare();
Toast.makeText(context, "成功!请断电重新连接!", Toast.LENGTH_SHORT).show();
Looper.loop();
}
}
}
}).start();
}
public void Delay(int x){
try {
Thread.sleep(x);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public boolean Trysync(){
Open_Usb_Connection();
byte Get_Sync[] = {code.GET_SYNC,code.EOC}; //0x21 0x20
byte[] Get_recv = new byte[2];
try {
usbCDCConnection.sendBuffer(Get_Sync);
Delay(500);
usbCDCConnection.readDataBlock(Get_recv);
if(Get_recv[0] == code.INSYNC && Get_recv[1] == code.OK){
/* Message message = new Message();
message.what = 3; //识别Bootloader成功
m_handler.sendMessage(message);*/
return true;
} else{
/* Message message = new Message();
message.what = 4; //识别Bootloader失败
m_handler.sendMessage(message);*/
return false;
}
}catch (Exception e) {
//Toast.makeText(getApplicationContext(),e.toString()+e.getMessage(),Toast.LENGTH_LONG).show();
return false;
}
}
public void Open_Usb_Connection(){
try {
usbCDCConnection.openUsbConnection(bundle);
} catch (Exception e) {
}
}
public boolean erase() {
byte Erase[] = {code.CHIP_ERASE, code.EOC};//0x23 0x20
try {
usbCDCConnection.sendBuffer(Erase);
Thread.sleep(10000); //延迟10s
byte aa[] = new byte[2];
usbCDCConnection.readDataBlock(aa);
if (aa[0] == 0x12 && aa[1] == 0x10) {
/* Message message = new Message();
message.what = 5; //擦除成功
m_handler.sendMessage(message);*/
return true;
} else {
/* Message message = new Message();
message.what = 6; //擦除失败
m_handler.sendMessage(message);*/
return false;
}
} catch (Exception e) {
// Toast.makeText(getApplicationContext(),e.toString()+e.getMessage(),Toast.LENGTH_LONG).show();
return false;
}
}
public void ProcessFirmware(InputStream Firmware) {
try {
int len = 0;
// Firmware = new FileInputStream(savefile);//获取文件
byte buffer[] = new byte[(int) Firmware.available()]; //创建文件大小的数组
Firmware.read(buffer); //将文件内容填充到数组中
Firmware.close();
byte[] data = decode(buffer, Base64.DEFAULT); //将文件内容base64解码,并将解码的内容填充到data数组中
ByteArrayInputStream Byte_data_io = new ByteArrayInputStream(data); //data数组==>转换成输入流
InflaterInputStream decompressionStream = new InflaterInputStream(Byte_data_io);//将字节流放进解压容器,解压的内容在decompressionStream中(将字节流进行解压)
byte imagebyte[] = new byte[i_size];
for (int a = 0; a < imagebyte.length; a++) //将字节数组初始化为0xff
{
imagebyte[a] = (byte) 0xff;
}
for(int i = 0; i<968312;i=i+1) {
decompressionStream.read(imagebyte, i, 1); //将字节流读进imagebyte数组中
}
//数组拆分
List groups =__split_len(imagebyte,60);;//将固件分为60大小的字节存进集合groups中
for(int i = 0 ; i < groups.size(); i ++){
__program_multi(groups.get(i));
}
} catch (FileNotFoundException e) {
//Toast.makeText(getApplicationContext(), e.toString() + e.getMessage(), Toast.LENGTH_LONG).show();
} catch (IOException e) {
//Toast.makeText(getApplicationContext(), e.toString() + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
public List __split_len(byte[] seq, int size) {
List answer = new ArrayList<>(); //创建list集合
//int size = length;
for (int a = 0; a < seq.length;) {
byte[] ba = new byte[size];
arraycopy(seq, a, ba, 0, size); //数组拷贝
answer.add(ba);
a += size;
if ((seq.length - a) < size)
size = seq.length - a;
}
return answer;
}
public boolean __program_multi(byte[] data) //发送多个数据包
{
final byte[] Start = {code.PROG_MULTI,(byte)data.length};
final byte[] End = {code.EOC};
usbCDCConnection.sendBuffer(Start);
usbCDCConnection.sendBuffer(data);
usbCDCConnection.sendBuffer(End);
byte aa[] = new byte[2];
try {
usbCDCConnection.readDataBlock(aa);
if(aa[0] == 0x12 && aa[1] == 0x10){
return true;
}else{
return false;
}
} catch (IOException e) {
return false;
//e.printStackTrace();
}
}
public void Reboot(){
byte Reboot[] = {code.REBOOT,code.EOC};
usbCDCConnection.sendBuffer(Reboot);
byte bb[] = new byte[2];
try {
usbCDCConnection.readDataBlock(bb);
/* if(bb[0] == 0x12 && bb[1] == 0x10){
Message message = new Message();
message.what = 10; //重启成功
m_handler.sendMessage(message);
}else{
Message message = new Message();
message.what = 11; //重启失败
m_handler.sendMessage(message);
}*/
} catch (Exception e){
}
}
}
class Code{
// response codes
byte NOP = 0x00,
OK = 0x10,
FAILED = 0x11,
INSYNC = 0x12,
INVALID = 0x13,
// protocol commands
EOC = 0x20,
GET_SYNC = 0x21,
GET_DEVICE = 0x22, // returns DEVICE_ID and FREQ bytes
CHIP_ERASE = 0x23,
LOAD_ADDRESS = 0x24,
PROG_FLASH = 0x25,
READ_FLASH = 0x26,
PROG_MULTI = 0x27,
READ_MULTI = 0x28,
REBOOT = 0x30;
}