|
|
|
@ -13,6 +13,8 @@ import shutil
@@ -13,6 +13,8 @@ import shutil
|
|
|
|
|
import sys |
|
|
|
|
import re |
|
|
|
|
import pickle |
|
|
|
|
import zlib |
|
|
|
|
import struct |
|
|
|
|
|
|
|
|
|
_dynamic_env_data = {} |
|
|
|
|
def _load_dynamic_env_data(bld): |
|
|
|
@ -93,6 +95,46 @@ class generate_bin(Task.Task):
@@ -93,6 +95,46 @@ class generate_bin(Task.Task):
|
|
|
|
|
def __str__(self): |
|
|
|
|
return self.outputs[0].path_from(self.generator.bld.bldnode) |
|
|
|
|
|
|
|
|
|
def to_unsigned(i): |
|
|
|
|
'''convert a possibly signed integer to unsigned''' |
|
|
|
|
if i < 0: |
|
|
|
|
i += 2**32 |
|
|
|
|
return i |
|
|
|
|
|
|
|
|
|
class set_app_descriptor(Task.Task): |
|
|
|
|
'''setup app descriptor in bin file''' |
|
|
|
|
color='BLUE' |
|
|
|
|
always_run = True |
|
|
|
|
def keyword(self): |
|
|
|
|
return "app_descriptor" |
|
|
|
|
def run(self): |
|
|
|
|
if not 'APP_DESCRIPTOR' in self.env: |
|
|
|
|
return |
|
|
|
|
if self.env.APP_DESCRIPTOR == 'MissionPlanner': |
|
|
|
|
descriptor = b'\x40\xa2\xe4\xf1\x64\x68\x91\x06' |
|
|
|
|
else: |
|
|
|
|
Logs.error("Bad APP_DESCRIPTOR %s" % self.env.APP_DESCRIPTOR) |
|
|
|
|
return |
|
|
|
|
img = open(self.inputs[0].abspath(), 'rb').read() |
|
|
|
|
offset = img.find(descriptor) |
|
|
|
|
if offset == -1: |
|
|
|
|
Logs.error("Failed to find %s APP_DESCRIPTOR" % self.env.APP_DESCRIPTOR) |
|
|
|
|
return |
|
|
|
|
offset += 8 |
|
|
|
|
# next 8 bytes is 64 bit CRC. We set first 4 bytes to |
|
|
|
|
# CRC32 of image before descriptor and 2nd 4 bytes |
|
|
|
|
# to CRC32 of image after descriptor. This is very efficient |
|
|
|
|
# for bootloader to calculate |
|
|
|
|
# after CRC comes image length and 32 bit git hash |
|
|
|
|
desc_len = 16 |
|
|
|
|
crc1 = to_unsigned(zlib.crc32(img[:offset])) |
|
|
|
|
crc2 = to_unsigned(zlib.crc32(img[offset+desc_len:])) |
|
|
|
|
githash = to_unsigned(int('0x' + self.generator.bld.git_head_hash(short=True),16)) |
|
|
|
|
desc = struct.pack('<IIII', crc1, crc2, len(img), githash) |
|
|
|
|
img = img[:offset] + desc + img[offset+desc_len:] |
|
|
|
|
Logs.info("Applying %s APP_DESCRIPTOR %08x%08x" % (self.env.APP_DESCRIPTOR, crc1, crc2)) |
|
|
|
|
open(self.inputs[0].abspath(), 'wb').write(img) |
|
|
|
|
|
|
|
|
|
class generate_apj(Task.Task): |
|
|
|
|
'''generate an apj firmware file''' |
|
|
|
|
color='CYAN' |
|
|
|
@ -148,6 +190,7 @@ def chibios_firmware(self):
@@ -148,6 +190,7 @@ def chibios_firmware(self):
|
|
|
|
|
self.link_task.always_run = True |
|
|
|
|
|
|
|
|
|
link_output = self.link_task.outputs[0] |
|
|
|
|
hex_task = None |
|
|
|
|
|
|
|
|
|
bin_target = self.bld.bldnode.find_or_declare('bin/' + link_output.change_ext('.bin').name) |
|
|
|
|
apj_target = self.bld.bldnode.find_or_declare('bin/' + link_output.change_ext('.apj').name) |
|
|
|
@ -177,7 +220,14 @@ def chibios_firmware(self):
@@ -177,7 +220,14 @@ def chibios_firmware(self):
|
|
|
|
|
src=link_output) |
|
|
|
|
default_params_task.set_run_after(self.link_task) |
|
|
|
|
generate_bin_task.set_run_after(default_params_task) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.env.APP_DESCRIPTOR: |
|
|
|
|
app_descriptor_task = self.create_task('set_app_descriptor', src=bin_target) |
|
|
|
|
app_descriptor_task.set_run_after(generate_bin_task) |
|
|
|
|
generate_apj_task.set_run_after(app_descriptor_task) |
|
|
|
|
if hex_task is not None: |
|
|
|
|
hex_task.set_run_after(app_descriptor_task) |
|
|
|
|
|
|
|
|
|
if self.bld.options.upload: |
|
|
|
|
_upload_task = self.create_task('upload_fw', src=apj_target) |
|
|
|
|
_upload_task.set_run_after(generate_apj_task) |
|
|
|
|