refactor(extern_interface): implement deinitialization and improve event handling

- Add extern_interface_deinit() function for proper deinitialization
- Implement event queue with move semantics for better performance
- Update telemetry and alarm handling logic
- Refactor code to use more modern C++ features and improve readability
This commit is contained in:
Ovizro 2024-12-02 14:48:26 +08:00
parent 6fb6402219
commit 539ea0e170
7 changed files with 57 additions and 44 deletions

View File

@ -8,7 +8,7 @@ if (NOT CMAKE_CROSSCOMPILING)
endif()
if (UNIX)
set(CMAKE_CXX_FLAGS "-std=c++17 -fPIC -Wall ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "-std=c++11 -fPIC -Wall ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "-g ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "-g -O2 ${CMAKE_CXX_FLAGS}")
elseif (WIN32)

View File

@ -14,7 +14,7 @@ public:
void Push(T data)
{
std::lock_guard<std::mutex> lock(m_Mutex);
m_Queue.push_back(data);
m_Queue.push_back(std::move(data));
m_Cond.notify_one();
}
@ -25,7 +25,7 @@ public:
{
m_Cond.wait(lock);
}
T data = m_Queue.front();
T data = std::move(m_Queue.front());
m_Queue.pop_front();
return data;
}

View File

@ -21,6 +21,7 @@ extern int g_iTelemetry_Com_tty_id;
extern int g_iEnableAlarmCode;
extern bool g_bKeepEtifRuning;
extern int g_iExternTimeDifference;
extern int g_iUseHostComForTelemetry;
extern uint8_t g_iAlarmCode[4];
#ifdef __cplusplus

View File

