Skip to content

Commit

Permalink
hw/ipc_nrf5340: Support for flexible memory sharing
Browse files Browse the repository at this point in the history
This adds easy way to add application specific shared
memory regions that will be defined on application
core and can be easily found on network core.
This is done so linker scripts for network and application
core does not have to be carefully synchronized.

Signed-off-by: Jerzy Kasenberg <jerzy.kasenberg@codecoup.pl>
  • Loading branch information
kasjer committed May 23, 2023
1 parent c65fe7c commit c9b5575
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 0 deletions.
68 changes: 68 additions & 0 deletions hw/drivers/ipc_nrf5340/include/ipc_nrf5340/ipc_nrf5340.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,74 @@ const void *ipc_nrf5340_net_image_get(uint32_t *size);
volatile struct hci_ipc_shm *ipc_nrf5340_hci_shm_get(void);
#endif

struct shm_memory_region {
uint32_t region_id;
void *region_start;
uint32_t region_size;
};

#if MYNEWT_VAL(MCU_APP_CORE)

#define __REGION_ID(id) shm_region_##id
/**
* Macro for shared memory region declaration
*
* It should be used on application core to specify memory region that should be accessible
* on the network core.
* example declaration form application core:
* \code
* struct application_shared_data {
* int anything;
* uint8_t buffer[1234]
* } shared_data;
*
* #define MY_REGION_ID 112233
* SHM_REGION(MY_REGION_ID, &shared_data, sizeof(shared_data));
* \endcode
*
* @param id number that will be used on netcore to locate this region by
* @param address start of shared memory region
* @param size size of shared memory region
*/
#define SHM_REGION(id, address, size) \
static struct shm_memory_region __attribute__((section(".shm.descriptor"), used)) __REGION_ID(id) = { \
.region_id = id, \
.region_start = address, \
.region_size = size, \
}

#else
/**
* Find shared memory region by it's ID.
*
* Region should be declared on application core with SHM_REGION macro.
* example declaration form application core:
* \code
* struct application_shared_data {
* int anything;
* uint8_t buffer[1234]
* } shared_data;
*
* SHM_REGION(112233, &shared_data, sizeof(shared_data));
* \endcode
* access on netcode:
* \code
* ...
* const struct shm_memory_region *shared_region;
* region = ipc_nrf5340_find_region(122233);
* if (region) {
* struct application_shared_data *shared_data = region->region_start;
* shared_data->anything = 1;
* ...
* }
* \endcode
* @param region_id Region ID to find.
*
* @return Pointer to region, NULL if not present
*/
const struct shm_memory_region *ipc_nrf5340_find_region(uint32_t region_id);
#endif

#ifdef __cplusplus
}
#endif
Expand Down
19 changes: 19 additions & 0 deletions hw/drivers/ipc_nrf5340/src/ipc_nrf5340.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ struct ipc_shared {
APP_AND_NET_RUNNING,
NET_RESTARTED,
} ipc_state;
struct shm_memory_region *region_descriptor_start;
struct shm_memory_region *region_descriptor_end;
#if MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_common_hci_ipc
volatile struct hci_ipc_shm hci_shm;
#endif
Expand Down Expand Up @@ -96,6 +98,9 @@ static struct ipc_channel ipcs[IPC_MAX_CHANS];
__attribute__((section(".ipc"))) static struct ipc_shared ipc_shared[1];

#if MYNEWT_VAL(MCU_APP_CORE)
extern struct shm_memory_region __shm_descriptor_start__[];
extern struct shm_memory_region __shm_descriptor_end__[];

static struct ipc_shm shms[IPC_MAX_CHANS];
static uint8_t shms_bufs[IPC_MAX_CHANS][IPC_BUF_SIZE];

Expand Down Expand Up @@ -285,6 +290,8 @@ ipc_nrf5340_init(void)
}
}
#endif
ipc_shared[0].region_descriptor_start = __shm_descriptor_start__;
ipc_shared[0].region_descriptor_end = __shm_descriptor_end__;

/* Make sure network core if off when we set up IPC */
NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Hold;
Expand Down Expand Up @@ -366,6 +373,18 @@ ipc_nrf5340_init(void)
ipc_shared->ipc_state = APP_AND_NET_RUNNING;
}
}

const struct shm_memory_region *
ipc_nrf5340_find_region(uint32_t region_id)
{
const struct shm_memory_region *region;
for (region = ipc_shared->region_descriptor_start; region != ipc_shared->region_descriptor_end; ++region) {
if (region->region_id == region_id) {
return region;
}
}
return NULL;
}
#endif

#if MYNEWT_VAL(MCU_APP_CORE)
Expand Down
5 changes: 5 additions & 0 deletions hw/mcu/nordic/nrf5340/nrf5340.ld
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ SECTIONS
*(SORT(.dtors.*))
*(.dtors)

. = ALIGN(4);
__shm_descriptor_start__ = .;
KEEP(*(.shm.descriptor))
__shm_descriptor_end__ = .;

*(.rodata*)

*(.eh_frame*)
Expand Down

0 comments on commit c9b5575

Please sign in to comment.