Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Source code for hci_dfu_send_hex.exe

I need a bootloader that I can use for my application that doesn't use a soft device and allows the firmware to be transferred through uart.  Going through the forums, I found a reference to a bootloader that does what I needed.  That package is nrf51822_v4.4 - Bootloader_Without_SD.zip.  I downloaded and installed that package and with a little effort, I was able to get the bootloader to work.  That same package included the following executable:

<path>/nrf51822_v4.4_Bootloader_Without_SD/Board/nrf6310/device_firmware_updates/experimental/hci_dfu_send_hex/hci_dfu_send_hex.exe

This executable is built to be ran on a Windows machine.  When using this executable on a Windows machine, it is a very simple mater to set up the bootloader to load the application and then run this program to transfer the file.  Everything works as it should.  Very nice job!

Now for my problem.  I will need to be able to load the new firmware from an embedded system and therefore, hci_dfu_send_hex.exe is not an option.  I tried downloading and running nrfutil version 0.5.2 as directed in multiple documents on this site, but it is a very different program than hci_dfu_send_hex.exe.  It is also not directly compatible with the bootloader and fails if you try to use it with this bootloader.  I tracked down the first issue to being a different enumerated value for the Packet Identifiers.  Here is how they are defined in dfu_types.h that's being used by the bootloader:

#define INVALID_PACKET                  0x00                                                    /**< Invalid packet identifies. */
#define INIT_PACKET                     0x01                                                    /**< Packet identifies for initialization packet. */
#define START_DATA_PACKET               0x02                                                    /**< Packet identifies for the Data Start Packet. */
#define DATA_PACKET                     0x03                                                    /**< Packet identifies for a Data Packet. */
#define STOP_DATA_PACKET                0x04                                                    /**< Packet identifies for the Data Stop Packet. */

But according to the information that I found in the Serial (HCI) packet format document on this site, they should be defined as:

#define INVALID_PACKET                  0x00                                                    /**< Invalid packet identifies. */
#define INIT_PACKET                     0x01                                                    /**< Packet identifies for initialization packet. */
#define START_DATA_PACKET               0x03                                                    /**< Packet identifies for the Data Start Packet. */
#define DATA_PACKET                     0x04                                                    /**< Packet identifies for a Data Packet. */
#define STOP_DATA_PACKET                0x05                                                    /**< Packet identifies for the Data Stop Packet. */

After making this change to my bootloader, nrfutil now runs through, but fails at the end with the following error:

