Skip to content

Commit

Permalink
[Silabs] Continue Migration to CMSIS OS2 api (project-chip#32901)
Browse files Browse the repository at this point in the history
* Migrate pw rpc support to cmsis os api

* Migration efr32 uart.cpp to cmsis os
  • Loading branch information
jmartinez-silabs committed Apr 25, 2024
1 parent 349fb27 commit 7b2118d
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 81 deletions.
11 changes: 5 additions & 6 deletions examples/common/pigweed/efr32/PigweedLoggerMutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@

#include "PigweedLogger.h"
#include "pigweed/RpcService.h"
#include "semphr.h"
#include <FreeRTOS.h>
#include <cmsis_os2.h>

namespace chip {
namespace rpc {
Expand All @@ -32,18 +31,18 @@ class PigweedLoggerMutex : public ::chip::rpc::Mutex
PigweedLoggerMutex() {}
void Lock() override
{
SemaphoreHandle_t * sem = PigweedLogger::GetSemaphore();
osMutexId_t * sem = PigweedLogger::GetMutex();
if (sem)
{
xSemaphoreTake(*sem, portMAX_DELAY);
osMutexAcquire(*sem, osWaitForever);
}
}
void Unlock() override
{
SemaphoreHandle_t * sem = PigweedLogger::GetSemaphore();
osMutexId_t * sem = PigweedLogger::GetMutex();
if (sem)
{
xSemaphoreGive(*sem);
osMutexRelease(*sem);
}
}
};
Expand Down
21 changes: 9 additions & 12 deletions examples/platform/silabs/PigweedLogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,13 @@
* needs to use HDLC/UART for another purpose like the RPC server.
*/

#include <FreeRTOS.h>

#include "semphr.h"
#include <pw_hdlc/encoder.h>
#include <pw_stream/sys_io_stream.h>
#include <pw_sys_io_efr32/init.h>

#include "PigweedLogger.h"
#include "pw_span/span.h"
#include <cassert>
#include <cstdint>
#include <pw_hdlc/encoder.h>
#include <pw_stream/sys_io_stream.h>
#include <pw_sys_io_efr32/init.h>
#include <string_view>

namespace PigweedLogger {
Expand All @@ -44,7 +41,7 @@ constexpr size_t kWriteBufferSize = 128; // Buffer for constructing HDLC frames

// Exclusive access to the backend is needed to make sure that log messages coming
// from different threads are not interwoven.
SemaphoreHandle_t sLoggerLock;
osMutexId_t sLoggerLock;

static pw::stream::SysIoWriter sWriter;
static size_t sWriteBufferPos;
Expand All @@ -60,15 +57,15 @@ static void send(void)

void init(void)
{
sLoggerLock = xSemaphoreCreateMutex();
sLoggerLock = osMutexNew(nullptr);
assert(sLoggerLock != NULL);

pw_sys_io_Init();
}

int putString(const char * buffer, size_t size)
{
xSemaphoreTake(sLoggerLock, portMAX_DELAY);
osMutexAcquire(sLoggerLock, osWaitForever);
assert(sWriteBufferPos < kWriteBufferSize);

for (size_t i = 0; i < size; ++i)
Expand All @@ -90,11 +87,11 @@ int putString(const char * buffer, size_t size)
send();
}

xSemaphoreGive(sLoggerLock);
osMutexRelease(sLoggerLock);
return size;
}

SemaphoreHandle_t * GetSemaphore()
osMutexId_t * GetMutex()
{
return &sLoggerLock;
}
Expand Down
6 changes: 2 additions & 4 deletions examples/platform/silabs/PigweedLogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@

#pragma once

#include <FreeRTOS.h>

#include "semphr.h"
#include <cmsis_os2.h>
#include <cstdint>

namespace PigweedLogger {

void init(void);
int putString(const char * buffer, size_t size);
SemaphoreHandle_t * GetSemaphore();
osMutexId_t * GetMutex();

} // namespace PigweedLogger
38 changes: 23 additions & 15 deletions examples/platform/silabs/Rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
*/

#include "AppTask.h"
#include "FreeRTOS.h"
#include "PigweedLoggerMutex.h"
#include "pigweed/RpcService.h"
#include "pw_sys_io_efr32/init.h"
#include "task.h"
#include <cmsis_os2.h>
#include <sl_cmsis_os2_common.h>

#if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE
#include "pigweed/rpc_services/Attributes.h"
Expand Down Expand Up @@ -94,7 +94,7 @@ class Efr32Device final : public Device
public:
pw::Status Reboot(const chip_rpc_RebootRequest & request, pw_protobuf_Empty & response) override
{
TickType_t delayMs = kRebootTimerPeriodMs;
uint32_t delayMs = kRebootTimerPeriodMs;
if (request.delay_ms != 0)
{
delayMs = request.delay_ms;
Expand All @@ -104,27 +104,36 @@ class Efr32Device final : public Device
ChipLogProgress(NotSpecified, "Did not receive a reboot delay. Defaulting to %d ms",
static_cast<int>(kRebootTimerPeriodMs));
}
mRebootTimer = xTimerCreateStatic("Reboot", pdMS_TO_TICKS(delayMs), false, nullptr, RebootHandler, &mRebootTimerBuffer);
xTimerStart(mRebootTimer, 0);

mRebootTimer = osTimerNew(RebootHandler, osTimerOnce, nullptr, &mRebootTimerAttr);
uint32_t delayTicks = ((uint64_t) osKernelGetTickFreq() * delayMs) / 1000;
osTimerStart(mRebootTimer, delayTicks);
return pw::OkStatus();
}

private:
static constexpr uint32_t kRebootTimerPeriodMs = 1000;
TimerHandle_t mRebootTimer;
StaticTimer_t mRebootTimerBuffer;
osTimerId_t mRebootTimer;
osTimer_t mRebootTimerBuffer;
osTimerAttr_t mRebootTimerAttr = { .name = "Reboot", .cb_mem = &mRebootTimerBuffer, .cb_size = osTimerCbSize };

static void RebootHandler(TimerHandle_t) { NVIC_SystemReset(); }
static void RebootHandler(void * timerCbArg) { NVIC_SystemReset(); }
};
#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE

namespace {

#define RPC_TASK_STACK_SIZE 4096
#define RPC_TASK_PRIORITY 1
static TaskHandle_t sRpcTaskHandle;
StaticTask_t sRpcTaskBuffer;
StackType_t sRpcTaskStack[RPC_TASK_STACK_SIZE];
static osThreadId_t sRpcTaskHandle;
osThread_t sRpcTaskControlBlock;
constexpr uint32_t kRpcTaskSize = 4096;
uint8_t sRpcTaskStack[kRpcTaskSize];
constexpr osThreadAttr_t kRpcTaskAttr = { .name = "RPC",
.attr_bits = osThreadDetached,
.cb_mem = &sRpcTaskControlBlock,
.cb_size = osThreadCbSize,
.stack_mem = sRpcTaskStack,
.stack_size = kRpcTaskSize,
.priority = osPriorityLow };

#if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE
Attributes attributes_service;
Expand Down Expand Up @@ -214,8 +223,7 @@ void Init()
pw_sys_io_Init();

// Start App task.
sRpcTaskHandle = xTaskCreateStatic(RunRpcService, "RPC_TASK", ArraySize(sRpcTaskStack), nullptr, RPC_TASK_PRIORITY,
sRpcTaskStack, &sRpcTaskBuffer);
sRpcTaskHandle = osThreadNew(RunRpcService, nullptr, &kRpcTaskAttr);
}

} // namespace rpc
Expand Down
78 changes: 34 additions & 44 deletions examples/platform/silabs/efr32/uart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@
* limitations under the License.
*/
#include "AppConfig.h"
#include "FreeRTOS.h"
#include "event_groups.h"
#include "matter_shell.h"
#include "semphr.h"
#include "task.h"
#include <cmsis_os2.h>
#include <sl_cmsis_os2_common.h>

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -108,28 +106,39 @@ static uint16_t lastCount; // Nb of bytes already processed from the active dmaB
#else
#define UART_MAX_QUEUE_SIZE 25
#endif
#define UART_TASK_SIZE 256
#define UART_TASK_NAME "UART"

