Use FreeRTOS stream buffers and task notifications
This commit is contained in:
committed by
Raphael Coeffic
parent
59f2b5e8b0
commit
73790c1654
+66
-15
@@ -27,6 +27,10 @@
|
||||
|
||||
#include "cli_traces.h"
|
||||
|
||||
#if defined(INTMODULE_USART)
|
||||
#include "intmodule_serial_driver.h"
|
||||
#endif
|
||||
|
||||
#define CLI_COMMAND_MAX_ARGS 8
|
||||
#define CLI_COMMAND_MAX_LEN 256
|
||||
|
||||
@@ -853,6 +857,20 @@ int cliSet(const char **argv)
|
||||
}
|
||||
|
||||
#if defined(ENABLE_SERIAL_PASSTHROUGH)
|
||||
static StreamBufferHandle_t spIntRxBuffer;
|
||||
|
||||
static void spRx(uint8_t data)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xStreamBufferSendFromISR(spIntRxBuffer, &data, 1,
|
||||
&xHigherPriorityTaskWoken);
|
||||
xTaskNotifyFromISR(cliTaskId.rtos_handle, 0, eNoAction,
|
||||
&xHigherPriorityTaskWoken);
|
||||
|
||||
// might effect a context switch on ISR exit
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
|
||||
int cliSerialPassthrough(const char **argv)
|
||||
{
|
||||
const char* port_type = argv[1];
|
||||
@@ -902,36 +920,69 @@ int cliSerialPassthrough(const char **argv)
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
if (port_n == INTERNAL_MODULE) {
|
||||
|
||||
// TODO: check the stack level so we don't crash it
|
||||
uint8_t* tmpBuf = (uint8_t*)malloc(256);
|
||||
size_t rx_bytes = 0;
|
||||
|
||||
// allocate quick & dirty a buffer on the heap
|
||||
// to be able to send via DMA
|
||||
constexpr size_t tmpBufSize = 128;
|
||||
uint8_t* tmpBuf = (uint8_t*)malloc(tmpBufSize*2);
|
||||
uint8_t* tmpBuf2 = tmpBuf + tmpBufSize;
|
||||
|
||||
StaticStreamBuffer_t spIntRxBufferStatic;
|
||||
// uses first half of 'tmpBuf'
|
||||
spIntRxBuffer = xStreamBufferCreateStatic(tmpBufSize, 1, tmpBuf, &spIntRxBufferStatic);
|
||||
|
||||
// setup serial com
|
||||
// TODO:
|
||||
// - '8n1' param
|
||||
intmoduleSerialStart(baudrate, true, USART_Parity_No, USART_StopBits_1,
|
||||
USART_WordLength_8b);
|
||||
for (;;) {
|
||||
/* Block for max 10ms. */
|
||||
const TickType_t xTimeout = 10 / RTOS_MS_PER_TICK;
|
||||
size_t xReceivedBytes =
|
||||
xStreamBufferReceive(cliRxBuffer, tmpBuf, sizeof(tmpBuf), xTimeout);
|
||||
etx_serial_init params;
|
||||
params.baudrate = baudrate;
|
||||
params.rx_enable = true;
|
||||
params.on_receive = spRx;
|
||||
intmoduleSerialStart(¶ms);
|
||||
|
||||
// loop forever
|
||||
for (;;) {
|
||||
|
||||
/* Block for max 100ms. */
|
||||
const TickType_t xTimeout = 10 / RTOS_MS_PER_TICK;
|
||||
BaseType_t notified = xTaskNotifyWait(0, 0, NULL, xTimeout);
|
||||
|
||||
// keep us up & running
|
||||
WDG_RESET();
|
||||
|
||||
if (xReceivedBytes) {
|
||||
// TODO: wait for previous buffer flushed
|
||||
// Timeout ?
|
||||
if (notified == pdFALSE)
|
||||
continue;
|
||||
|
||||
// use 2nd half of 'tmpBuf'
|
||||
rx_bytes = xStreamBufferBytesAvailable(cliRxBuffer);
|
||||
if (rx_bytes) {
|
||||
// debug
|
||||
GPIO_SetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN);
|
||||
|
||||
// wait for end of last transmission
|
||||
intmoduleWaitForTxCompleted();
|
||||
intmoduleSendBuffer(tmpBuf, xReceivedBytes);
|
||||
|
||||
rx_bytes = xStreamBufferReceive(cliRxBuffer, tmpBuf2, tmpBufSize, 0);
|
||||
intmoduleSendBuffer(tmpBuf2, rx_bytes); // sends asynchronously
|
||||
|
||||
// debug
|
||||
GPIO_ResetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN);
|
||||
}
|
||||
|
||||
// Let's hope this does not starve the other side
|
||||
uint8_t inData;
|
||||
while(intmoduleFifo.pop(inData)) {
|
||||
serialPutc(inData);
|
||||
uint8_t inData[tmpBufSize];
|
||||
rx_bytes = xStreamBufferReceive(spIntRxBuffer, inData, tmpBufSize, 0);
|
||||
if (rx_bytes) {
|
||||
for (uint8_t *tx_data = inData; rx_bytes > 0; tx_data++, rx_bytes--) {
|
||||
serialPutc(*tx_data); // sends synchronously
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
intmoduleSerialStop();
|
||||
vStreamBufferDelete(spIntRxBuffer);
|
||||
free(tmpBuf);
|
||||
tmpBuf = nullptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user