PublishQueueAsyncRK - size limitation on addressable Retained RAM

Two questions on this library if anyone could help:

  1. Does the header size field mean that addressing is limited to 64k (unsigned int16) ? The rest of the library uses pointers (32bits) to the memory space.
typedef struct { // 8 bytes
	uint32_t	magic;			//!< PUBLISH_QUEUE_HEADER_MAGIC
	uint16_t	size;			//!< retainedBufferSize, in case it changed, or for file systems, this is the number of events that have been sent already
	uint16_t	numEvents;		//!< number of events, see the PublishQueueEventData structure
} PublishQueueHeader;
  1. Would it be possible to make a public interface that would return the remaining/unused space in the queue buffer, much like getNumEvents() method?

Retained memory is limited to under 4K bytes. There’s no reason to use a larger value for PublishQueueHeader::size as it would never be larger than 2 bytes. This structure is only for retained memory; it’s not used for FRAM or file systems. And since the structure is stored in retained memory, keeping it as small as possible makes sense.

The number of available events you could store is unknown, since they vary in size. The number of bytes available could be returned, but not for POSIX file systems. I’m not convinced how useful it would be, for the amount of work it would be, but it’s possible for retained memory and FRAM.

Hi Rick, thanks for the reply. Maybe I just don’t understand how this library is constructed -

In PublishQueueAsyncRK.h within the conditional compile for #if defined(__MB85RC256V_FRAM_RK) || defined(DOXYGEN_BUILD) after the constructors in the setup() class there is this use of header.size

if (header.magic == PUBLISH_QUEUE_HEADER_MAGIC && header.size == len) {
Where len is size_t type and could be >64k whereas header.size is uint16_t?
For a FRAM of len 131072 say this would be false.

||/**|
|---|---|
|| * @brief The header, copied from FRAM|
|| */|
PublishQueueHeader header;

Where the typedef struct PublishQueueHeader is defined as:

typedef struct { // 8 bytes
	uint32_t	magic;			//!< PUBLISH_QUEUE_HEADER_MAGIC
	uint16_t	size;			//!< retainedBufferSize, in case it changed, or for file systems, this is the number of events that have been sent already
	uint16_t	numEvents;		//!< number of events, see the PublishQueueEventData structure
} PublishQueueHeader;

For the second part - I am trying to implement a mechanism that stores an event just before the queue is full to later recover and explain why events have been dumped thereafter. To do this I figure I need to know the freespace before queuing an event. Unless you can think of a better way?

I am thinking that free space could be calculated as;

size_t freespace = len;
nextFree = start + sizeof(PublishQueueHeader);
for(uint16_t ii = 0; ii < header.numEvents; ii++) {
    nextFree = skipEvent(nextFree, eventBuf);}
freespace -=nextFree;
return freespace;

Does this need a StMutexLock before it like getNumEvents(); ?

Hmm, yes that structure is used for FRAM, but not for file systems. I guess it would be easiest to make it a uint32_t, however an extra empty uint16_t reserved needs to be added after numEvents to keep the structure 4-byte aligned.

I don’t think you need to call skipEvent to get the free space for retained or FRAM. You should just be able to use len - (nextFree - start). But it does need to be in a mutex lock.

Thanks again - for both replies. I have learnt a lot from looking at the code in this library - Future bool, virtual keyword.