<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>A bare metal example of Inter Processor Communication (IPC) on nrf5340</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/124930/a-bare-metal-example-of-inter-processor-communication-ipc-on-nrf5340</link><description>Dear experts, I am programming bare metal using Segger Embedded Studio and nrf.h and want to achieve a simple example of network core sending data to the application core. 
 Since the network core runs in non-secure domain and application core runs in</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 14 Oct 2025 06:32:33 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/124930/a-bare-metal-example-of-inter-processor-communication-ipc-on-nrf5340" /><item><title>RE: A bare metal example of Inter Processor Communication (IPC) on nrf5340</title><link>https://devzone.nordicsemi.com/thread/551353?ContentTypeID=1</link><pubDate>Tue, 14 Oct 2025 06:32:33 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:725a218c-33eb-467d-99d1-ead0ce5269bd</guid><dc:creator>JonasForssell</dc:creator><description>&lt;p&gt;Here is an update.&amp;nbsp;&lt;br /&gt;It works now. I summarize the solution below for anyone who is interested:&lt;br /&gt;&lt;br /&gt;App core main()&lt;br /&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;  spu_configure();
  ipc_rx_configure();
  ipc_rx_recieve();
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ipc_rx&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;volatile uint32_t __attribute__((section(&amp;quot;.shared_memory&amp;quot;))) shared_value;


// Configure the app core to trigger an event every time a message is transmitted from network core
void ipc_rx_configure(void) {

  // Enable interrupt for RECEIVE[0]
  NRF_IPC_S-&amp;gt;INTENSET = IPC_INTENSET_RECEIVE0_Msk;

  // Listen to channel 0
  NRF_IPC_S-&amp;gt;RECEIVE_CNF[0] = 1;
  
  // Enable IPC interrupt in NVIC
  NVIC_EnableIRQ(IPC_IRQn);

  // Start up the network core
  NRF_RESET_S-&amp;gt;NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release;

}


void ipc_rx_recieve(void) {

  // From now on this will be interrupt driven so stay here
  while (1) {

    //__WFE();
    }

}

// This event will be triggered every time there is a message.
void IPC_IRQHandler(void) {
    if (NRF_IPC_S-&amp;gt;EVENTS_RECEIVE[0]) {
        NRF_IPC_S-&amp;gt;EVENTS_RECEIVE[0] = 0;

        printf(&amp;quot;Message: &amp;quot;);
        printf(&amp;quot;%u&amp;quot;, shared_value);
        printf(&amp;quot; \n&amp;quot;);
    
    }
}

&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;spu&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#define SPU_RAM_REGION_INDEX 31

void spu_configure(void) {
// In secure boot eller startup p&amp;#229; application core
// Configure RAM region 31 (0x2003F000) as non-secure
NRF_SPU_S-&amp;gt;RAMREGION[SPU_RAM_REGION_INDEX].PERM =
   (SPU_RAMREGION_PERM_READ_Msk |
    SPU_RAMREGION_PERM_WRITE_Msk |
    SPU_RAMREGION_PERM_SECATTR_Non_Secure &amp;lt;&amp;lt; SPU_RAMREGION_PERM_SECATTR_Msk |
    SPU_RAMREGION_PERM_EXECUTE_Msk);    // SECATTR bit is 0 =&amp;gt; non-secure

}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;I have added a reference to the right memory area in the linker script for both network and application cores as&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;place at address 0x2003F000 { section .shared_memory };

//but for the network core I have also added
do not initialize                           { section .shared_memory };

// ...since the app core must unlock the area before the network core can write&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Here is the network core&amp;nbsp;&lt;br /&gt;&lt;br /&gt;main()&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt; ipc_tx_configure();

 while(1) {
  delay_one_second();
  ipc_tx_transmit();
  }&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;ipc_tx&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#define IPC_CHANNEL 0

volatile uint32_t __attribute__((section(&amp;quot;.shared_memory&amp;quot;))) shared_value;

void ipc_tx_configure(void){

// Set up the IPC channel 0 to be used for trigger a signal to application core.
// We will only send on channel 0 (so we set bit 0 here)
    NRF_IPC_NS-&amp;gt;SEND_CNF[IPC_CHANNEL] = 1;

}


void ipc_tx_transmit(void) {

    //Use the shared memory to send a message to the application core
    shared_value = 23;

    // Trigger IPC event on channel 0
    NRF_IPC_NS-&amp;gt;TASKS_SEND[IPC_CHANNEL] = 1;


}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: A bare metal example of Inter Processor Communication (IPC) on nrf5340</title><link>https://devzone.nordicsemi.com/thread/551293?ContentTypeID=1</link><pubDate>Mon, 13 Oct 2025 14:01:18 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7946d313-dece-4735-b3be-dbe51b53a2f6</guid><dc:creator>JonasForssell</dc:creator><description>&lt;p&gt;A small update.&lt;br /&gt;&lt;br /&gt;I can get the interrupt to work now. The app core has to listen to channel 0 and the network core has to be started from the app core.&lt;br /&gt;&lt;br /&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;// Configure the app core to trigger an event every time a message is transmitted from network core
void ipc_rx_configure(void) {

  // Enable interrupt for RECEIVE[0]
  NRF_IPC_S-&amp;gt;INTENSET = IPC_INTENSET_RECEIVE0_Msk;

  // Listen to channel 0
  NRF_IPC_S-&amp;gt;RECEIVE_CNF[0] = 1;
  
  // Enable IPC interrupt in NVIC
  NVIC_EnableIRQ(IPC_IRQn);

  // Start up the network core
  NRF_RESET_S-&amp;gt;NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release;


}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Next up is to figure out how I can transfer a message through shared memory.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;I read about that the IPC contains two registers for general purpose data GPMEM[0] and [1] but I cannot seem to get the data across to the other core.&lt;br /&gt;&lt;br /&gt;On the network core I use NRF_IPC_NS-&amp;gt;GPMEM[0] = 27;&lt;br /&gt;and on the application core I try&amp;nbsp;printf(&amp;quot;Value %u&amp;quot;, NRF_IPC_S-&amp;gt;GPMEM[0]);&lt;/p&gt;
&lt;p&gt;but the value does not seem to get across and stays at 0. Also in the debugger.&lt;br /&gt;Any thoughts?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: A bare metal example of Inter Processor Communication (IPC) on nrf5340</title><link>https://devzone.nordicsemi.com/thread/551246?ContentTypeID=1</link><pubDate>Mon, 13 Oct 2025 10:17:14 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d32e4f34-3c8b-4700-aa50-f2dc45cd54e0</guid><dc:creator>JonasForssell</dc:creator><description>&lt;p&gt;Thank you for your reply. I am not using Zephyr at all since this is bare metal.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: A bare metal example of Inter Processor Communication (IPC) on nrf5340</title><link>https://devzone.nordicsemi.com/thread/551233?ContentTypeID=1</link><pubDate>Mon, 13 Oct 2025 08:45:13 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b5927934-d80f-4472-a459-2e78d81347bc</guid><dc:creator>Turbo J</dc:creator><description>&lt;p&gt;I don&amp;#39;t see the required IRQ_CONNECT() macro in your code. Zephyr interrupt handlers are not called by name. Your program thus tries to to fire an unhandled interrupt which should trigger a corresponding fault.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>