From 53a5fe6d501441803cd09a36f14b757f5b38a167 Mon Sep 17 00:00:00 2001 From: ovizro Date: Sat, 14 Dec 2024 14:39:28 +0800 Subject: [PATCH] feat(core): rename and restructure event handling and initialization - Rename exint_init to exint_initialize - Update event handling to use multiple threads - Add epoch checking to DataQueue - Modify config reading logic - Update build scripts - Refactor test cases --- CMakeLists.txt | 7 +- README.md | 2 +- include/CCfgFileParser.h | 78 +++++++++ include/dataqueue.hpp | 16 +- include/exint/event.h | 5 +- include/exint/handler.h | 26 +++ include/external_interface.h | 2 +- scripts/bdist.sh | 8 +- scripts/sdist.sh | 6 +- scripts/x3_mak | 12 ++ src/CCfgFileParser.cpp | 263 ++++++++++++++++++++++++++++ src/event.cpp | 47 +++-- src/external_interface.cpp | 62 +++++-- src/handler/base.cpp | 1 + src/host_com.cpp | 10 +- tests/CMakeLists.txt | 7 +- tests/test_event.cpp | 15 +- toolchains/armv7l_linux_setup.cmake | 6 +- 18 files changed, 508 insertions(+), 65 deletions(-) create mode 100755 include/CCfgFileParser.h create mode 100644 include/exint/handler.h create mode 100755 scripts/x3_mak create mode 100755 src/CCfgFileParser.cpp create mode 100644 src/handler/base.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ec7b848..bf9e396 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ if (CMAKE_CROSSCOMPILING) message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") endif() -include_directories(${CMAKE_SOURCE_DIR}/include) +include_directories(./include) aux_source_directory(${CMAKE_SOURCE_DIR}/src SRC_LIST) add_library(exint SHARED ${SRC_LIST}) @@ -40,8 +40,9 @@ set_target_properties(exint_static PROPERTIES OUTPUT_NAME exint) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") target_compile_options(exint PRIVATE -Wno-nonnull -fvisibility=hidden) + target_compile_options(exint_static PRIVATE -Wno-nonnull -fvisibility=hidden) endif() -link_libraries(pthread) +link_libraries(pthread util) -subdirs(tests) +add_subdirectory(tests) diff --git a/README.md b/README.md index 41a16d4..adc2b2f 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ cmake --build build -j6 --target test 以下接口由通讯模块公开,可以在VOIX主程序中使用。 -1. `void exint_init(const char* config_path, et_callback_t cb)`:模块初始化函数,此函数会读取配置文件,开启串口并启动模块所需的线程 +1. `void exint_initialize(const char* config_path, et_callback_t cb)`:模块初始化函数,此函数会读取配置文件,开启串口并启动模块所需的线程 - `config_path`:配置文件路径 - `cb`:回调函数,用于进行指令响应和遥测数据请求 2. `void (*et_callback_t)(uint32_t type, size_t len, void* data)`:回调函数类型,内部数据为指针类型的数据包仅保证在回调函数中有效。 diff --git a/include/CCfgFileParser.h b/include/CCfgFileParser.h new file mode 100755 index 0000000..5eb141e --- /dev/null +++ b/include/CCfgFileParser.h @@ -0,0 +1,78 @@ +#if !defined(AFX_CFGFILEPARSERGENERATOR_H__AAF8F913_7694_4A69_A05F_57A1A1887CA1__INCLUDED_) +#define AFX_CFGFILEPARSERGENERATOR_H__AAF8F913_7694_4A69_A05F_57A1A1887CA1__INCLUDED_ + +#include +#include + +#ifdef WIN32 +#pragma warning(disable:4786) +#pragma warning(disable:4503) +#endif + +#include +#include + +class __attribute__((visibility("default"))) CCfgFileParser +{ +public: + explicit CCfgFileParser(bool base64 = false, + char chSectionBMark = '[', + char chSectionEMark = ']', + char chRecordEMark = ';', //record end-mark + char chCommentMark = '#' + ) + :m_base64(base64), m_chSectionBMark(chSectionBMark), m_chSectionEMark(chSectionEMark), + m_chRecordEMark(chRecordEMark), m_chCommentMark(chCommentMark), m_bShowError(false) + { + } + + virtual ~CCfgFileParser() {} + + typedef std::map SECTION_CONTENT; + typedef std::map FILE_CONTENT; + +private: + bool m_base64; + enum{ + SYNTAX_ERROR = 0x100, + }; + +public: + bool m_bShowError; + const char* getErrorString(int err); + int parseFile(const char* lpszFilename); + int sections() const { return m_content.size(); } + + FILE_CONTENT::const_iterator sectionBegin() const { return m_content.begin(); } + FILE_CONTENT::const_iterator sectionEnd() const { return m_content.end(); } + + //return empty-string if no corresponding value presented. + bool getValue(const std::string& strSection, const std::string& strKey, const char *&Value) const; + bool getValue(const std::string& strKey, const char *&Value) const; + bool getIntValue(const std::string& strSection, const std::string& strKey, long &pValue) const; + bool getIntValue(const std::string& strKey, long &Value) const; + bool getDoubleValue(const std::string& strSection, const std::string& strKey, double &Value) const; + bool getDoubleValue(const std::string& strKey, double &Value) const; + void printContent(); + +protected: + bool extractSection(char* line, std::string& strSection); + bool extractKeyValue(char* line, std::pair& pairKeyValue); + +private: + FILE_CONTENT m_content; + + char m_chSectionBMark; + char m_chSectionEMark; + char m_chRecordEMark; + char m_chCommentMark; + int m_error_line; +}; + +extern "C" __attribute__((visibility("default"))) CCfgFileParser* createParser(); + + +extern "C" __attribute__((visibility("default"))) void deleteParser(CCfgFileParser* parser); + + +#endif // !defined(AFX_CFGFILEPARSERGENERATOR_H__AAF8F913_7694_4A69_A05F_57A1A1887CA1__INCLUDED_) diff --git a/include/dataqueue.hpp b/include/dataqueue.hpp index cb9fb7a..f31bc53 100644 --- a/include/dataqueue.hpp +++ b/include/dataqueue.hpp @@ -47,6 +47,8 @@ public: } }; +typedef uint8_t queue_epoch_t; + template class DataQueue { public: @@ -109,6 +111,18 @@ public: return m_Queue.size(); } + queue_epoch_t GetEpoch() noexcept + { + std::lock_guard lock(m_Mutex); + return m_CurrEpoch; + } + + bool CheckEpoch(queue_epoch_t epoch) noexcept + { + std::lock_guard lock(m_Mutex); + return m_CurrEpoch == epoch; + } + void Clear() noexcept { std::lock_guard lock(m_Mutex); @@ -123,7 +137,7 @@ protected: std::condition_variable m_Cond; private: - uint8_t m_CurrEpoch; + queue_epoch_t m_CurrEpoch; }; #endif \ No newline at end of file diff --git a/include/exint/event.h b/include/exint/event.h index 864e7c0..e106eda 100644 --- a/include/exint/event.h +++ b/include/exint/event.h @@ -1,6 +1,7 @@ #ifndef _INCLUDE_EVENT_H_ #define _INCLUDE_EVENT_H_ +#include #include #define CONCAT_(prefix, suffix) prefix##suffix @@ -23,8 +24,8 @@ typedef void (*event_callback)(const char*, size_t, void*, void*); void exint_event(const char *event_name, size_t args_size, void *args); int exint_event_register(const char *event_name, event_callback callback, void* user_data); int exint_event_unregister(const char *event_name, event_callback callback, void* user_data); -void* exint_event_thread(void*); -void exint_event_thread_exit(); +void exint_event_thread_start(uint8_t num); +void exint_event_thread_stop(); #ifdef __cplusplus } diff --git a/include/exint/handler.h b/include/exint/handler.h new file mode 100644 index 0000000..045dcaa --- /dev/null +++ b/include/exint/handler.h @@ -0,0 +1,26 @@ +#ifndef _INCLUDE_EXINT_HANDLER_ +#define _INCLUDE_EXINT_HANDLER_ + +#include +#include "comframe.h" + +#define ET_HDL_FLAG_DEFAULT 0 +#define ET_HDL_FLAG_DISABLED 1 +#define ET_HDL_FLAG_ASYNC 2 +#define ET_HDL_FLAG_NOVERIFY 4 + +#ifdef __cplusplus +extern "C" { +#endif + +struct EtHandlerDef { + uint16_t hd_type; + uint16_t hd_flags; + void (*hd_handler)(struct EtHandlerDef *handler, ComFrame* frame); +}; + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/external_interface.h b/include/external_interface.h index b2077a3..437f792 100644 --- a/include/external_interface.h +++ b/include/external_interface.h @@ -44,7 +44,7 @@ struct TelemetryRequestData { typedef void (*et_callback_t)(uint32_t, size_t, void*); EXTERN_INTERFACE_PUBLIC -int exint_init(const char* config_path, et_callback_t cb); +int exint_initialize(const char* config_path, et_callback_t cb); EXTERN_INTERFACE_PUBLIC void exint_send(uint32_t type, size_t len, void* data); EXTERN_INTERFACE_PUBLIC diff --git a/scripts/bdist.sh b/scripts/bdist.sh index 88c9ca2..270e532 100755 --- a/scripts/bdist.sh +++ b/scripts/bdist.sh @@ -1,5 +1,9 @@ #!/bin/sh mkdir -p dist -zip -r "dist/exint-build-$(date +%Y%m%d-%H%M%S).zip" bin/ lib/ config/\ - scripts/ README.md include/external_interface.h \ No newline at end of file +NAME="dist/exint-build-$(date +%Y%m%d-%H%M%S).zip" + +zip -r $NAME bin/ lib/ config/\ + scripts/ README.md include/external_interface.h + +echo "Created $NAME" diff --git a/scripts/sdist.sh b/scripts/sdist.sh index 825588b..6dfc585 100755 --- a/scripts/sdist.sh +++ b/scripts/sdist.sh @@ -1,5 +1,9 @@ #!/bin/sh mkdir -p dist -tar -czvf "dist/exint-$(date +%Y%m%d-%H%M%S).tar.gz" src/ include/ tests/ config/\ +NAME="dist/exint-$(date +%Y%m%d-%H%M%S).tar.gz" + +tar -czvf $NAME src/ include/ tests/ config/\ scripts/ toolchains/ README.md CMakeLists.txt mak .gitignore + +echo "Created $NAME" diff --git a/scripts/x3_mak b/scripts/x3_mak new file mode 100755 index 0000000..ef4ee51 --- /dev/null +++ b/scripts/x3_mak @@ -0,0 +1,12 @@ +#!/bin/bash +SERVER="sunrise@192.168.50.58" +SDIST=$(./scripts/sdist.sh | tail -1 | sed "s/Created //") +scp -r ${SDIST} $SERVER:/tmp +ssh $SERVER << EOF +mkdir -p voix_exint && cd voix_exint +tar -xzf /tmp/$(basename ${SDIST}) +./mak $@ +rm -rf src/ include/ tests/ build/ +EOF +rm -rf ./lib/x3/ +scp -r $SERVER:voix_exint/lib/ ./lib/x3/ diff --git a/src/CCfgFileParser.cpp b/src/CCfgFileParser.cpp new file mode 100755 index 0000000..4f93494 --- /dev/null +++ b/src/CCfgFileParser.cpp @@ -0,0 +1,263 @@ +//bb.cpp + +#include +#include +#include +#include +#include +#include +#include + +#include "CCfgFileParser.h" + +using namespace std; + +static inline bool istab(int c) { return (c == '\t'); } + +static inline char *strltrim(char *str) { + while (isspace(*str) || istab(*str)) { + ++str; + } + return str; +} + +static inline char *strrtrim(char *str) { + int len = strlen(str) - 1; + while (isspace(str[len]) || istab(str[len])) { + str[len--] = '\0'; + } + return str; +} + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// +int CCfgFileParser::parseFile(const char *lpszFilename) { + using std::string; + std::ifstream in1(lpszFilename); + + if (!in1.is_open()) return errno; + + char line[2048]; + char *pline; + bool bInSection = false; + SECTION_CONTENT *pSC = NULL; + string strSection; + std::pair pairKeyValue; + + m_error_line = 0; + m_content.clear(); + pSC = &m_content["default"]; + bInSection = true; + string base64str(""); + string mystr(""); + while (!in1.eof()) { + in1.getline(line, sizeof(line)); + + if (line[strlen(line)] != '\n') + mystr += line + string("\n"); + else + mystr += line; + + } + in1.close(); + + stringstream in; + in.str(mystr); + + while (!in.eof()) { /*if(base64str.size() > sizeof(line)) + { + printf("error in config parser!\n"); + return -1; + } + memcpy(line, base64str.c_str(), base64str.size()); + */ + in.getline(line, sizeof(line)); + pline = line; + ++m_error_line; + pline = strltrim(pline); + if (pline[0] == '\0') continue; //white line, skip + if (pline[0] == m_chCommentMark) continue; //comment line, skip + if (bInSection) { + //is new-section begin? + if (pline[0] == m_chSectionBMark && extractSection(pline, strSection)) { + pSC = &m_content[strSection]; + } + else if (extractKeyValue(pline, pairKeyValue)) { + //key-value pair + pSC->insert(pairKeyValue); + } + else { + //in.close(); + return SYNTAX_ERROR; + } + } + else { //NOT in section + //is a valid section? + if (extractSection(pline, strSection)) { + pSC = &m_content[strSection]; + bInSection = true; + } + else { + //in.close(); + return SYNTAX_ERROR; + } + } + } + // in.close(); + return 0; +} + + +bool CCfgFileParser::getValue(const std::string &strSection, + const std::string &strKey, const char * &Value) const { + FILE_CONTENT::const_iterator it; + + if ((it = m_content.find(strSection)) != m_content.end()) { + SECTION_CONTENT::const_iterator p; + const SECTION_CONTENT §ion = (*it).second;//m_content[strSection]; + if ((p = section.find(strKey)) != section.end()) { + Value = ((*p).second).c_str(); + return true; + } + } + + if (m_bShowError) + fprintf(stderr, "***Error: fail to read [%s]:%s\n", strSection.c_str(), strKey.c_str()); + return false; +} + +bool CCfgFileParser::getValue(const std::string &strKey, const char * &pValue) const { + return getValue("default", strKey, pValue); +} + +bool CCfgFileParser::getIntValue(const std::string &strSection, + const std::string& strKey, long& Value) const { + const char* pstr; + if (getValue(strSection, strKey, pstr) && strlen(pstr) > 0) + { + if (strlen(pstr) > 0) + { + Value = atol(pstr); + return true; + } + } + if (m_bShowError) + fprintf(stderr, "***Error: fail to read [%s]:%s\n", strSection.c_str(), strKey.c_str()); + return false; +} + +bool CCfgFileParser::getIntValue(const std::string &strKey, long &Value) const { + return getIntValue("default", strKey, Value); +} + +bool CCfgFileParser::getDoubleValue(const std::string &strSection, + const std::string &strKey, double &Value) const { + const char *pstr; + if (getValue(strSection, strKey, pstr) && strlen(pstr) > 0) + { + Value = atof(pstr); + return true; + } + else + { + if (m_bShowError) + fprintf(stderr, "***Error: fail to read [%s]:%s\n", strSection.c_str(), strKey.c_str()); + return false; + } +} + +bool CCfgFileParser::getDoubleValue(const std::string &strKey, double &Value) const { + return getDoubleValue("default", strKey, Value); +} + + +/* + * Description: Extract section name + * Parameters: line[IN]---A string line to be parsed + * strSection[OUT]---Section name + * + * Return Value: if section name is in the line return true,or return false + */ +bool CCfgFileParser::extractSection(char *line, std::string &strSection) { + char *tmp; + if (line[0] == m_chSectionBMark) { + if ((tmp = strchr(++line, m_chSectionEMark)) != NULL) { + *tmp = '\0'; + strSection = line; + return true; + } + } + + return false; +} + + +/* + * Description: Parse a record line into a std:pair as key and value + * Parameters: line[IN]---A string to be parsed + * pairKeyValue[OUT]---Parsing result + * + * Return Value: If parse successfully return true,or return false + */ + +bool CCfgFileParser::extractKeyValue(char *line, + std::pair &pairKeyValue) { + char *tmp; + if ((tmp = strchr(line, m_chRecordEMark)) != NULL || (tmp = strchr(line, '\r')) != NULL || + (tmp = strchr(line, '='))) { + if (*tmp == '=') + tmp = line + strlen(line); // tmp++; + *tmp = '\0'; //ignore content after ';'(the RecordEMark) + if ((tmp = strchr(line, '=')) != NULL) { + *tmp++ = '\0'; + tmp = strltrim(tmp); + tmp = strrtrim(tmp); + line = strrtrim(line); + + pairKeyValue.first = line; + pairKeyValue.second = tmp; + return true; + } + } + + return false; +} + +const char *CCfgFileParser::getErrorString(int err) { + static char buf[100]; + if (err == SYNTAX_ERROR) { + sprintf(buf, "configuration file format is invalid at line %d", m_error_line); + return buf; + } + else { + return strerror(err); + } +} + + +void CCfgFileParser::printContent() { + using std::cout; + using std::endl; + FILE_CONTENT::const_iterator pf; + SECTION_CONTENT::const_iterator ps; + for (pf = m_content.begin(); pf != m_content.end(); ++pf) { + cout << "section:" << (*pf).first << endl; + const SECTION_CONTENT &sc = (*pf).second; + for (ps = sc.begin(); ps != sc.end(); ++ps) { + cout << '\t' << (*ps).first << "=" << (*ps).second << endl; + } + } +} + +// 在库中定义一个工厂函数 createParser +extern "C" __attribute__((visibility("default"))) CCfgFileParser* createParser() { + return new CCfgFileParser(); // 在工厂函数中调用构造函数创建对象并返回指针 +} + +// 在库中定义一个销毁函数 deleteParser + +extern "C" __attribute__((visibility("default"))) void deleteParser(CCfgFileParser* parser) { + // 在销毁函数中调用析构函数销毁对象 + delete parser; +} \ No newline at end of file diff --git a/src/event.cpp b/src/event.cpp index 77b1bc6..e5d8ebc 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -4,15 +4,19 @@ #include #include #include +#include #include #include +#include "logging/logger.hpp" #include "dataqueue.hpp" #include "exint/event.h" #include "exint/detail.h" -std::atomic_bool _is_event_thread_running { false }; -DataQueue, void*>> _event_queue; +using EventCallbackData = std::tuple, void*>; +std::atomic_size_t _event_thread_count { 0 }; +DataQueue _event_queue; +static auto& logger = *logging::get_logger("exint::event"); static std::unordered_map>>& get_event_map() { static std::unordered_map>> _events; return _events; @@ -23,7 +27,7 @@ void exint_event(const char *event_name, size_t args_size, void *args) { auto it = event_map.find(event_name); if (it != event_map.end()) { for (auto &pair : it->second) { - if (!_is_event_thread_running) { + if (!_event_thread_count.load()) { pair.first(event_name, args_size, args, pair.second); continue; } @@ -70,31 +74,46 @@ int exint_event_unregister(const char *event_name, event_callback callback, void } void* exint_event_thread(void*) { - bool is_running = false; - if (!_is_event_thread_running.compare_exchange_strong(is_running, true)) { - return NULL; - } - const char* event_name; + std::string event_name; event_callback callback; size_t args_size; std::unique_ptr args; void* user_data; - while (g_bKeepExintRuning) { + queue_epoch_t queue_epoch = _event_queue.GetEpoch(); + _event_thread_count.fetch_add(1); + while (_event_queue.CheckEpoch(queue_epoch)) { try { std::tie(event_name, callback, args_size, args, user_data) = _event_queue.Pop(); } catch (const QueueException&) { break; } - callback(event_name, args_size, args.get(), user_data); + callback(event_name.c_str(), args_size, args.get(), user_data); } - _is_event_thread_running.store(false); + _event_thread_count.fetch_sub(1); return NULL; } -void exint_event_thread_exit() { - bool is_running = true; - if (!_is_event_thread_running.compare_exchange_strong(is_running, false)) { +void exint_event_thread_start(uint8_t num) { + if (_event_thread_count.load()) { + logger.warn("event thread already started"); + } + for (int i = 0; i < num; i++) { + std::thread([] { (void)exint_event_thread(NULL); }).detach(); + } + while (_event_thread_count.load() != num) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + logger.info("started %d event threads", num); +} + +void exint_event_thread_stop() { + if (!_event_thread_count.load()) { + logger.warn("event thread already stopped"); return; } _event_queue.Clear(); + while (_event_thread_count.load()) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + logger.info("stopped event threads"); } diff --git a/src/external_interface.cpp b/src/external_interface.cpp index e0e9665..f3bc3b7 100644 --- a/src/external_interface.cpp +++ b/src/external_interface.cpp @@ -1,17 +1,18 @@ #include #include "logging/logger.hpp" #include "comframe.h" +#include "CCfgFileParser.h" #include "inicpp.hpp" #include "exint/detail.h" #include "exint/event.h" +static auto& logger = *logging::get_logger("exint"); static et_callback_t et_callback; -static pthread_t event_thread; static pthread_t upperhost_thread; static pthread_t telemetry_thread; -int g_iHostCom_tty_id; -int g_iTelemetry_Com_tty_id; +int g_iHostCom_tty_id = 0; +int g_iTelemetry_Com_tty_id = 0; int g_iEnableAlarmCode = true; bool g_bTelemetry_Open = true; bool g_bKeepExintRuning = false; @@ -20,30 +21,53 @@ 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); - if (!manager.isSectionExists("System-Setting")) return -1; - auto system_setting = manager["System-Setting"]; - auto host_com_path = system_setting["HostInfo_COM_Path"]; - auto host_com_baudrate = system_setting.toInt("HostInfo_COM_Baud_Rate"); - g_iHostCom_tty_id = get_com_tty_id(host_com_path.c_str(), host_com_baudrate); - g_iUseHostComForTelemetry = system_setting.toInt("Use_HostCOM_for_Telemetry"); + CCfgFileParser config; + if (config.parseFile(config_path) < 0) { + logger.error("read config file %s failed", config_path); + return -1; + } + const char* host_com_path = NULL; + if (!config.getValue("System-Setting", "HostInfo_COM_Path", host_com_path)) { + logger.error("fail to read [System-Setting]:HostInfo_ExchangeMode from %s", config_path); + } + long host_com_baudrate = 115200; + if (!config.getIntValue("System-Setting", "HostInfo_COM_Baud_Rate", host_com_baudrate)) { + logger.error("fail to read [System-Setting]:HostInfo_COM_Baud_Rate from %s", config_path); + } + if (host_com_path != NULL) + g_iHostCom_tty_id = get_com_tty_id(host_com_path, host_com_baudrate); - g_bTelemetry_Open = system_setting.toInt("Telemetry_Open") == 1; + long use_host_com_for_telemetry = 1; + if (!config.getIntValue("System-Setting", "Use_HostCOM_for_Telemetry", use_host_com_for_telemetry)) { + logger.error("fail to read [System-Setting]:Use_HostCOM_for_Telemetry from %s", config_path); + } + g_iUseHostComForTelemetry = use_host_com_for_telemetry == 1; + long telemetry_open = 1; + if (!config.getIntValue("System-Setting", "Telemetry_Open", telemetry_open)) { + logger.error("fail to read [System-Setting]:Telemetry_Open from %s", config_path); + } + g_bTelemetry_Open = telemetry_open == 1; if (g_bTelemetry_Open) { - auto telemetry_com_path = system_setting["Telemetry_COM_Path"]; - auto telemetry_com_baudrate = system_setting.toInt("Telemetry_COM_Baud_Rate"); - g_iTelemetry_Com_tty_id = get_com_tty_id(telemetry_com_path.c_str(), telemetry_com_baudrate); - + const char* telemetry_com_path = NULL; + if (!config.getValue("System-Setting", "Telemetry_COM_Path", telemetry_com_path)) { + logger.error("fail to read [System-Setting]:Telemetry_COM_Path from %s", config_path); + } + long telemetry_com_baudrate = 115200; + if (!config.getIntValue("System-Setting", "Telemetry_COM_Baud_Rate", telemetry_com_baudrate)) { + logger.error("fail to read [System-Setting]:Telemetry_COM_Baud_Rate from %s", config_path); + } + if (telemetry_com_path != NULL) + g_iTelemetry_Com_tty_id = get_com_tty_id(telemetry_com_path, telemetry_com_baudrate); } return 0; } -int exint_init(const char* config_path, et_callback_t cb) { +int exint_initialize(const char* config_path, et_callback_t cb) { if (read_config(config_path)) return -1; et_callback = cb; g_bKeepExintRuning = true; - pthread_create(&event_thread, NULL, exint_event_thread, NULL); + exint_event_thread_start(1); pthread_create(&upperhost_thread, NULL, upper_host_com_thread, NULL); pthread_create(&telemetry_thread, NULL, telemetry_host_com_thread, NULL); return 0; @@ -54,7 +78,7 @@ int exint_init_from_tty(int host_com_tty, int telemetry_com_tty, et_callback_t c g_iHostCom_tty_id = host_com_tty; g_iTelemetry_Com_tty_id = telemetry_com_tty; g_bKeepExintRuning = true; - pthread_create(&event_thread, NULL, exint_event_thread, NULL); + exint_event_thread_start(1); pthread_create(&upperhost_thread, NULL, upper_host_com_thread, NULL); pthread_create(&telemetry_thread, NULL, telemetry_host_com_thread, NULL); return 0; @@ -77,9 +101,9 @@ void exint_send(uint32_t type, size_t len, void* data) { void exint_finialize() { g_bKeepExintRuning = false; - pthread_cancel(event_thread); pthread_cancel(upperhost_thread); pthread_cancel(telemetry_thread); + exint_event_thread_stop(); } void exint_handle_pack(uint32_t type, size_t len, void* data) { diff --git a/src/handler/base.cpp b/src/handler/base.cpp new file mode 100644 index 0000000..cc18cb2 --- /dev/null +++ b/src/handler/base.cpp @@ -0,0 +1 @@ +#include "exint/handler.h" \ No newline at end of file diff --git a/src/host_com.cpp b/src/host_com.cpp index 92a5421..4fc030e 100644 --- a/src/host_com.cpp +++ b/src/host_com.cpp @@ -611,10 +611,10 @@ void send_command_upper_host(int length, void* payload) { 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) { + while (need_resend && g_bKeepExintRuning) { + gettimeofday(&tCurTime, NULL); + uint64_t tCurTimeMs = tCurTime.tv_sec * 1000 + tCurTime.tv_usec / 1000; if (sendtime == 0) { last_send_time = tCurTimeMs; @@ -678,3 +678,7 @@ void send_audio_upper_host(int length, void* payload) { ON_EVENT(send_command) { send_command_upper_host(args_size, args); } + +ON_EVENT(send_audio) { + send_audio_upper_host(args_size, args); +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d44bd1e..e0fe279 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,9 +1,5 @@ -cmake_minimum_required(VERSION 3.15) -project(test) - set(TESTS_DIR .) set(TEST_COMMON_SOURCE "${TESTS_DIR}/c_testcase.cpp") - file(GLOB_RECURSE TEST_FILES "${TESTS_DIR}/test_*.cpp") foreach(TEST_FILE ${TEST_FILES}) @@ -12,6 +8,9 @@ foreach(TEST_FILE ${TEST_FILES}) list(APPEND TEST_EXECUTABLES "${EXECUTABLE_OUTPUT_PATH}/${TEST_NAME}") endforeach() +# message(STATUS "Test files: ${TEST_FILES}") +# message(STATUS "Test executables: ${TEST_EXECUTABLES}") + add_custom_target(test COMMAND ${CMAKE_SOURCE_DIR}/scripts/unittest.py ${TEST_EXECUTABLES} DEPENDS ${TEST_EXECUTABLES} diff --git a/tests/test_event.cpp b/tests/test_event.cpp index d6fb147..196ecfe 100644 --- a/tests/test_event.cpp +++ b/tests/test_event.cpp @@ -14,13 +14,11 @@ ON_EVENT(test) { SETUP { g_vec.clear(); - g_bKeepExintRuning = true; return 0; } TEARDOWN { - g_bKeepExintRuning = false; - exint_event_thread_exit(); + exint_event_thread_stop(); return 0; } @@ -38,15 +36,7 @@ TEST_CASE(test_event) { } TEST_CASE(test_event_thread) { - bool started = false; - std::thread t([&]() { - started = true; - exint_event_thread(NULL); - }); - t.detach(); - while (!started) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } + exint_event_thread_start(2); int i = 2; exint_event("test", sizeof(int), &i); for (int i = 0; i < 10; i++) { @@ -60,5 +50,6 @@ TEST_CASE(test_event_thread) { assert(false); end: + exint_event_thread_stop(); END_TEST; } diff --git a/toolchains/armv7l_linux_setup.cmake b/toolchains/armv7l_linux_setup.cmake index a8b8fec..6f003e2 100644 --- a/toolchains/armv7l_linux_setup.cmake +++ b/toolchains/armv7l_linux_setup.cmake @@ -1,5 +1,7 @@ set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) -set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc-9) -set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++-9) +set(CMAKE_C_COMPILER arm-none-linux-gnueabihf-gcc) +set(CMAKE_CXX_COMPILER arm-none-linux-gnueabihf-g++) + +# set(CMAKE_CXX_FLAGS "-static ${CMAKE_CXX_FLAGS}")