This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

RTOS-2 API call osMessageQueueGet() corrupts thread stack

Hi,

I'm using Keil RTX5 (5.5.2) over RTOS-2 API. I'm trying to send a simple struct of data (8 bytes) from one thread to another:

typedef struct LogType
{
    uint32_t id;
    uint32_t timestamp;
} LogType_t;

Sending data (passing a pointer to queue) from Thread A:

LogType_t* entry = NULL;

entry = (LogType_t*)osMemoryPoolAlloc(logPool, osWaitForever);
assert(entry);
entry->id           = 0xDEADBEEF;
entry->timestamp    = 0xDEADBEEF;

osMessageQueuePut(logQueue, &entry, NULL, osWaitForever);

Receiving data from Thread B:

osStatus_t readLogEntry(const LogType_t* extEntry)
{
    extEntry = NULL;

    static LogType_t localEntry;
    memset((void*)&localEntry, 0x0, sizeof(LogType_t));
    LogType_t* tempEntry = NULL;

    PRINTF("\r\n\nBEFORE");
    PRINTF("\r\n%16s: %8X", "localEntry addr", &localEntry);

    PRINTF("\r\n%16s: %8X", "*tempEntry addr", &tempEntry);
    PRINTF("\r\n%16s: %8X", "tempEntry addr", tempEntry);

    PRINTF("\r\n%16s: %8X", "*extEntry addr", &extEntry);
    PRINTF("\r\n%16s: %8X", "extEntry addr", extEntry);

    /* Wait for log entry data from other threads */
    osStatus_t status = osMessageQueueGet(logQueue, (void*)&tempEntry, NULL, osWaitForever);

    if (status == osOK)
    {
        PRINTF("\r\n\nAFTER");
        PRINTF("\r\n%16s: %8X", "localEntry addr", &localEntry);

        PRINTF("\r\n%16s: %8X", "*tempEntry addr", &tempEntry);
        PRINTF("\r\n%16s: %8X", "tempEntry addr", tempEntry);

        PRINTF("\r\n%16s: %8X", "*extEntry addr", &extEntry);
        PRINTF("\r\n%16s: %8X", "extEntry addr", extEntry);

        PRINTF("\r\n\n%16s: %8X", "ID", tempEntry->id);
        PRINTF("\r\n%16s: %8X", "Timestamp", tempEntry->timestamp);

        osMemoryPoolFree(logPool, tempEntry);
    }

    return status;
}

What I'm getting out of this simplified function is:

BEFORE
 localEntry addr: 20009E18    // ok
 *tempEntry addr: 20000DB8    // ok
  tempEntry addr:        0    // ok at this point
  *extEntry addr: 20000DBC    // ok
   extEntry addr:        0    // ok at this point

AFTER
 localEntry addr: 20009E18    // still ok
 *tempEntry addr: 20000DB8    // still ok
  tempEntry addr: 20002B58    // ok, pointing to my struct in pool
  *extEntry addr: 20000DBC    // still ok
   extEntry addr:      7FF    // NOT OK

              ID: DEADBEEF    // ok
       Timestamp: DEADBEEF    // ok

It seems the local copy of the extEntry pointer is getting overwritten during the call for reason I don't understand. Is this a bug in RTX or the RTOS-2 API or have I done some obvious mistake? I have no similar issues if the size of the struct is max. 4 bytes.

Here are the pool and queue initializations:

osMemoryPoolId_t logPool;
osMessageQueueId_t logQueue;

const osMemoryPoolAttr_t logMemorypoolAttr =
{
    .name = "log_pool",
};

logPool  = osMemoryPoolNew(16, sizeof(LogType_t), &logMemorypoolAttr);
logQueue = osMessageQueueNew(16, sizeof(LogType_t), NULL);

Environment details:

  • IDE: ARM/Keil µVision5 (V5.34.0.0)
  • Compiler: ARM Compiler V6.16
  • Target: LPC55S28