Skip to content

Commit

Permalink
zipm: fix the transmit/receive fragmentation
Browse files Browse the repository at this point in the history
and update the sample to use data larger than the
block available to illustrate the fragmentation
option

Signed-off-by: Felipe Neves <[email protected]>
  • Loading branch information
uLipe committed Oct 28, 2024
1 parent e65f0a0 commit 98240c3
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 60 deletions.
4 changes: 2 additions & 2 deletions include/zipm/zipm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 =
Expand Down
2 changes: 1 addition & 1 deletion include/zipm/zipm_device_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
8 changes: 5 additions & 3 deletions samples/ping-pong/rx/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,19 @@
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;

static void zipm_event_callback(const struct device *dev, int sq, void *user_data)
{
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);
}
}

Expand Down
14 changes: 12 additions & 2 deletions samples/ping-pong/tx/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand All @@ -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;
Expand Down
28 changes: 14 additions & 14 deletions src/zipm.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define DT_DRV_COMPAT zipm_message_device

#include <errno.h>
#include <zephyr/cache.h>
#include <zipm/zipm.h>
#include "zipm_node_pool.h"
#include "zipm_shared_queue.h"
Expand Down Expand Up @@ -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));
Expand All @@ -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;
}
Expand All @@ -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;
Expand All @@ -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!");
Expand All @@ -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);
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/zipm_node_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
6 changes: 4 additions & 2 deletions src/zipm_node_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <zephyr/kernel.h>
#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;
Expand All @@ -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);

Expand Down
32 changes: 1 addition & 31 deletions src/zipm_shared_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions src/zipm_shared_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@
#include <zephyr/kernel.h>
#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

0 comments on commit 98240c3

Please sign in to comment.