From 51abe02956c085b161761a50eb5b7306a2400cc6 Mon Sep 17 00:00:00 2001 From: Felipe Neves Date: Mon, 28 Oct 2024 00:37:58 -0300 Subject: [PATCH] zipm: fix the transmit/receive fragmentation and update the sample to use data larger than the block available to illustrate the fragmentation option Signed-off-by: Felipe Neves --- include/zipm/zipm.h | 4 ++-- include/zipm/zipm_device_interface.h | 2 +- samples/ping-pong/README.rst | 20 +++++++++++++++++ samples/ping-pong/rx/src/main.c | 8 ++++--- samples/ping-pong/tx/src/main.c | 14 ++++++++++-- src/zipm.c | 28 ++++++++++++------------ src/zipm_node.h | 2 +- src/zipm_node_pool.c | 2 +- src/zipm_node_pool.h | 6 ++++-- src/zipm_shared_queue.c | 32 +--------------------------- src/zipm_shared_queue.h | 8 +++---- 11 files changed, 65 insertions(+), 61 deletions(-) diff --git a/include/zipm/zipm.h b/include/zipm/zipm.h index 5e59779..d8b6247 100644 --- a/include/zipm/zipm.h +++ b/include/zipm/zipm.h @@ -121,7 +121,7 @@ static inline int zipm_send(const struct device *zdev, const void *data, size_t * * @param zdev pointer to the ZIPM device * @param data pointer where to store the data - * @param size size in bytes of the storage + * @param size pointer to store the size of received block * @param shared_queue_number desired shared queue to extract data * * @return 0 if extracted all the data, positive value if there is @@ -136,7 +136,7 @@ static inline int zipm_send(const struct device *zdev, const void *data, size_t * was fragmented, so user needs to call this function multiple times * until it returns 0 or -ENOMEM to reassembly the fragmented data. */ -static inline int zipm_receive(const struct device *zdev, void *data, size_t size, +static inline int zipm_receive(const struct device *zdev, void *data, size_t *size, int shared_queue_number) { const struct zipm_device_api *api = diff --git a/include/zipm/zipm_device_interface.h b/include/zipm/zipm_device_interface.h index 61d5955..eeec1ae 100644 --- a/include/zipm/zipm_device_interface.h +++ b/include/zipm/zipm_device_interface.h @@ -16,7 +16,7 @@ typedef int (*zipm_register_event_callback_t)(const struct device *zdev, struct typedef int (*zipm_remove_event_callback_t)(struct zipm_callback *cs); typedef int (*zipm_send_t)(const struct device *zdev, const void *data, size_t size, int shared_queue_number, int wait_time); -typedef int (*zipm_receive_t)(const struct device *zdev, void *data, size_t size, +typedef int (*zipm_receive_t)(const struct device *zdev, void *data, size_t *size, int shared_queue_number); typedef int (*zipm_flush_t)(const struct device *zdev, int shared_queue_number); diff --git a/samples/ping-pong/README.rst b/samples/ping-pong/README.rst index 1fc5ba0..106a44f 100644 --- a/samples/ping-pong/README.rst +++ b/samples/ping-pong/README.rst @@ -52,6 +52,26 @@ you should see something similar on the console: 9012: Other core said: Hello from other side! 9512: Other core said: Hello from other side! +Also you can connect the console of the secondary core to see the +message from primary core arriving to it: + +.. code-block:: console + + Primary core asked: Say something secondary core! , so let's say something + Primary core asked: Say something secondary core! , so let's say something + Primary core asked: Say something secondary core! , so let's say something + Primary core asked: Say something secondary core! , so let's say something + Primary core asked: Say something secondary core! , so let's say something + Primary core asked: Say something secondary core! , so let's say something + Primary core asked: Say something secondary core! , so let's say something + Primary core asked: Say something secondary core! , so let's say something + Primary core asked: Say something secondary core! , so let's say something + Primary core asked: Say something secondary core! , so let's say something + Primary core asked: Say something secondary core! , so let's say something + Primary core asked: Say something secondary core! , so let's say something + Primary core asked: Say something secondary core! , so let's say something + Primary core asked: Say something secondary core! , so let's say something + You should see also the LED0 (if present) on your board blinking every time an event arrives to one of the CPUs. diff --git a/samples/ping-pong/rx/src/main.c b/samples/ping-pong/rx/src/main.c index 0005910..e7be4f4 100644 --- a/samples/ping-pong/rx/src/main.c +++ b/samples/ping-pong/rx/src/main.c @@ -14,8 +14,8 @@ static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios); static const struct device *handle = DEVICE_DT_GET(DT_NODELABEL(zipm_device0)); static struct zipm_callback callback; -static const char msg[] = {"Hello from other side!\0"}; - +static const char msg[] = {"Hello from other side! Aka secondary core! \0"}; +static char rx_msg[64] = {0}; const int doorbell_queue = 0; const int tx_queue = 1; @@ -23,8 +23,10 @@ static void zipm_event_callback(const struct device *dev, int sq, void *user_dat { if(sq == doorbell_queue) { gpio_pin_toggle_dt(&led); - zipm_receive(dev, NULL, 0, doorbell_queue); + zipm_receive(dev, &rx_msg, NULL, doorbell_queue); zipm_send(dev, &msg, sizeof(msg), tx_queue, 0); + + printk("Primary core asked: %s, so let's say something \n", (const char *)rx_msg); } } diff --git a/samples/ping-pong/tx/src/main.c b/samples/ping-pong/tx/src/main.c index 7b4cd39..326200c 100644 --- a/samples/ping-pong/tx/src/main.c +++ b/samples/ping-pong/tx/src/main.c @@ -15,15 +15,25 @@ static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios); static const struct device *handle = DEVICE_DT_GET(DT_NODELABEL(zipm_device0)); static struct zipm_callback callback; static char rx_msg[64] = {0}; +static char tx_msg[] = {"Say something secondary core! \0"}; static int rx_queue = 1; static int doorbell_queue = 0; static void zipm_event_callback(const struct device *dev, int sq, void *user_data) { + int copied = 0; + size_t block_size; + int ret; + if(sq == rx_queue) { gpio_pin_toggle_dt(&led); - zipm_receive(handle, &rx_msg, sizeof(rx_msg), rx_queue); + do { + ret = zipm_receive(handle, &rx_msg[copied], &block_size, rx_queue); + if(ret > 0) { + copied += block_size; + } + }while(ret != 0); printk("%lld: Other core said: %s \n", k_uptime_get(), (const char *)rx_msg); } } @@ -40,7 +50,7 @@ int main(void) while(1) { k_msleep(500); - zipm_send(handle, NULL, 0, doorbell_queue, 0); + zipm_send(handle, &tx_msg, sizeof(tx_msg), doorbell_queue, 0); } return 0; diff --git a/src/zipm.c b/src/zipm.c index bf56c26..5848653 100644 --- a/src/zipm.c +++ b/src/zipm.c @@ -7,6 +7,7 @@ #define DT_DRV_COMPAT zipm_message_device #include +#include #include #include "zipm_node_pool.h" #include "zipm_shared_queue.h" @@ -127,7 +128,7 @@ static int zipm_dev_send(const struct device *zdev, const void *data, size_t siz } do { - + uintptr_t from = (uintptr_t)data; mem = zipm_node_pool_alloc(dev_data->node_pool); if(!mem) { ret = k_sem_take(&dev_data->shared_queue_sem, K_MSEC(wait_time)); @@ -139,18 +140,18 @@ static int zipm_dev_send(const struct device *zdev, const void *data, size_t siz continue; } - LOG_DBG("Block allocated! remaining to transfer: %d", remaining); + LOG_DBG("Block allocated! remaining to transfer: %d\n", remaining); desc.addr = (uint32_t)mem; desc.size = dev_cfg->node_pool_block_size; if(remaining > desc.size) { - memcpy((void *)mem, &data+copied, remaining); - copied += remaining; + memcpy((void *)mem, (const void *)(from+copied), desc.size); + copied += desc.size; desc.flags = ZIPM_NODE_FLAGS_NEXT; remaining -= desc.size; } else { - memcpy((void *)mem, &data+copied, desc.size); - copied += desc.size; + memcpy((void *)mem, (const void *)(from+copied), remaining); + copied += remaining; desc.flags = ZIPM_NODE_FLAGS_END; remaining = 0; } @@ -165,7 +166,7 @@ static int zipm_dev_send(const struct device *zdev, const void *data, size_t siz return ipm_send(dev_cfg->ipc_device, 0, 0, NULL, 0); } -static int zipm_dev_receive(const struct device *zdev, void *data, size_t size, +static int zipm_dev_receive(const struct device *zdev, void *data, size_t *size, int shared_queue_number) { int fragmented; @@ -177,11 +178,6 @@ static int zipm_dev_receive(const struct device *zdev, void *data, size_t size, if(shared_queue_number >= dev_data->noof_queues) return -EINVAL; - if(size < dev_cfg->node_pool_block_size && data) { - LOG_ERR("Not enough space provided to extract block of data"); - return -EINVAL; - } - sq = zipm_shared_queue_access((void *)dev_cfg->queues_location[shared_queue_number]); if(!sq) { LOG_ERR("Invalid shared queue!"); @@ -194,7 +190,7 @@ static int zipm_dev_receive(const struct device *zdev, void *data, size_t size, return -ENOMEM; } - if(!(desc.flags & ZIPM_NODE_FLAGS_EMPTY) && data && size) { + if(!(desc.flags & ZIPM_NODE_FLAGS_EMPTY) && data) { memcpy(data, (const void *)desc.addr, desc.size); } @@ -203,6 +199,10 @@ static int zipm_dev_receive(const struct device *zdev, void *data, size_t size, zipm_node_pool_dealloc(dev_data->node_pool, (uint8_t *)desc.addr); k_sem_give(&dev_data->shared_queue_sem); + if(size != NULL) { + *size = desc.size; + } + return fragmented; } @@ -300,7 +300,7 @@ static int zipm_dev_init(const struct device *zdev) } } - dev_data->node_pool = zipm_node_pool_get((void *)dev_cfg->node_pool_location); + dev_data->node_pool = zipm_node_pool_access((void *)dev_cfg->node_pool_location); if(dev_data->node_pool == NULL) { LOG_ERR("Invalid node pool! aborting!"); return -ENOENT; diff --git a/src/zipm_node.h b/src/zipm_node.h index 4d79dcd..580a3c6 100644 --- a/src/zipm_node.h +++ b/src/zipm_node.h @@ -15,7 +15,7 @@ #define ZIPM_NODE_FLAGS_NEXT (1 << 1) #define ZIPM_NODE_FLAGS_EMPTY (1 << 2) -struct zipm_node_descriptor { +__packed struct zipm_node_descriptor { uint32_t addr; uint32_t size; uint32_t flags; diff --git a/src/zipm_node_pool.c b/src/zipm_node_pool.c index 271311a..2a02b69 100644 --- a/src/zipm_node_pool.c +++ b/src/zipm_node_pool.c @@ -73,7 +73,7 @@ int zipm_node_pool_initialize(uint32_t block_size, return 0; } -struct zipm_node_pool_header *zipm_node_pool_get(volatile void *shared_memory_address) +struct zipm_node_pool_header *zipm_node_pool_access(volatile void *shared_memory_address) { struct zipm_node_pool_header *h = (struct zipm_node_pool_header *)shared_memory_address; diff --git a/src/zipm_node_pool.h b/src/zipm_node_pool.h index 3c779a7..d455608 100644 --- a/src/zipm_node_pool.h +++ b/src/zipm_node_pool.h @@ -12,7 +12,7 @@ #include #include "zipm_node.h" -struct zipm_node_pool_header { +__packed struct zipm_node_pool_header { uint32_t magic_1; unsigned long control; uint32_t blocks_avail; @@ -23,8 +23,10 @@ struct zipm_node_pool_header { int zipm_node_pool_initialize(uint32_t block_size, uint32_t blocks_avail, volatile void *shared_memory_address); -struct zipm_node_pool_header *zipm_node_pool_get(volatile void *shared_memory_address); +struct zipm_node_pool_header *zipm_node_pool_access(volatile void *shared_memory_address); + bool zipm_node_pool_is_valid(volatile const struct zipm_node_pool_header *h); + uint8_t *zipm_node_pool_alloc(volatile struct zipm_node_pool_header *h); int zipm_node_pool_dealloc(volatile struct zipm_node_pool_header *h, uint8_t *desc); diff --git a/src/zipm_shared_queue.c b/src/zipm_shared_queue.c index d6a2df9..eb12281 100644 --- a/src/zipm_shared_queue.c +++ b/src/zipm_shared_queue.c @@ -20,10 +20,9 @@ int zipm_shared_queue_initialize(volatile void *shared_memory_address, int size) if(!size) return - EINVAL; - sq = (struct zipm_shared_queue *)shared_memory_address; int key = irq_lock(); - sq->event = 0; + sq = (struct zipm_shared_queue *)shared_memory_address; sq->write_idx = 0; sq->read_idx = 0; sq->avail = 0; @@ -32,9 +31,6 @@ int zipm_shared_queue_initialize(volatile void *shared_memory_address, int size) sq->magic_2 = ZIPM_SHARED_Q_MAGIC_2; sq->descs = (struct zipm_node_descriptor *)((uint32_t)shared_memory_address + sizeof(struct zipm_shared_queue)); - - memset(sq->descs, 0x00, sizeof(struct zipm_shared_queue) * size); - irq_unlock(key); return 0; @@ -149,32 +145,6 @@ int zipm_shared_queue_push(volatile struct zipm_shared_queue *sq, const struct z return 0; } -int zipm_shared_queue_set_event(volatile struct zipm_shared_queue *sq, uint32_t event) -{ - if(!sq) - return -EINVAL; - - int key = irq_lock(); - atomic_set((atomic_t *)&sq->event, event); - irq_unlock(key); - - return 0; -} - -int zipm_shared_queue_get_event(volatile struct zipm_shared_queue *sq) -{ - uint32_t ev; - - if(!sq) - return -EINVAL; - - int key = irq_lock(); - ev = sq->event; - irq_unlock(key); - - return ev; -} - bool zipm_shared_queue_has_data(volatile struct zipm_shared_queue *sq) { int avail; diff --git a/src/zipm_shared_queue.h b/src/zipm_shared_queue.h index 53f172f..923a2a9 100644 --- a/src/zipm_shared_queue.h +++ b/src/zipm_shared_queue.h @@ -12,24 +12,24 @@ #include #include "zipm_node.h" -struct zipm_shared_queue { +__packed struct zipm_shared_queue { uint32_t magic_1; uint32_t write_idx; uint32_t read_idx; uint32_t avail; uint32_t end; - uint32_t event; uint32_t magic_2; struct zipm_node_descriptor *descs; }; int zipm_shared_queue_initialize(volatile void *shared_memory_address, int size); struct zipm_shared_queue *zipm_shared_queue_access(volatile void *shared_memory_address); + bool zipm_is_shared_queue_valid(volatile const struct zipm_shared_queue *sq); + int zipm_shared_queue_get(volatile struct zipm_shared_queue *sq, struct zipm_node_descriptor *desc); int zipm_shared_queue_push(volatile struct zipm_shared_queue *sq, const struct zipm_node_descriptor *desc); -int zipm_shared_queue_set_event(volatile struct zipm_shared_queue *sq, uint32_t event); -int zipm_shared_queue_get_event(volatile struct zipm_shared_queue *sq); + bool zipm_shared_queue_has_data(volatile struct zipm_shared_queue *sq); #endif \ No newline at end of file