diff --git a/hw/drivers/ipc_nrf5340/include/ipc_nrf5340/ipc_nrf5340.h b/hw/drivers/ipc_nrf5340/include/ipc_nrf5340/ipc_nrf5340.h index c68b3e7c04..214633fe57 100644 --- a/hw/drivers/ipc_nrf5340/include/ipc_nrf5340/ipc_nrf5340.h +++ b/hw/drivers/ipc_nrf5340/include/ipc_nrf5340/ipc_nrf5340.h @@ -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 diff --git a/hw/drivers/ipc_nrf5340/pkg.yml b/hw/drivers/ipc_nrf5340/pkg.yml index 4ad4b9c139..ae875fa24b 100644 --- a/hw/drivers/ipc_nrf5340/pkg.yml +++ b/hw/drivers/ipc_nrf5340/pkg.yml @@ -32,3 +32,6 @@ pkg.deps: pkg.init: ipc_nrf5340_init: 'MYNEWT_VAL(IPC_NRF5340_SYSINIT_STAGE)' ipc_nrf5340_netcore_init: 'MYNEWT_VAL(IPC_NRF5340_NETCORE_SYSINIT_STAGE)' + +pkg.link_tables: + - shm_descriptor diff --git a/hw/drivers/ipc_nrf5340/src/ipc_nrf5340.c b/hw/drivers/ipc_nrf5340/src/ipc_nrf5340.c index 6d586799d2..8fb161fe16 100644 --- a/hw/drivers/ipc_nrf5340/src/ipc_nrf5340.c +++ b/hw/drivers/ipc_nrf5340/src/ipc_nrf5340.c @@ -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 @@ -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]; @@ -289,6 +294,8 @@ ipc_nrf5340_init(void) } } #endif + ipc_shared[0].region_descriptor_start = __shm_descriptor_start__; + ipc_shared[0].region_descriptor_end = __shm_descriptor_end__; for (i = 0; i < IPC_MAX_CHANS; ++i) { shms[i].buf = shms_bufs[i]; @@ -381,6 +388,18 @@ ipc_nrf5340_netcore_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)