nRF5340 - Accessing Shared Memory

Hello. I am just getting started with nRF5340 development using the u-Blox NORA-B106 dev kit. I am trying to use the peripheral_uart code example to understand how the two processors use the shared memory space to communicate. I am able to send data over Bluetooth and have it appear in a terminal connected to the J-link UART, so the app is working. But tracing through the code, I'm unable to find where the received data is being put in shared memory so the UART function call can see it.

1) Can someone point me to the specific code within this example where this happens?

2) In general, how do you assign a variable to reside in this space so that both processors can access it? I'm assuming this is done through linker files for both net and app builds so that the same variable is mapped to the same memory location, but I can't find those files either.

Coming from STM32 and FreeRTOS, so the Zephyr learning curve is feeling steep so far. Any help is appreciated.

Thanks,

Jamie

  • Hello Jamie,

    I will get back to you on this. Note that we have entered the summer holiday period in Norway so staffing is low, some delayed response time should be expected.

    Regards,

    Elfving

  • Hello again,

    Coming from STM32 and FreeRTOS, so the Zephyr learning curve is feeling steep so far. Any help is appreciated.

    That is very understandable. To start off, I would recommend you to take a look at our DevAcademy, which will give you a basic understanding of Zephyr.

    You are right in that the inter-core communication is happening using shared memory. This is unfortunately a complex topic, and difficult to give basic example of. The documentation on the nRF5340 and the documentation on working with it describes a little bit about it. And this previous case of mine describes a bit more. Taking a look at the examples I linked to there will probably be beneficial, and answer your second question.

    When it comes to how this is done in a project like the peripheral_uart sample, I would have to get back to you.

    Regards,

    Elfving

  • Thank you. the DevAcademy link looks like a very good starting point. I will work my way through that.

  • Hello. I am revisiting this topic lately and still need some clarification. I am looking at the device tree includes and can see that both the peripheral_uart project and the hci_rpmsg project eventually include "nrf5340_shared_sram_planning_conf.dts" which gives the following:

    chosen {
       /* shared memory reserved for the inter-processor communication */
       zephyr,ipc_shm = &sram0_shared;
    };

    reserved-memory {
       #address-cells = <1>;
       #size-cells = <1>;
       ranges;

       sram0_shared: memory@20070000 {
          /* SRAM allocated to shared memory */
          reg = <0x20070000 0x10000>;
       };
    };

    So now we have established a shared memory region, okay, so far so good. Next, I see in each device tree, somewhere the following eventually gets included:

    ipc0: ipc0 {
       compatible = "zephyr,ipc-openamp-static-vrings"; 
       memory-region = <&sram0_shared>;
       mboxes = <&mbox 0>, <&mbox 1>;
       mbox-names = "tx", "rx";
       role = "host";
       status = "okay";
    };

    So now we have the ipc module attached to the shared memory region. However, here is where I get lost. How do each of the programs use this memory region? Normally I would expect to see something like __attribute__ used in front of a variable to denote that it should be placed in that region by the linker (also, where are the linker files?).

    In the hci_rpmsg main.c, I can at least see some references to this, such as:

    const struct device *hci_ipc_instance = DEVICE_DT_GET(DT_NODELABEL(ipc0));
    and:
    const struct device *hci_ipc_instance = DEVICE_DT_GET(DT_NODELABEL(ipc0));
    But how does this link back to the sram0_shared region? Also, how are the mailboxes used in this context? How large are the mailboxes (i.e. where is the mailbox size determined).
    Now, on the other end, the main.c from the peripheral_uart project, I don't see any references to the ipc system at all. This leads me to believe that the bt_nus is somehow uses this information behind the scenes, but I'm so far unable to follow the function calls back through to anything that makes this explicit. How is peripheral_uart using the ipc system and the shared memory?
    -Jamie
  • Another notable thing - looking at both zephyr.map files, neither file seems to have any data structures living in the shared memory range. Shouldn't I see some overlapping variables at 0x20070000 vicinity?

Related