<path>\nrfutil\pc-nrfutil>python .\nordicsemi\__main__.py dfu serial --package <path>\examples\peripheral\blinky\pca10031\blank\arm5_no_packs\_build\nrf51422_xxac.zip --port COM4 --baudrate 38400
Upgrading target on COM4 with DFU package <path>\examples\peripheral\blinky\pca10031\blank\arm5_no_packs\_build\nrf51422_xxac.zip. Flow control is disabled.
  [####################################]  100%             Timed out waiting for acknowledgement from device.


Failed to upgrade target. Error is: No data received on serial port. Not able to proceed.

Possible causes:
- bootloader, SoftDevice or application on target does not match the requirements in the DFU package.
- baud rate or flow control is not the same as in the target bootloader.
- target is not in DFU mode. If using the SDK examples, press Button 4 and RESET and release both to enter DFU mode.

So this tells me that there's something that nrfutil is expecting the bootloader to return but the bootloader is failing to do so given that is wasn't written to be compatible with nrftutil.

So what I would like to know is, is the source code for hci_dfu_send_hex.exe available?  Having that source code which is compatible with the SDK v4.4 bootloader will make my porting task much simpler.  

Thanks in advance...

Parents
  • I've managed to recover the original python source code from hci_dfu_send_hex.exe.  Here is the procedure that I used:

    Download and install 'PyExe Binary Editor v0.1' from here.  This file is compressed with 7-Zip, so you may need to install that as well to install this program.

    Execute the program and use it to extract PYTHONSCRIPT and library.zip from hci_dfu_send_hex.exe.

    Once you have PYTHONSCRIPT, follow the instructions in 'Reversing Py2Exe.pdf' to create a python script that you will use to extract the python byte code files from PYTHONSCRIPT.  The script will look like this:

    import marshal, imp
    f = open('PYTHONSCRIPT', 'rb')
    f.seek(17) # Skip the header, you have to know the header size beforehand
    ob=marshal.load(f)
    for i in range(0, len(ob)):
        open(str(i) + '.pyc', 'wb').write(imp.get_magic() + '\0'*4 + marshal.dumps(ob[i]))
    f.close()

    This script will extract three python byte code files; 0.pyc, 1.pyc, and 2.pyc

    Next, download and install 'Easy Python Decompiler' from here.

    Execute this program and use it to convert the *.pyc files to *.pyc_dis files.

    Once you have the *.pyc_dis, you can open up the files with any flat file editor and the first line lists the name of the original *.py file.  You will want to find and rename the file for hci_dfu_send_hex.py.

    You may also need to unzip library.zip to get crc16pure.pyc, then use 'Easy Python Decompiler' to convert it to crc16pure.pyc_dis, and then rename it to crc16pure.py.  I believe that crc16pure is also available on github.

    Once you have hci_dfu_send_hex.py and crc16pure.py, you can execute the program as shown below:

    >python hci_dfu_send_hex.py --file blinky.hex --port COM4 --baudrate 38400
    Sending file blinky.hex to COM4, flow control = False
    Progress: 0
    Progress: 0
    Progress: 20
    Progress: 40
    Progress: 60
    Progress: 100

    As a side note, this python script works under Linux as well.  But be aware that you may need to adjust the uart buffer size to match your system.  I needed to change the buffer size in file hci_dfu_send_hex.py from 512 to 48.

    That's it for now...

Reply
  • I've managed to recover the original python source code from hci_dfu_send_hex.exe.  Here is the procedure that I used:

    Download and install 'PyExe Binary Editor v0.1' from here.  This file is compressed with 7-Zip, so you may need to install that as well to install this program.

    Execute the program and use it to extract PYTHONSCRIPT and library.zip from hci_dfu_send_hex.exe.

    Once you have PYTHONSCRIPT, follow the instructions in 'Reversing Py2Exe.pdf' to create a python script that you will use to extract the python byte code files from PYTHONSCRIPT.  The script will look like this:

    import marshal, imp
    f = open('PYTHONSCRIPT', 'rb')
    f.seek(17) # Skip the header, you have to know the header size beforehand
    ob=marshal.load(f)
    for i in range(0, len(ob)):
        open(str(i) + '.pyc', 'wb').write(imp.get_magic() + '\0'*4 + marshal.dumps(ob[i]))
    f.close()

    This script will extract three python byte code files; 0.pyc, 1.pyc, and 2.pyc

    Next, download and install 'Easy Python Decompiler' from here.

    Execute this program and use it to convert the *.pyc files to *.pyc_dis files.

    Once you have the *.pyc_dis, you can open up the files with any flat file editor and the first line lists the name of the original *.py file.  You will want to find and rename the file for hci_dfu_send_hex.py.

    You may also need to unzip library.zip to get crc16pure.pyc, then use 'Easy Python Decompiler' to convert it to crc16pure.pyc_dis, and then rename it to crc16pure.py.  I believe that crc16pure is also available on github.

    Once you have hci_dfu_send_hex.py and crc16pure.py, you can execute the program as shown below:

    >python hci_dfu_send_hex.py --file blinky.hex --port COM4 --baudrate 38400
    Sending file blinky.hex to COM4, flow control = False
    Progress: 0
    Progress: 0
    Progress: 20
    Progress: 40
    Progress: 60
    Progress: 100

    As a side note, this python script works under Linux as well.  But be aware that you may need to adjust the uart buffer size to match your system.  I needed to change the buffer size in file hci_dfu_send_hex.py from 512 to 48.

    That's it for now...

Children
No Data
Related