This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SDK 15.3 Secure Serial UART Bootloader does not handle NRF_DFU_OP_OBJECT_WRITE (data)

Hi,

I am currently trying to use SDK 15.3 secure serial UART bootloader (from the example in nRF5_SDK_15.3.0_59ac345\examples\dfu\secure_bootloader\pca10040_uart) on a custom chip embedding an nRF52832 and a GSM chip, communicating between themselves via UART. In order to adapt the given example to my particular case, I just added in nrf_dfu_init() function the power-on of the GSM chip. I also modified UART configuration (pinout, HWFC activated, baudrate = 57600).

After calling this function, the bootloader then loops forever (loop_forever() function), and waits for commands, via UART, from the GSM chip. The GSM chip basically connects to server, downloads new firmware, checks if a firmware upgrade is needed, and "if true" starts to transfer said firmware to nRF52832.

Here is the detailed communication between GSM and nRF52832, from the GSM chip point of view:

<--Sent CMD: 02, len: 4-->
Received 0x02 0x01

<--Sent CMD: 07, len: 2-->
Received 0x07 0x01

<--Sent CMD: 06, len: 3-->
Received 0x06 0x01

<--Sent CMD: 01, len: 7-->
Received 0x01 0x01

<--Sent CMD: 08, len: 130--> (command)
<--Sent CMD: 08, len: 16-->  (command)
<--Sent CMD: 03, len: 2-->
Received 0x03 0x01
<-- Received CALC CRC message response -->
<-- Received CRC: 912423956 (36627C14), local CRC: 912423956(36627C14) -->
<-- Received offset: 141, local offset: 141 -->

<--Sent CMD: 04, len: 2-->
Received 0x04 0x01

<--Sent CMD: 06, len: 3-->
Received 0x06 0x01

<--Sent CMD: 01, len: 7-->
Received 0x01 0x01

<--Sent CMD: 08, len: 129-->	(data)
<-- Sent 127 bytes, local CRC: -1046533821(C19F2943) -->
<--Sent CMD: 08, len: 129-->	(data)
<-- Sent 254 bytes, local CRC: -340869425(EBAEBECF) -->
<--Sent CMD: 08, len: 129-->	(data)
<-- Sent 381 bytes, local CRC: -793576822(D0B2FA8A) -->
<--Sent CMD: 08, len: 129-->	(data)
<-- Sent 508 bytes, local CRC: 143380219(088BCEFB) -->

...


<--Sent CMD: 08, len: 34-->	(data)
<-- Sent 4096 bytes, local CRC: 1943765718(73DB82D6) -->

<--Sent CMD: 03, len: 2-->

This command sequence is right and was working perfectly fine with a secure serial UART bootloader I used with SDK 12.1. The problem here is that after having received and handled successfully the 2 first chunks of data (lines 30 and 32), so 254 bytes, the nRF52832 seems to stop receiving the data, or at least handling it: it does not go into the case NRF_DFU_OP_OBJECT_WRITE from the nrf_dfu_serial_on_packet_received() function anymore. As so of course it doesn't reply to the CRC command (0x03, line 45) sent by the GSM chip, which is waiting for a CRC answer before proceeding with sending next data packet.

Now I am having trouble understanding the source of this issue. I thought at first that it could be a full buffer issue, but it is supposed to be freed asynchronously. I then thought the GSM chip was sending chunks of data too quickly for the nRF52832 to handle, but even after adding a 500ms delay between each chunks (originally 100ms), the issue is still there.

Also, for some reason the logs are not working properly, which does not help debugging... Some of them seems to be missing on the viewer, and they appear very slowly, like they are flushed 30 seconds after being called (and again, not all of them...). So for now my only way of debugging, which is also how I know of this issue, is a buzzer embedded on the board.

Thank you in advance for any help !

  • sizeof(m_slip.p_buffer) is only the size of the pointer, not the size of the array, you should find the size of the packet in m_slip.current_index. 

    How do you detect that it stuck in point 1 can can't get to point 2 ? I don't think it would stuck in wait_for_flash_ready(). It only checks the hardware register and we haven't seen any case the hardware (writing to flash) wouldn't work. 

    I would suggest to print out log instead of line stepping .

    How do you find that the issue is from nrf_nvmc_write_words () ? 

  • With RX_BUF_SIZE = 127 and GSM chip sending 100 bytes data packets, m_slip.current_index
    = 101 bytes, so 100 bytes payload + 1 command byte.

    I agree printing out the log would be preferable but one of my issue previously stated is that I can not: the log is printed with quite an important delay, and as the MCU seems to crash after receiving the 2nd data packet, I can't access debug logs after a certain point.

    I detect it because my custom board has a buzzer that I can use to know when the code reaches certain points, and I used it on point 1 and point 2. That is kow I know that as some point the code reaches point 1 but never point 2.

    I found the issue is from nrf_nvmc_write_words () using the method previously stated.

    Could it be a problem related to the presence of a SoftDevice with the bootloader ?

  • Oh, I was not aware that you have the softdevice. Was the softdevice initialized when you call nrf_nvmc_write_words() ?

    If the softdevice is initialized you would need to nrf_fstorage_sd.c instead of nrf_fstorage_nvmc.c. There could be a chance that the timing needed to write 64 bytes was OK with the softdevice but not 100 bytes. 

  • Well, SoftDevice 6.1.1 is programmed on the chip before downloading bootloader, because without it bootloader alone doesn't seem to do anything, but the purpose of this bootloader will be at some point to download and write into memory this SoftDevice 6.1.1 in order to replace an older one. So I guess it is supposed to be able to work without it, and the fact that it can not seem to for now is also an issue.

    Plus my SDK 12.1 serial bootloader was using nrf_nvmc_write_words() also.

    What would be this timing problem ?

    UPDATE: Bootloader works without SoftDevice if I add MBR hex file to bootloader (nRF5_SDK_15.3.0_59ac345\components\softdevice\mbr\nrf52832\hex).

  • Yes an MBR is needed for the bootloader to do DFU update itself as well as to receive the interrupt vector forwarding. 

    If you don't initiate the softdevice (calling sd_mbr_command() with SD_MBR_COMMAND_INIT_SD) , it shouldn't be a problem to access the flash directly using NVMC. 

    Note that if you use an GPIO to detect if you can get to point 1 or point 2, you should also check if there is any assertion that interrupt the process. Please check if the CPU get to any of the app error handler function. 

    Have you tried to test using debug mode ? And the check where the CPU is at when it stuck ? 

    It's a little bit harder for us to reproduce the issue here to test what you described (due to that we need to customize the DFU master). We will try to find time to test but it's a bit busy here. 

Related