#include "VK_Com.h" #include "VK_Client.h" #include "drv_ec800k.h" #include "rtdef.h" #include "rtthread.h" #include #define ENABLE_MEMORY_USAGE_LOG 0 #if ENABLE_MEMORY_USAGE_LOG #define DBG_TAG "MEM_LOG" #define DBG_LVL DBG_INFO #include #endif rt_device_t fmu_com = RT_NULL; rt_sem_t fmu_com_rx_sem = RT_NULL; #define FMU_NET_QUEUE_SIZE 512 static struct rt_ringbuffer fmu_net_queue; static struct rt_mutex fmu_net_queue_lock; static uint8_t fmu_net_queue_pool[FMU_NET_QUEUE_SIZE]; static bool fmu_net_queue_ready = false; #if ENABLE_MEMORY_USAGE_LOG static rt_size_t thread_stack_used(rt_thread_t thread) { rt_uint8_t *stack; rt_size_t unused = 0; if (thread == RT_NULL || thread->stack_addr == RT_NULL) { return 0; } stack = (rt_uint8_t *)thread->stack_addr; while (unused < thread->stack_size && stack[unused] == '#') { unused++; } return thread->stack_size - unused; } static void log_memory_usage(void) { rt_size_t total = 0; rt_size_t used = 0; rt_size_t max_used = 0; rt_thread_t lte_thread; rt_memory_info(&total, &used, &max_used); LOG_I("heap used=%u total=%u free=%u max=%u", used, total, total - used, max_used); lte_thread = rt_thread_find("lte"); if (lte_thread != RT_NULL) { rt_size_t stack_used = thread_stack_used(lte_thread); LOG_I("lte stack used=%u total=%u free=%u", stack_used, lte_thread->stack_size, lte_thread->stack_size - stack_used); } } #endif static rt_err_t fmu_com_rx_cb(rt_device_t dev, rt_size_t size) { if (fmu_com_rx_sem != RT_NULL) { rt_sem_release(fmu_com_rx_sem); } return RT_EOK; } rt_device_t fmu_com_get(void) { return fmu_com; } int fmu_com_register(rt_device_t com_dev) { fmu_com = com_dev; if (fmu_com_rx_sem == RT_NULL) { fmu_com_rx_sem = rt_sem_create("fmuComRx", 0, RT_IPC_FLAG_PRIO); } rt_device_set_rx_indicate(fmu_com, fmu_com_rx_cb); if (!fmu_net_queue_ready) { rt_ringbuffer_init(&fmu_net_queue, fmu_net_queue_pool, sizeof(fmu_net_queue_pool)); rt_mutex_init(&fmu_net_queue_lock, "fmuNet", RT_IPC_FLAG_PRIO); fmu_net_queue_ready = true; } return 0; } rt_size_t fmu_net_queue_put(const uint8_t *data, rt_size_t length) { rt_size_t queued; rt_size_t used; if (!fmu_net_queue_ready || data == RT_NULL || length == 0) return 0; rt_mutex_take(&fmu_net_queue_lock, RT_WAITING_FOREVER); queued = rt_ringbuffer_put(&fmu_net_queue, data, length); used = rt_ringbuffer_data_len(&fmu_net_queue); rt_mutex_release(&fmu_net_queue_lock); if (queued < length) lte_diag.tx_queue_drops += length - queued; if (used > lte_diag.tx_queue_high_water) lte_diag.tx_queue_high_water = used; return queued; } rt_size_t fmu_net_queue_get(uint8_t *data, rt_size_t length) { rt_size_t read; if (!fmu_net_queue_ready || data == RT_NULL || length == 0) return 0; rt_mutex_take(&fmu_net_queue_lock, RT_WAITING_FOREVER); read = rt_ringbuffer_get(&fmu_net_queue, data, length); rt_mutex_release(&fmu_net_queue_lock); return read; } void fmu_net_queue_reset(void) { if (!fmu_net_queue_ready) return; rt_mutex_take(&fmu_net_queue_lock, RT_WAITING_FOREVER); rt_ringbuffer_reset(&fmu_net_queue); rt_mutex_release(&fmu_net_queue_lock); } /*接收到串口的数据,并将数据转发到网络端*/ void com_task(void) { static uint8_t buff[128]; uint32_t len = 0; #if ENABLE_MEMORY_USAGE_LOG rt_tick_t memory_log_start = rt_tick_get(); #endif while (1) { if (rt_sem_take(fmu_com_rx_sem, 1000) == RT_EOK) { while (1) { len = rt_device_read(fmu_com, 0, buff, sizeof(buff)); if (len > 0) { lte_diag_fmu_data(buff, len); if (lte_dev.client1->connect_sta == true && lte_dev.data_tx_paused == false) { /* 仅在客户端2连接时转发 */ fmu_net_queue_put(buff, len); } } else { break; } } } #if ENABLE_MEMORY_USAGE_LOG if (rt_tick_get() - memory_log_start >= RT_TICK_PER_SECOND * 5) { memory_log_start = rt_tick_get(); log_memory_usage(); } #endif } }