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 !

  • Hi Pierre, 

    Shouldn't we focus on solving the 127 bytes byte issue first ? Could you try to test just updating the APP without the SD ? 

    I'm don't think we support updating SD+APP from a non-softdevice bootloader. You can merge the softdevice and app and then updating it as an app. But we can solve this after we solve the 127 bytes packet issue. 

  • Hi,

    I agree, hence my update. Serial bootloader + MBR gives me the same hard fault at the same point (second data packet received).

  • Hi,

    Hung asked me to follow up on this case as he's out of office this week. There has been a while since the last update, have you had any progress in the meantime?

    As a test, I think it would be interesting if you could try adding a delay between every packet on the controller side and see if that makes a difference (w 127 byte MTU). Also, the stack frame from the hardfault handler appears to be incorrect. The LR value is not pointing to a valid address but is a typical value for xPSR. It might be worth trying the hardfault handler included in the SDK, I'm not familiar with the ARM version, but this implementation will detect stack overflow as well. 

    Do the following to use the SDK Hardfault handler:

    Add  "\nRF5_SDK_15.2.0_9412b96\components\libraries\hardfault\nrf52\handler\hardfault_handler_keil.c" and "\nRF5_SDK_15.2.0_9412b96\components\libraries\hardfault\hardfault_implementation.c" to the project and build with HARDFAULT_HANDLER_ENABLED=1

    Best regards,

    Vidar

  • Hi Vidar, thank you for your help.

    No progress in the meantime no, I used 100 bytes data packet to continue my project, but it can't be a final solution...

    By default, a delay of 100 ms is present between every data packet sent by the GSM chip to the NRF52, and I tried increasing this delay (up to 1000ms), but it doesn't change anything.

    Here are the results shown by the SDK 15.2 Hardfault Handler (I am still going into HardFault when handling, so writing, the second 127 bytes data packet received whith RX_BUF_SIZE = 127):

    <error> hardfault: HARD FAULT at 0x00076F90
    <error> hardfault:   R0:  0x0263DB00  R1:  0x4001E504  R2:  0x0000001F  R3:  0x00000001
    <error> hardfault:   R12: 0x0007AD89  LR:  0x0007ADB9  PSR: 0x81000000
    <error> hardfault: Cause: Data bus error (PC value stacked for the exception return points to the instruction that caused the fault).
    <error> hardfault: Bus Fault Address: 0x0002607F

    The PC value points to this line in the code:

    The LR value points to this line in the code:

    And BFAR value, which I'm guessing represents the address where the value should be written:

    More precisely, the HardFault PC points to the "STR" assembly instruction, that is supposed to store (at the address r5+(r4<<2)) the data and that causes the fault here:

    I checked the assembly code for the same C instruction in my SDK 12.1 Serial Bootloader, that works with 127 bytes packets, and I see no difference in the assembly code, except for the registers used:

    UPDATE:

    After running some tests, it seems that this issue may have to do with the size of sent data packets, in bytes, being a multiple of 4. It actually works for 124 bytes data packets with RX_BUF_SIZE >= 124. It also works with 128 bytes data packets with RX_BUF_SIZE = 128, but for this precise case I get a NRF_DRV_UART_EVT_ERROR when trying to send CRC via UART after the reception of the first 4096 bytes of data.

    Any reason for a non divisible per 4 size not working ? Could it come from the fact that the packet length is at some point divided by 4 to equal the number of words ?

  • Hi,

    Thanks for the update. This stack frame looks more correct. I will try to replicate then debug this on my side to see if I can find the root cause. I'll keep you posted.

Related