#ifdef CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE
#define UART_TX_MAX_BUF_LEN (CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE + 2) // \r\n
#else
#define UART_TX_MAX_BUF_LEN (258)
#endif

static TaskHandle_t sUartTaskHandle;
static StackType_t uartStack[UART_TASK_SIZE * sizeof(StackType_t)];
static StaticTask_t uartTaskStruct;
static constexpr uint32_t kUartTxCompleteFlag = 1;
static osThreadId_t sUartTaskHandle;
constexpr uint32_t kUartTaskSize = 1024;
static uint8_t uartStack[kUartTaskSize];
static osThread_t sUartTaskControlBlock;
constexpr osThreadAttr_t kUartTaskAttr = { .name = "UART",
.attr_bits = osThreadDetached,
.cb_mem = &sUartTaskControlBlock,
.cb_size = osThreadCbSize,
.stack_mem = uartStack,
.stack_size = kUartTaskSize,
.priority = osPriorityRealtime };

typedef struct
{
uint8_t data[UART_TX_MAX_BUF_LEN];
uint16_t length = 0;
} UartTxStruct_t;

static osMessageQueueId_t sUartTxQueue;
static osMessageQueue_t sUartTxQueueStruct;
uint8_t sUartTxQueueBuffer[UART_MAX_QUEUE_SIZE * sizeof(UartTxStruct_t)];
static StaticQueue_t sUartTxQueueStruct;
static QueueHandle_t sUartTxQueue;
constexpr osMessageQueueAttr_t kUartTxQueueAttr = { .cb_mem = &sUartTxQueueStruct,
.cb_size = osMessageQueueCbSize,
.mq_mem = sUartTxQueueBuffer,
.mq_size = sizeof(sUartTxQueueBuffer) };