@ -24,8 +24,12 @@
extern "C" {
#endif
struct AlarmData {
uint32_t alarm_id;
const char* text;
};
struct TelemetryRequestData {
bool keep_sys_running;
bool close_asr;
int sys_state;
bool volume_key_pressed;
@ -51,6 +55,8 @@ EXTERN_INTERFACE_PUBLIC
int extern_interface_init(const char* config_path, et_callback_t cb);
EXTERN_INTERFACE_PUBLIC
void extern_interface_send(uint32_t type, size_t len, union PacketData data);
EXTERN_INTERFACE_PUBLIC
void extern_interface_deinit();
#ifdef __cplusplus
}

View File

@ -7,18 +7,18 @@
#include <string.h>
#include "event.h"
#include "dataqueue.hpp"
#include "etif_detail.h"
std::unordered_map<std::string, std::vector<std::pair<event_callback, void*>>> _events;
DataQueue<std::tuple<const char*, event_callback, std::unique_ptr<void>, void*>> _event_queue;
DataQueue<std::tuple<const char*, event_callback, std::unique_ptr<uint8_t[]>, void*>> _event_queue;
void etif_event(const char *event_name, void *args, size_t args_size) {
auto it = _events.find(event_name);
if (it != _events.end()) {
for (auto &pair : it->second) {
void* args_copy = malloc(args_size);
assert(args_copy != nullptr);
auto args_copy = new uint8_t[args_size];
memcpy(args_copy, args, args_size);
_event_queue.Push(std::make_tuple(event_name, pair.first, std::unique_ptr<void>(args), pair.second));
_event_queue.Push(std::make_tuple(event_name, pair.first, std::unique_ptr<uint8_t[]>(args_copy), pair.second));
}
}
}
@ -54,9 +54,9 @@ int etif_event_unregister(const char *event_name, event_callback callback, void*
void* etif_event_thread(void*) {
const char* event_name;
event_callback callback;
std::unique_ptr<void> args;
std::unique_ptr<uint8_t[]> args;
void* user_data;
while (true) {
while (g_bKeepEtifRuning) {
std::tie(event_name, callback, args, user_data) = _event_queue.Pop();
callback(event_name, args.get(), user_data);
}

View File

@ -8,13 +8,27 @@ static pthread_t event_thread;
static pthread_t upperhost_thread;
static pthread_t telemetry_thread;
int extern_interface_init(const char* config_path, et_callback_t cb) {
int g_iHostCom_tty_id;
int g_iTelemetry_Com_tty_id;
int g_iEnableAlarmCode = true;
bool g_bKeepEtifRuning = false;
int g_iExternTimeDifference = 0;
int g_iUseHostComForTelemetry = true;
uint8_t g_iAlarmCode[4] = {0xAA, 0xAA, 0xAA, 0xAA};
static int read_config(const char* config_path) {
inicpp::IniManager manager(config_path);
}
int extern_interface_init(const char* config_path, et_callback_t cb) {
if (read_config(config_path)) return -1;
et_callback = cb;
g_bKeepEtifRuning = true;
pthread_create(&event_thread, NULL, etif_event_thread, NULL);
pthread_create(&upperhost_thread, NULL, upper_host_com_thread, NULL);
pthread_create(&telemetry_thread, NULL, telemetry_host_com_thread, NULL);
return 0;
}
void extern_interface_send(uint32_t type, size_t len, union PacketData data) {
@ -30,6 +44,13 @@ void extern_interface_send(uint32_t type, size_t len, union PacketData data) {
}
}
void extern_interface_deinit() {
g_bKeepEtifRuning = false;
pthread_cancel(event_thread);
pthread_cancel(upperhost_thread);
pthread_cancel(telemetry_thread);
}
void handle_pack(uint32_t type, size_t len, union PacketData data) {
et_callback(type, len, data);
}

View File

@ -3,6 +3,7 @@
#include <list>
#include <sys/time.h>
#include <sys/sysinfo.h>
#include <unistd.h>
#include "telemetry.h"
#include "dataqueue.hpp"
#include "command.h"
@ -258,11 +259,7 @@ void* telemetry_host_com_thread(void* path) {//Integrated Business Unit, telemet
}
//获取指令文本与报警码
struct AlarmNotice {
uint32_t iAlarmCode; //指令编码,小端序
const char* pAlarmText;
};
AlarmNotice g_AlarmTable[] = {
AlarmData g_AlarmTable[] = {
{0x61006100, "热控A回路压力报警"},
{0x62006200, "热控B回路压力报警"},
{0x63006300, "热控分系统,参数异常"},
@ -343,16 +340,16 @@ AlarmNotice g_AlarmTable[] = {
};
//获取指令文本与报警码
const char* GetAlarmTextByCode(uint8_t cmd_code[], uint8_t iAlarmCode[4])
AlarmData* GetAlarmTextByCode(uint8_t cmd_code[], uint8_t iAlarmCode[4])
{
uint32_t iCode = *(uint32_t*)cmd_code ;
uint32_t* pAlarmCode = (uint32_t*)iAlarmCode;
int n = sizeof(g_AlarmTable) / sizeof(struct AlarmNotice);
int n = sizeof(g_AlarmTable) / sizeof(struct AlarmData);
for (int i = 0; i<n; ++i) {
if (g_AlarmTable[i].iAlarmCode == iCode) {
if (g_AlarmTable[i].alarm_id == iCode) {
*pAlarmCode = iCode;
return g_AlarmTable[i].pAlarmText;
return &g_AlarmTable[i];
}
}
*pAlarmCode = 0;
@ -553,25 +550,13 @@ void* upper_host_com_thread(void* arg) {//hand-control display processing unit
int iTextBytes;
const char *pNoticeStr;
ttsInfo.m_iSource = 0;
ttsInfo.m_iTimerValue = -1;
g_iOrdinaryPlayStop = 1;
ttsInfo.m_iUrgent = 1;
//语音通报与报警码
pNoticeStr = GetAlarmTextByCode(frame->payload+2, g_iAlarmCode);
if(!pNoticeStr)
auto alarm = GetAlarmTextByCode(frame->payload+2, g_iAlarmCode);
if(!alarm)
continue;
handle_pack(ET_TYPE_TEXT, sizeof(alarm), {.pd_pointer = alarm});
iTextBytes = strlen(pNoticeStr) + 1;
ttsInfo.m_iDataBytes = iTextBytes;
iEnqueueBytes = EnDataQueue(g_pDataQueue[TEXT_QUEUE_FOR_TTS_URGENT], (void*)(&ttsInfo), sizeof(ttsInfo),
(void*)pNoticeStr, iTextBytes, NULL, 0);
if (iEnqueueBytes <= 0) {//队列满,入队失败
ProcQueueFull(TEXT_QUEUE_FOR_TTS_URGENT, true);
iEnqueueBytes = EnDataQueue(g_pDataQueue[TEXT_QUEUE_FOR_TTS_URGENT], (void*)(&ttsInfo), sizeof(ttsInfo),
(void*)pNoticeStr, iTextBytes, NULL, 0);
}
uint8_t payload[6] = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55};
ComFrame* f_data = ComFrame_New(
COM_FRAME_ADDRESS_VOIX,
@ -617,11 +602,6 @@ void* upper_host_com_thread(void* arg) {//hand-control display processing unit
}
delete[] buffer;
free(ptrProcHostAudio);
if (g_pRcvCmdQueue)
{
CloseDataQueue(g_pRcvCmdQueue);
g_pRcvCmdQueue = NULL;
}
return NULL;
}
@ -629,14 +609,19 @@ void send_command_upper_host(int length, void* payload) {
int tty_id = g_iHostCom_tty_id;
need_resend = true;
int sendtime = 0;
ComFrame* f_data = ComFrame_New(
COM_FRAME_ADDRESS_VOIX,
COM_FRAME_TYPE_REQUEST,
payload, length, true);
struct timeval tCurTime;
gettimeofday(&tCurTime, NULL);
uint64_t tCurTimeMs = tCurTime.tv_sec * 1000 + tCurTime.tv_usec / 1000;
uint64_t last_send_time;
while (need_resend) {
if (sendtime == 0) {
last_send_time = g_iSysTimerMilliSeconds;
last_send_time = tCurTimeMs;
if (ComFrame_Send(tty_id, f_data, true)) {
PrintFilePos(); fprintf(stderr, "send telemetry data frame error: %s\n", strerror(errno));
@ -647,8 +632,8 @@ void send_command_upper_host(int length, void* payload) {
break;
}
else {
if (g_iSysTimerMilliSeconds > last_send_time + 250) {
last_send_time = g_iSysTimerMilliSeconds;
if (tCurTimeMs > last_send_time + 250) {
last_send_time = tCurTimeMs;
if (ComFrame_Send(tty_id, f_data, true)) {
PrintFilePos(); fprintf(stderr, "send telemetry data frame error: %s\n", strerror(errno));