feat: 保存已验证的CH390网络打通基线
This commit is contained in:
+174
@@ -0,0 +1,174 @@
|
||||
#include "route_msg.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "task.h"
|
||||
|
||||
typedef struct {
|
||||
route_msg_t msg;
|
||||
uint8_t data[ROUTE_MSG_MAX_PAYLOAD];
|
||||
uint8_t in_use;
|
||||
} route_slot_t;
|
||||
|
||||
static route_slot_t g_route_slots[ROUTE_MSG_POOL_SIZE];
|
||||
|
||||
void route_msg_init(void)
|
||||
{
|
||||
memset(g_route_slots, 0, sizeof(g_route_slots));
|
||||
}
|
||||
|
||||
static route_msg_t *route_msg_try_alloc_locked(void)
|
||||
{
|
||||
uint32_t index;
|
||||
|
||||
for (index = 0; index < ROUTE_MSG_POOL_SIZE; ++index) {
|
||||
if (g_route_slots[index].in_use == 0u) {
|
||||
g_route_slots[index].in_use = 1u;
|
||||
g_route_slots[index].msg.data = g_route_slots[index].data;
|
||||
g_route_slots[index].msg.len = 0u;
|
||||
g_route_slots[index].msg.src_id = 0u;
|
||||
g_route_slots[index].msg.dst_mask = 0u;
|
||||
g_route_slots[index].msg.conn_type = 0u;
|
||||
return &g_route_slots[index].msg;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
route_msg_t *route_msg_alloc(TickType_t wait_ticks)
|
||||
{
|
||||
TickType_t start_tick = xTaskGetTickCount();
|
||||
route_msg_t *msg;
|
||||
|
||||
do {
|
||||
taskENTER_CRITICAL();
|
||||
msg = route_msg_try_alloc_locked();
|
||||
taskEXIT_CRITICAL();
|
||||
if (msg != NULL) {
|
||||
return msg;
|
||||
}
|
||||
if (wait_ticks == 0u) {
|
||||
break;
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
} while ((xTaskGetTickCount() - start_tick) < wait_ticks);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
route_msg_t *route_msg_alloc_from_isr(BaseType_t *xHigherPriorityTaskWoken)
|
||||
{
|
||||
route_msg_t *msg;
|
||||
UBaseType_t saved_interrupt_status;
|
||||
|
||||
(void)xHigherPriorityTaskWoken;
|
||||
saved_interrupt_status = taskENTER_CRITICAL_FROM_ISR();
|
||||
msg = route_msg_try_alloc_locked();
|
||||
taskEXIT_CRITICAL_FROM_ISR(saved_interrupt_status);
|
||||
return msg;
|
||||
}
|
||||
|
||||
void route_msg_free(route_msg_t *msg)
|
||||
{
|
||||
uint32_t index;
|
||||
|
||||
if (msg == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
for (index = 0; index < ROUTE_MSG_POOL_SIZE; ++index) {
|
||||
if (&g_route_slots[index].msg == msg) {
|
||||
g_route_slots[index].in_use = 0u;
|
||||
g_route_slots[index].msg.len = 0u;
|
||||
break;
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
|
||||
void route_msg_free_from_isr(route_msg_t *msg)
|
||||
{
|
||||
uint32_t index;
|
||||
UBaseType_t saved_interrupt_status;
|
||||
|
||||
if (msg == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
saved_interrupt_status = taskENTER_CRITICAL_FROM_ISR();
|
||||
for (index = 0; index < ROUTE_MSG_POOL_SIZE; ++index) {
|
||||
if (&g_route_slots[index].msg == msg) {
|
||||
g_route_slots[index].in_use = 0u;
|
||||
g_route_slots[index].msg.len = 0u;
|
||||
break;
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL_FROM_ISR(saved_interrupt_status);
|
||||
}
|
||||
|
||||
static bool route_prepare(route_msg_t *msg,
|
||||
uint8_t src_id,
|
||||
uint8_t dst_mask,
|
||||
uint8_t conn_type,
|
||||
const uint8_t *data,
|
||||
uint16_t len)
|
||||
{
|
||||
if (msg == NULL || data == NULL || len == 0u || len > ROUTE_MSG_MAX_PAYLOAD) {
|
||||
return false;
|
||||
}
|
||||
|
||||
msg->src_id = src_id;
|
||||
msg->dst_mask = dst_mask;
|
||||
msg->conn_type = conn_type;
|
||||
msg->len = len;
|
||||
memcpy(msg->data, data, len);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool route_send(QueueHandle_t queue,
|
||||
uint8_t src_id,
|
||||
uint8_t dst_mask,
|
||||
uint8_t conn_type,
|
||||
const uint8_t *data,
|
||||
uint16_t len,
|
||||
TickType_t wait_ticks)
|
||||
{
|
||||
route_msg_t *msg = route_msg_alloc(wait_ticks);
|
||||
|
||||
if (!route_prepare(msg, src_id, dst_mask, conn_type, data, len)) {
|
||||
route_msg_free(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xQueueSend(queue, &msg, wait_ticks) != pdPASS) {
|
||||
route_msg_free(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool route_send_from_isr(QueueHandle_t queue,
|
||||
uint8_t src_id,
|
||||
uint8_t dst_mask,
|
||||
uint8_t conn_type,
|
||||
const uint8_t *data,
|
||||
uint16_t len,
|
||||
BaseType_t *xHigherPriorityTaskWoken)
|
||||
{
|
||||
route_msg_t *msg = route_msg_alloc_from_isr(xHigherPriorityTaskWoken);
|
||||
|
||||
if (!route_prepare(msg, src_id, dst_mask, conn_type, data, len)) {
|
||||
route_msg_free_from_isr(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xQueueSendFromISR(queue, &msg, xHigherPriorityTaskWoken) != pdPASS) {
|
||||
route_msg_free_from_isr(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user