// Rx buffer for the receive Fifo
static uint8_t sRxFifoBuffer[MAX_BUFFER_SIZE];
Expand Down Expand Up @@ -264,8 +273,8 @@ void uartConsoleInit(void)
UARTDRV_Receive(vcom_handle, sRxDmaBuffer, MAX_DMA_BUFFER_SIZE, UART_rx_callback);
UARTDRV_Receive(vcom_handle, sRxDmaBuffer2, MAX_DMA_BUFFER_SIZE, UART_rx_callback);

sUartTxQueue = xQueueCreateStatic(UART_MAX_QUEUE_SIZE, sizeof(UartTxStruct_t), sUartTxQueueBuffer, &sUartTxQueueStruct);
sUartTaskHandle = xTaskCreateStatic(uartMainLoop, UART_TASK_NAME, UART_TASK_SIZE, nullptr, 30, uartStack, &uartTaskStruct);
sUartTxQueue = osMessageQueueNew(UART_MAX_QUEUE_SIZE, sizeof(UartTxStruct_t), &kUartTxQueueAttr);
sUartTaskHandle = osThreadNew(uartMainLoop, nullptr, &kUartTaskAttr);

assert(sUartTaskHandle);
assert(sUartTxQueue);
Expand Down Expand Up @@ -311,9 +320,8 @@ void USART_IRQHandler(void)
*/
void UART_tx_callback(struct UARTDRV_HandleData * handle, Ecode_t transferStatus, uint8_t * data, UARTDRV_Count_t transferCount)
{
BaseType_t xHigherPriorityTaskWoken;

vTaskNotifyGiveFromISR(sUartTaskHandle, &xHigherPriorityTaskWoken) portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
// This function may be called from Interrupt Service Routines.
osThreadFlagsSet(sUartTaskHandle, kUartTxCompleteFlag);
}

/*
Expand Down Expand Up @@ -363,20 +371,10 @@ int16_t uartConsoleWrite(const char * Buf, uint16_t BufLength)
memcpy(workBuffer.data, Buf, BufLength);
workBuffer.length = BufLength;

if (xPortIsInsideInterrupt())
if (osMessageQueuePut(sUartTxQueue, &workBuffer, osPriorityNormal, 0) == osOK)
{
BaseType_t xHigherPriorityTaskWoken;
xQueueSendFromISR(sUartTxQueue, &workBuffer, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
return BufLength;
}
else
{
if (pdTRUE == xQueueSend(sUartTxQueue, &workBuffer, portMAX_DELAY))
{
return BufLength;
}
}

return UART_CONSOLE_ERR;
}
Expand All @@ -400,20 +398,10 @@ int16_t uartLogWrite(const char * log, uint16_t length)
memcpy(workBuffer.data + length, "\r\n", 2);
workBuffer.length = length + 2;

if (xPortIsInsideInterrupt())
if (osMessageQueuePut(sUartTxQueue, &workBuffer, osPriorityNormal, 0) == osOK)
{
BaseType_t xHigherPriorityTaskWoken;
xQueueSendFromISR(sUartTxQueue, &workBuffer, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
return length;
}
else
{
if (pdTRUE == xQueueSend(sUartTxQueue, &workBuffer, 0))
{
return length;
}
}

return UART_CONSOLE_ERR;
}
Expand Down Expand Up @@ -453,11 +441,11 @@ void uartMainLoop(void * args)
while (1)
{

BaseType_t eventReceived = xQueueReceive(sUartTxQueue, &workBuffer, portMAX_DELAY);
osStatus_t eventReceived = osMessageQueueGet(sUartTxQueue, &workBuffer, nullptr, osWaitForever);
while (eventReceived == pdTRUE)
{
uartSendBytes(workBuffer.data, workBuffer.length);
eventReceived = xQueueReceive(sUartTxQueue, &workBuffer, 0);
eventReceived = osMessageQueueGet(sUartTxQueue, &workBuffer, nullptr, 0);
}
}
}
Expand All @@ -470,29 +458,31 @@ void uartMainLoop(void * args)
*/
void uartSendBytes(uint8_t * buffer, uint16_t nbOfBytes)
{

#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM1);
#endif
#endif // SL_CATALOG_POWER_MANAGER_PRESENT

#if SL_UARTCTRL_MUX
sl_wfx_host_pre_uart_transfer();
#endif // SL_UARTCTRL_MUX

#if (defined(EFR32MG24) && defined(WF200_WIFI))
// Blocking transmit for the MG24 + WF200 since UART TX is multiplexed with
// WF200 SPI IRQ
UARTDRV_ForceTransmit(vcom_handle, (uint8_t *) buffer, nbOfBytes);
#else
// Non Blocking Transmit
UARTDRV_Transmit(vcom_handle, (uint8_t *) buffer, nbOfBytes, UART_tx_callback);
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
osThreadFlagsWait(kUartTxCompleteFlag, osFlagsWaitAny, osWaitForever);
#endif /* EFR32MG24 && WF200_WIFI */

#if SL_UARTCTRL_MUX
sl_wfx_host_post_uart_transfer();
#endif // SL_UARTCTRL_MUX

#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1);
#endif
#endif // SL_CATALOG_POWER_MANAGER_PRESENT
}

#ifdef __cplusplus
Expand Down

0 comments on commit 7b2118d

Please sign in to comment.