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

Fault When Reading Magic From Image Header

Hi,

I am trying to send some information from the application image (e.g. header, TLVs, etc.) through a SPI channel. 

The problem is that whenever I try to copy the header information of the application from Flash to a buffer in RAM I always get a fault, and I don't understand why. My pointers are correct, I have tried memcpy, a for loop, direct byte by byte copy, and always get the same result. Are there any restrictions to copy Flash to RAM?

As an example, the code below is just trying to copy the magic value (4 bytes) from the application's header to a buffer in RAM. As mentioned, using memcpy, a for loop, direct copy, will cause a fault. I know my destination buffer is fine, because I can just write a value to it and it works without generating the fault.

Thoughts?

const uint8_t *image_header = (const uint8_t *)0x10000;
uint8_t magic_nr_length = sizeof(uint32_t);

#define OPT 0   // This is to select the example code to copy the magic to the RAM buffer.

#if OPT == 0
    memcpy(tx_data.buffer, image_header, magic_nr_length);  // This causes a fault.
#elif OPT == 1
    for (uint16_t i = 0; i < magic_nr_length; i++)    // This causes a fault.
    {
        tx_data.buffer[i] = image_header[i];
    }
#elif OPT == 2    // This causes a fault
    tx_data.buffer[0] = image_header[0];
    tx_data.buffer[1] = image_header[1];
    tx_data.buffer[2] = image_header[2];
    tx_data.buffer[3] = image_header[3];
#else

    // This does not cause a fault.

    tx_data.buffer[0] = 0x96;
    tx_data.buffer[1] = 0xf3;
    tx_data.buffer[2] = 0xf8;
    tx_data.buffer[3] = 0x3d;
#endif

Thanks in advance.

  • Forgot to add, this is happening in an nRF9160. I have tried the same in an nRF5340 and I don't see the issue.

  • Hello,

    Is there a chance that the source pointer may be pointing to the secure domain? Do you have any debug logs from the device? I think the crashlog might provide some more clues. Just make sure you have CONFIG_RESET_ON_FATAL_ERROR set to 'n' in your prj.conf file for both SPM and your app to prevent it from entering a boot loop. 

    Best regards,

    Vidar

  • Hi Vidar,

    I am using a non-secure board for the 9160, but we do have the mcuboot enabled and the application is signed. Is this what you refer about the secure domain?

    All I want to do is to read the header and some of the TLV information from the application, so I can send it to a master SPI peripheral which will compare it to a locally stored 9160 image and determine if an update is needed.

    If I can't read the header and TLV information from the 9160, what options do I have to accomplish this?

    In the meantime I will check about the debug log as well.

    Best regards

    Peter

  • Hi Peter,

    Yes I was wondering if you built the app as non-secure. I think you may be attempting to read from the mcu pad area for the SPM which runs in the Trust Zone secure domain.

    Here is a screenshot I took from VS code with the new nRF connect plug-in to illustrate what the typical memory layout may look like:

    Notice that the main non-secure application starts after the SPM at 0x50000.

    Best regards,

    Vidar

  • Hi Vidar,

    See the layout in my project below, which looks similar to the one you sent:

    Regarding the secure and non-secure partitions, in the DTS they are currently as follows:

    partitions {
    						compatible = "fixed-partitions";
    						#address-cells = < 0x1 >;
    						#size-cells = < 0x1 >;
    						boot_partition: partition@0 {
    							label = "mcuboot";
    							reg = < 0x0 0x10000 >;
    						};
    						slot0_partition: partition@10000 {
    							label = "image-0";
    							reg = < 0x10000 0x40000 >;
    						};
    						slot0_ns_partition: partition@50000 {
    							label = "image-0-nonsecure";
    							reg = < 0x50000 0x30000 >;
    						};
    						slot1_partition: partition@80000 {
    							label = "image-1";
    							reg = < 0x80000 0x40000 >;
    						};
    						slot1_ns_partition: partition@c0000 {
    							label = "image-1-nonsecure";
    							reg = < 0xc0000 0x30000 >;
    						};
    						scratch_partition: partition@f0000 {
    							label = "image-scratch";
    							reg = < 0xf0000 0xa000 >;
    						};
    						storage_partition: partition@fa000 {
    							label = "storage";
    							reg = < 0xfa000 0x6000 >;
    						};
    					};

    From looking into memory, I don't have anything in the non secure partition at 0x50000, but I do in the secure one at 0x10000. Not sure why this is happening because the board file I use specifies the code to be in the non-secure partition:

    zephyr,code-partition = &slot0_ns_partition;

    Thoughts?

    Regards

    Peter

Related