Upload Tensorflow Lite to Artemis Nano

I have been trying to upload the binary file (source https://codelabs.developers.google.com/ … sorflow/#5) to Artemis Nano.

The binary file is a file that contains the program in a form that can be run directly by the SparkFun Edge hardware. It was compiled from the Micro example (https://github.com/tensorflow/tensorflo … rkfun-edge) in the Tensorflow lite folder (https://github.com/tensorflow/tensorflo … rflow/lite).

I assumed that since Artemis Nano and SparkFun Edge both have the same ARM Cortex-M4F architecture, the binary file which works on Edge should be working on Artemis Nano as well.

Whenever after Artemis boots up, it would wait 50 ms to detect an incoming character from the serial. For this reason, I assumed anything uploaded to Artemis Nano in that 50 ms would be flashed to the memory and become the new code.

So I upload the binary file (main_nonsecure_wire.bin) using this command

cat <BinaryFile> > <DevicePort>
cat main_nonsecure_wire.bin > /dev/ttyUSB0

I also tried “minicom” for uploading.

However, Artemis Nano only showed RX LED light up but without flashing the existing code in the memory.

Does anyone have an idea to upload an accepted binary file to Artemis Nano?
Or generally, how to implement TensorFlow lite microcontroller examples (https://github.com/tensorflow/tensorflo … o/examples) to Artemis Nano?

Are you familiar with the bootloader tools? The action you described is incorrect - the Apollo3 samples the ‘boot’ pin at startup and if it is in the proper state then the bootloader begins operating (otherwise code execution begins). The bootloader does indeed communicate over a serial (uart) connection but it is not as simple as transmitting the image directly. There is error checking, recovery, etc.

Using the ambiq secure bootloader (ASB) is a three-step process:

  1. Generate an OTA signed image from the original executable binary file

  2. Generate a wired signed image from the OTA image

  3. Use the bootloader script to transmit the wired signed image.

These three steps are combined into one python script here: https://github.com/sparkfun/SparkFun_Ap … n2board.py

Check the --help option for usage info

The Nano also comes with a secondary bootloader that is easier to use and faster (though it requires code to be linked with a different starting address - this would require changes to the TensorFlow source code) You can see that here: https://github.com/sparkfun/SparkFun_Ap … mis_svl.py

To use that bootloader you need to flash the corresponding embedded bootloader onto the board. The best way is to use Arduino. See here: viewtopic.php?f=163&t=50480

Furthermore - though you might think that the same firmware for the Edge would work on the Artemis modules we encountered difficulty.

https://github.com/tensorflow/tensorflow/pull/31847

@liquid.soulder, thank you for the detailed explanation.

I have been trying to upload “micro_speech.bin” using ambiq_bin2board.py (https://github.com/sparkfun/SparkFun_Ap … n2board.py) and artemis_svl.py (https://github.com/sparkfun/SparkFun_Ap … mis_svl.py). However, both python scripts failed to upload the binary file to Artemis Nano.

python3 ambiq_bin2board.py --bin ~/tensorflow/tensorflow/lite/micro/tools/make/gen/sparkfun_nano_x86_64/bin/micro_speech.bin --load-address-blob 0x20000 --magic-num 0xCB -o main_nonsecure_ota --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b 115200 -port /dev/ttyUSB0 -r 2 -v

python3 artemis_svl.py -f ~/tensorflow/tensorflow/lite/micro/tools/make/gen/sparkfun_nano_x86_64/bin/micro_speech.bin -b 115200 -v -t 100 /dev/ttyUSB0

Both uploads required the baud rate at 115200 and terminated while sending the data packet. “ambiq_bin2board.py” failed three times and showed “Upload failed: No ack to command. Failed to ack command.” “artemis_svl.py” failed and three times as well and showed “Upload failed.”

If I understand correctly, Artemis Nano has two bootloaders on board which is Ambiq Secure Bootloader and SparkFun Variable Loader. Both python script, ambiq_bin2board.py and artemis_svl.py, could successfully upload a binary file. However, you mentioned that while uploading to Artemis Nano, the starting address needs to be modified.

I’m thinking of searching the Tensorflow micro_speech example and find out the part required modification.

Or should I dig in the Ambiq bootloader GitHub (https://github.com/sparkfun/AmbiqSuiteSDK) and find out the correct starting address for Artemis Nano?
Or what would other references I should study to make Micro_speech example (https://github.com/tensorflow/tensorflo … cro_speech) work on Artemis Nano?

Thanks for the great explanation of what you are doing - it definitely allows me to offer better advice.

I should let you know that it is not guaranteed to have both bootloaders - the SparkFun Variable Loader (SVL) is not protected in memory and is overwritten if the standard Ambiq Secure Bootloader (ASB) is ever used. You can easily re-flash it using the Arduino IDE to re-enable the SVL bootloader. What I am suggesting is that it is possible that at some point the SVL on your nano was overwritten and it needs to be re-installed.

Programs that are uploaded with the SVL are expected to begin at memory address 0x10000 (as opposed to those programs meant to be uploaded by the ASB which should begin at address 0xC000) The location where this is usually set is in the linker script. For example in the TensorFlow project that file is here: [apollo3evb.ld (the Edge shares a linker script with the Apollo3 Evaluation Board for the time being)](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/tools/make/targets/apollo3evb/apollo3evb.ld)

Whenever uploading the micro_speech.bin file with different address parameters in ambiq_bin2board.py ( https://github.com/sparkfun/SparkFun_Ap … n2board.py ), the error always showed “Failed to ack command”.

python3 ambiq_bin2board.py --bin ~/tensorflow/tensorflow/lite/micro/tools/make/gen/sparkfun_nano_ld_x86_64/bin/micro_speech.bin --load-address-blob 0x20000 --magic-num 0xCB -o main_nonsecure_ota --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b 115200 -port /dev/ttyUSB0 -r 2 -v

I can’t find the corresponding “–load-address-blob” and “–load-address-wired” in link files apollo3evb.ld (https://github.com/tensorflow/tensorflo … llo3evb.ld) or asb_svl_linker.ld (https://github.com/sparkfun/SparkFun_Ap … _linker.ld) or Artemis Bootloader (https://github.com/sparkfun/SparkFun_Ar … Bootloader). Alternatively, I changed the parameter to 0xC000 or 0x10000 in all combinations to the two address flags.

No matter which parameter I changed the error showed the same, “Upload failed: No ack to command”. However, acknowledge is not included in the UART communication protocol. UART is an asynchronous transmission that doesn’t require acknowledgment. From the Sparkfun Artemis Documents Apollo3_Blue_MCU_Data_Sheet_v0_10_0.pdf (https://github.com/sparkfun/SparkFun_Ar … 0_10_0.pdf ), I found only I2C required ACK command.

Could it be that ambiq_bin2board.py is using I2C to communicate with the Artemis Nano, however, CH340C serial chip on the Artemis Nano only accepts UART communication?
Therefore, when uploading to Artemis Nano we should only use artemis_svl.py (https://github.com/sparkfun/SparkFun_Ap … mis_svl.py)?
If so, I can’t locate the bootload address in the artemis_svl.py. Would you suggest me to look in other files?