diff --git a/doc/design.md b/doc/design.md index b1b6ad3..8282142 100644 --- a/doc/design.md +++ b/doc/design.md @@ -138,6 +138,7 @@ loop 光敏检测 小核 ->> 小核:ircut切换-消耗0ms 小核 ->> 小核:Sensor初始化 小核 --> 大核:Sensor初始化完成-100ms + deactivate 小核 activate 大核 大核 ->> 大核:内核快启抓拍(1P/3P)-200ms 大核 ->> 大核:内核启动(文件系统/挂载sd卡)-?ms @@ -156,7 +157,6 @@ loop 光敏检测 大核 ->> MCU:关机 MCU ->> 大核:断电 end - deactivate 小核 deactivate 大核 end end @@ -190,6 +190,7 @@ opt PIR信号触发 小核 ->> 小核:ircut切换-消耗0ms 小核 ->> 小核:Sensor初始化 小核 --> 大核:Sensor初始化完成-100ms + deactivate 小核 activate 大核 大核 ->> 大核:内核快启抓拍(1P/3P)-200ms 大核 ->> 大核:内核启动(文件系统/挂载sd卡)-?ms @@ -223,7 +224,6 @@ opt PIR信号触发 MCU ->> 大核:断电 end end - deactivate 小核 deactivate 大核 else 主控已经开机 MCU ->> +大核:发送抓拍指令 @@ -257,6 +257,7 @@ opt 根据定时参数上电 小核 ->> 小核:ircut切换-消耗0ms 小核 ->> 小核:Sensor初始化 小核 --> 大核:Sensor初始化完成-100ms + deactivate 小核 activate 大核 大核 ->> 大核:内核快启抓拍(1P/3P)-200ms 大核 ->> 大核:内核启动(文件系统/挂载sd卡)-?ms @@ -283,7 +284,6 @@ opt 根据定时参数上电 大核 ->> MCU:关机 MCU ->> 小核:断电 MCU ->> 大核:断电 - deactivate 小核 deactivate 大核 end ``` @@ -315,6 +315,7 @@ opt TEST拨键-ON 小核 ->> 小核:ircut切换-消耗0ms 小核 ->> 小核:Sensor初始化 小核 --> 大核:Sensor初始化完成-100ms + deactivate 小核 大核 ->> 大核:内核启动(文件系统/挂载sd卡)-?ms 大核 ->> 大核:启动脚本启动APP-?ms 大核 ->> +MCU:获取启动模式 @@ -339,7 +340,6 @@ opt TEST拨键-ON end end end - deactivate 小核 deactivate 大核 end ``` @@ -362,6 +362,7 @@ MCU ->> 小核:上电 activate 大核 小核 ->> 小核:Sensor初始化 小核 --> 大核:Sensor初始化完成-100ms + deactivate 小核 大核 ->> 大核:内核启动(文件系统/挂载sd卡)-?ms 大核 ->> 大核:启动脚本启动APP-?ms alt TEST拨键-ON @@ -383,7 +384,6 @@ MCU ->> 小核:上电 MCU ->> 大核:断电 end end - deactivate 小核 deactivate 大核 ``` @@ -528,9 +528,97 @@ end ###### 1.4.3.2.5.1. 协议格式 -| 协议头 | 命令字 | 长度 | 数据段 | 校验位 | 协议尾 | -|----|----|----|----|----|----| -| 2字节
0xFAC1 | 2字节 | 2字节 | - | - | 2字节
0xFAC9 | +| 协议头 | 命令字 | 长度 | 数据段 | 校验码 | +|----|----|----|----|----| +| 2字节
0xFAC1 | 2字节 | 2字节 | - | 2字节 | + + +**校验码算法** + +   校验码算法使用ModBus CRC16方法计算。 +**参考代码(查表法)** + +``` +/* Table of CRC values for high–order byte */ +unsigned char chCRCHi[] ={ + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 +}; + +/* Table of CRC values for low–order byte */ +unsigned char chCRCLo[] ={ + 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, + 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, + 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, + 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, + 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, + 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, + 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, + 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, + 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, + 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, + 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, + 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, + 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, + 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, + 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, + 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, + 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, + 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, + 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, + 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, + 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, + 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, + 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, + 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, + 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, + 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 +}; +/** + * @brief 计算校验和 + * + * @param pData 数据指针 + * @param length 数据长度 + * @return unsigned short + */ +unsigned short Calculate_Check_Sum(const unsigned char* pData, unsigned short length) +{ + unsigned char CRCHi = 0xFF; + unsigned char CRCLo = 0xFF; + int uIndex; + while (length--) + { + uIndex = CRCHi ^ *pData++; + CRCHi = CRCLo ^ chCRCHi[uIndex]; + CRCLo = chCRCLo[uIndex]; + } + return (CRCHi << 8 | CRCLo); +} +``` ###### 1.4.3.2.5.2. 协议内容 @@ -556,7 +644,7 @@ end | 0x8108 | ask | - | Data[0]:灵敏度
0-9 | 设置PIR灵敏度 | - | | 0x0108 | - | reply | Data[0]:结果
0x01:成功
0x02:失败 | 设置PIR灵敏度回复 | - | | 0x8109 | ask | - | Data[0]:Hour
0-23
Data[1]:Min
0-59
Data[2]:Sec
0-59 | 设置连拍间隔 | - | -| 0x0108 | - | reply | Data[0]:结果
0x01:成功
0x02:失败 | 设置连拍间隔回复 | - | +| 0x0109 | - | reply | Data[0]:结果
0x01:成功
0x02:失败 | 设置连拍间隔回复 | - | ##### 1.4.3.2.6. IPC配置库 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4a4fa27..6fe33be 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,8 +1,5 @@ # cmake_minimum_required(VERSION 2.8.0) -# Mock Linux api. -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_LINUX_MOCK}") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TEST_LINUX_MOCK}") # Compile gtest for test code. execute_process(COMMAND sh build_gtest.sh ${TARGET_PLATFORM} ${PLATFORM_PATH} ${PLATFORM_PATH} WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/) execute_process(COMMAND mv ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/lib/libgtest.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libgtest.a @@ -10,6 +7,26 @@ execute_process(COMMAND mv ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11 execute_process(COMMAND mv ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/lib/libgmock.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libgmock.a WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/) +if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) + message("linux mock api will be set.") + set(TEST_LINUX_MOCK "-Wl,--wrap=fx_open" CACHE STRING INTERNAL FORCE) + # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=tcgetattr" CACHE STRING INTERNAL FORCE) + # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=tcsetattr" CACHE STRING INTERNAL FORCE) + # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=gethostbyname" CACHE STRING INTERNAL FORCE) + # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=connect" CACHE STRING INTERNAL FORCE) + # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=socket" CACHE STRING INTERNAL FORCE) + # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=select" CACHE STRING INTERNAL FORCE) + # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_open" CACHE STRING INTERNAL FORCE) + # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_read" CACHE STRING INTERNAL FORCE) + # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_write" CACHE STRING INTERNAL FORCE) + # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_close" CACHE STRING INTERNAL FORCE) + # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_fclose" CACHE STRING INTERNAL FORCE) + # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_fread" CACHE STRING INTERNAL FORCE) + # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_fcntl" CACHE STRING INTERNAL FORCE) +endif() +# Mock Linux api. +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_LINUX_MOCK}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TEST_LINUX_MOCK}") # build gtest and gmock # add_custom_command( # OUTPUT ${EXTERNAL_LIBS_OUTPUT_PATH}/libgtest.a diff --git a/test/utils/CMakeLists.txt b/test/utils/CMakeLists.txt index e6841d8..e9b8df2 100644 --- a/test/utils/CMakeLists.txt +++ b/test/utils/CMakeLists.txt @@ -3,5 +3,7 @@ add_subdirectory(Config) add_subdirectory(Log) add_subdirectory(SharedData) add_subdirectory(WebServer) +add_subdirectory(UartDevice) +add_subdirectory(LinuxApiMock) diff --git a/test/utils/LinuxApiMock/CMakeLists.txt b/test/utils/LinuxApiMock/CMakeLists.txt new file mode 100644 index 0000000..224f22b --- /dev/null +++ b/test/utils/LinuxApiMock/CMakeLists.txt @@ -0,0 +1,52 @@ +include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake) +set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH}) +set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH}) + +include_directories( + ./src + ./include + ${UTILS_SOURCE_PATH}/Log/include +) +# link_directories( +# ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs +# ) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +aux_source_directory(./src SRC_FILES) + +set(TARGET_NAME LinuxApiMock) +add_library(${TARGET_NAME} STATIC ${SRC_FILES}) +target_link_libraries(${TARGET_NAME} Log) + +if ("${CLANG_TIDY_SUPPORT}" MATCHES "true") +add_custom_target( + LinuxApiMock_code_check + COMMAND ${CLANG_TIDY_EXE} + -checks='${CLANG_TIDY_CHECKS}' + --header-filter=.* + --system-headers=false + ${SRC_FILES} + ${CLANG_TIDY_CONFIG} + -p ${PLATFORM_PATH}/cmake-shell + WORKING_DIRECTORY ${TEST_SOURCE_PATH}/utils/LinuxApiMock +) +file(GLOB_RECURSE HEADER_FILES *.h) +add_custom_target( + LinuxApiMock_code_format + COMMAND ${CLANG_FORMAT_EXE} + -style=file + -i ${SRC_FILES} ${HEADER_FILES} + WORKING_DIRECTORY ${TEST_SOURCE_PATH}/utils/LinuxApiMock +) +add_custom_command( + TARGET ${TARGET_NAME} + PRE_BUILD + COMMAND make LinuxApiMock_code_check + COMMAND make LinuxApiMock_code_format + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ +) +endif() + +define_file_name(${TARGET_NAME}) \ No newline at end of file diff --git a/test/utils/LinuxApiMock/README.md b/test/utils/LinuxApiMock/README.md new file mode 100644 index 0000000..8ab3986 --- /dev/null +++ b/test/utils/LinuxApiMock/README.md @@ -0,0 +1,3 @@ +# 1. Linux 系统函数模拟接口 + +   为了方便在ubuntu系统进行代码的调试运行,对Linux标准函数进行多态转换。 \ No newline at end of file diff --git a/test/utils/LinuxApiMock/include/LinuxApiMock.h b/test/utils/LinuxApiMock/include/LinuxApiMock.h new file mode 100644 index 0000000..6329ca3 --- /dev/null +++ b/test/utils/LinuxApiMock/include/LinuxApiMock.h @@ -0,0 +1,30 @@ +#ifndef LINUX_API_MOCK_H +#define LINUX_API_MOCK_H +#include +#ifdef __cplusplus +extern "C" { +#endif +// Modify all the real api. +int __real_fx_open(const char *pathname, int flags); +#ifdef __cplusplus +} +#endif +class LinuxApiMock +{ +public: + LinuxApiMock() = default; + virtual ~LinuxApiMock() = default; + static std::shared_ptr &GetInstance(std::shared_ptr *impl = nullptr) + { + static auto instance = std::make_shared(); + if (impl) { + // The non-thread-safe changing is only for gtest. + instance = *impl; + } + return instance; + } + virtual void Init() {} + virtual void UnInit() {} + virtual int fx_open(const char *pathname, int flags); +}; +#endif \ No newline at end of file diff --git a/test/utils/LinuxApiMock/src/LinuxApiMock.cpp b/test/utils/LinuxApiMock/src/LinuxApiMock.cpp new file mode 100644 index 0000000..9b91dfb --- /dev/null +++ b/test/utils/LinuxApiMock/src/LinuxApiMock.cpp @@ -0,0 +1,10 @@ +#include "LinuxApiMock.h" +#ifdef __cplusplus +extern "C" { +#endif +// Modify all the wrap api. +int __wrap_fx_open(const char *pathname, int flags) { return LinuxApiMock::GetInstance()->fx_open(pathname, flags); } +#ifdef __cplusplus +} +#endif +int LinuxApiMock::fx_open(const char *pathname, int flags) { return __real_fx_open(pathname, flags); } \ No newline at end of file diff --git a/test/utils/SharedData/mainTest.cpp b/test/utils/SharedData/mainTest.cpp index fb1d91b..475ceee 100644 --- a/test/utils/SharedData/mainTest.cpp +++ b/test/utils/SharedData/mainTest.cpp @@ -1,3 +1,17 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include #include #include diff --git a/test/utils/SharedData/src/SharedData_Test.cpp b/test/utils/SharedData/src/SharedData_Test.cpp index 6ce7efd..b419d96 100644 --- a/test/utils/SharedData/src/SharedData_Test.cpp +++ b/test/utils/SharedData/src/SharedData_Test.cpp @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "SharedData.h" #include "ILog.h" +#include "SharedData.h" #include #include namespace SharedDataTest diff --git a/test/utils/UartDevice/CMakeLists.txt b/test/utils/UartDevice/CMakeLists.txt new file mode 100644 index 0000000..cb485d8 --- /dev/null +++ b/test/utils/UartDevice/CMakeLists.txt @@ -0,0 +1,71 @@ +# include(${CMAKE_SOURCE_DIR}/build/independent_source.cmake) +include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake) +set(EXECUTABLE_OUTPUT_PATH ${TEST_OUTPUT_PATH}/bin) + +include_directories( + ${UTILS_SOURCE_PATH}/StatusCode/include + ${UTILS_SOURCE_PATH}/Log/include + ${UTILS_SOURCE_PATH}/UartDevice/include + ${TEST_SOURCE_PATH}/utils/LinuxApiMock/include + ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include + ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/include +) + +link_directories( + ${LIBS_OUTPUT_PATH} + ${EXTERNAL_LIBS_OUTPUT_PATH} +) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +aux_source_directory(. SRC_FILES) +aux_source_directory(./src SRC_FILES) +if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) + aux_source_directory(./src_mock SRC_FILES) +endif() + +set(TARGET_NAME UartDeviceTest) +add_executable(${TARGET_NAME} ${SRC_FILES}) +target_link_libraries(${TARGET_NAME} UartDevice gtest gmock pthread Log) +if(${TEST_COVERAGE} MATCHES "true") + target_link_libraries(${TARGET_NAME} gcov) +endif() +if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) + target_link_libraries(${TARGET_NAME} LinuxApiMock) +endif() +if ("${CLANG_TIDY_SUPPORT}" MATCHES "true") +add_custom_target( + UartDeviceTest_code_check + COMMAND ${CLANG_TIDY_EXE} + -checks='${CLANG_TIDY_CHECKS}' + --header-filter=.* + --system-headers=false + ${SRC_FILES} + ${CLANG_TIDY_CONFIG} + # --line-filter='[{\"name\":\"${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include/getest/gtest.h\"}]' + --line-filter='[{\"name\":\"${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include/getest/*.h\"}]' + -p ${PLATFORM_PATH}/cmake-shell + WORKING_DIRECTORY ${TEST_SOURCE_PATH}/utils/UartDevice +) +file(GLOB_RECURSE HEADER_FILES *.h) +add_custom_target( + UartDeviceTest_code_format + COMMAND ${CLANG_FORMAT_EXE} + -style=file + -i ${SRC_FILES} ${HEADER_FILES} + WORKING_DIRECTORY ${TEST_SOURCE_PATH}/utils/UartDevice +) +add_custom_command( + TARGET ${TARGET_NAME} + PRE_BUILD + COMMAND make UartDeviceTest_code_check + COMMAND make UartDeviceTest_code_format + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ +) +endif() + +define_file_name(${TARGET_NAME}) \ No newline at end of file diff --git a/test/utils/UartDevice/mainTest.cpp b/test/utils/UartDevice/mainTest.cpp new file mode 100644 index 0000000..475ceee --- /dev/null +++ b/test/utils/UartDevice/mainTest.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +int main(int argc, char *argv[]) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/test/utils/UartDevice/src/UartDevice_Test.cpp b/test/utils/UartDevice/src/UartDevice_Test.cpp new file mode 100644 index 0000000..68b5ef2 --- /dev/null +++ b/test/utils/UartDevice/src/UartDevice_Test.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "ILog.h" +#include "UartDevice.h" +#include +#include +namespace UartDeviceTest +{ +// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceTest.IllegalObject +/** + * UartDevice module api will not crash when object is illegal. + */ +TEST(UartDeviceTest, IllegalObject) +{ + CreateLogModule(); + ILogInit(LOG_INSTANCE_TYPE_END); + IUartOpen(nullptr); + IUartSend(nullptr, nullptr, 0); + IUartRecv(nullptr, nullptr, 0, 0); + IUartTcflush(nullptr); + IUartDeviceFree(nullptr); + int illegalObject = 0; + void *object = &illegalObject; + IUartOpen(object); + IUartSend(object, nullptr, 0); + IUartRecv(object, nullptr, 0, 0); + IUartTcflush(object); + IUartDeviceFree(object); + ILogUnInit(); +} +// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceTest.Demo +TEST(UartDeviceTest, Demo) +{ + CreateLogModule(); + ILogInit(LOG_INSTANCE_TYPE_END); + uart_info device = { + "dev/s1", + }; + void *object = CreateUartDevice(device); + IUartOpen(object); + // IUartSend(object, nullptr, 0); + // IUartRecv(object, nullptr, 0, 0); + // IUartTcflush(object); + IUartDeviceFree(object); + ILogUnInit(); +} +} // namespace UartDeviceTest \ No newline at end of file diff --git a/test/utils/UartDevice/src_mock/UartDevice_Mock_Test.cpp b/test/utils/UartDevice/src_mock/UartDevice_Mock_Test.cpp new file mode 100644 index 0000000..3142843 --- /dev/null +++ b/test/utils/UartDevice/src_mock/UartDevice_Mock_Test.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "ILog.h" +#include "LinuxApiMock.h" +#include "UartDevice.h" +#include +#include +namespace UartDeviceMockTest +{ +class LinuxApiMockTest : public LinuxApiMock +{ +public: + LinuxApiMockTest() = default; + virtual ~LinuxApiMockTest() = default; + MOCK_METHOD2(fx_open, int(const char *, int)); +}; +class UartDeviceMockTest : public testing::Test +{ +public: + UartDeviceMockTest() {} + virtual ~UartDeviceMockTest() {} + static void SetUpTestCase() + { + CreateLogModule(); + ILogInit(LOG_INSTANCE_TYPE_END); + } + static void TearDownTestCase() { ILogUnInit(); } + virtual void SetUp() {} + virtual void TearDown() {} +}; +// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.Demo +TEST_F(UartDeviceMockTest, Demo) +{ + const char *deviceName = "dev/s1"; + uart_info device = { + deviceName, + 1152000, + 'N', + 8, + 1, + 'N', + }; + std::shared_ptr tmp = std::make_shared(); + std::shared_ptr test = tmp; + LinuxApiMock::GetInstance(&test); + EXPECT_CALL(*tmp.get(), fx_open(deviceName, ::testing::_)) + .WillRepeatedly(::testing::DoAll((::testing::Return(1000000000)))); + void *object = CreateUartDevice(device); + IUartOpen(object); + // IUartSend(object, nullptr, 0); + // IUartRecv(object, nullptr, 0, 0); + // IUartTcflush(object); + IUartDeviceFree(object); +} +} // namespace UartDeviceMockTest \ No newline at end of file diff --git a/utils/LinuxApi/include/LinuxApi.h b/utils/LinuxApi/include/LinuxApi.h index db9c6dc..c367562 100644 --- a/utils/LinuxApi/include/LinuxApi.h +++ b/utils/LinuxApi/include/LinuxApi.h @@ -17,7 +17,8 @@ #ifdef __cplusplus extern "C" { #endif -int FX_system(const char *command); +int fx_system(const char *command); +int fx_open(const char *pathname, int flags); #ifdef __cplusplus } #endif diff --git a/utils/LinuxApi/src/LinuxApi.c b/utils/LinuxApi/src/LinuxApi.c index daca257..bb565c7 100644 --- a/utils/LinuxApi/src/LinuxApi.c +++ b/utils/LinuxApi/src/LinuxApi.c @@ -13,5 +13,14 @@ * limitations under the License. */ #include "LinuxApi.h" +#include +#include +#include #include -int FX_system(const char *command) { return system(command); } \ No newline at end of file +#include +#include +#include +#include + +int fx_system(const char *command) { return system(command); } +int fx_open(const char *pathname, int flags) { return open(pathname, flags); } \ No newline at end of file diff --git a/utils/SharedData/src/SharedMemory.cpp b/utils/SharedData/src/SharedMemory.cpp index 549063b..0f18784 100644 --- a/utils/SharedData/src/SharedMemory.cpp +++ b/utils/SharedData/src/SharedMemory.cpp @@ -33,7 +33,7 @@ StatusCode SharedMemory::MakeSharedMemory(const int &size) char touchPath[128] = {0}; if (access(mPath, F_OK) != 0) { sprintf(touchPath, "%s %s", "touch", mPath); - FX_system(touchPath); + fx_system(touchPath); } key_t key = ftok(mPath, mProjectId); if (key < 0) { diff --git a/utils/UartDevice/CMakeLists.txt b/utils/UartDevice/CMakeLists.txt index 811d8b6..66bbeff 100644 --- a/utils/UartDevice/CMakeLists.txt +++ b/utils/UartDevice/CMakeLists.txt @@ -5,6 +5,7 @@ set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH}) include_directories( ./src ./include + ${UTILS_SOURCE_PATH}/LinuxApi/include ${UTILS_SOURCE_PATH}/StatusCode/include ${UTILS_SOURCE_PATH}/Log/include ) @@ -19,7 +20,7 @@ aux_source_directory(./src SRC_FILES) set(TARGET_NAME UartDevice) add_library(${TARGET_NAME} STATIC ${SRC_FILES}) -target_link_libraries(${TARGET_NAME} StatusCode Log) +target_link_libraries(${TARGET_NAME} LinuxApi StatusCode Log) if ("${CLANG_TIDY_SUPPORT}" MATCHES "true") add_custom_target( diff --git a/utils/UartDevice/include/UartDevice.h b/utils/UartDevice/include/UartDevice.h index cc761dc..0a61094 100644 --- a/utils/UartDevice/include/UartDevice.h +++ b/utils/UartDevice/include/UartDevice.h @@ -28,28 +28,12 @@ typedef struct uart_info const int mStopBits; const int mParity; } UartInfo; -typedef struct uart_device UartDevice; -typedef struct uart_device -{ - const StatusCode (*mOpen)(UartDevice *); - const size_t (*mSend)(UartDevice *, const char *, const size_t); - const size_t (*mRecv)(UartDevice *, char *, const size_t, const unsigned int); - void (*mTcflush)(UartDevice *); - void (*mFree)(void *); -} UartDevice; -UartDevice *CreateUartDevice(const UartInfo info); -static inline const StatusCode IUartOpen(UartDevice *object) { return object->mOpen(object); } -static inline const size_t IUartSend(UartDevice *object, const char *buff, const size_t buffLength) -{ - return object->mSend(object, buff, buffLength); -} -static inline const size_t IUartRecv(UartDevice *object, char *buff, const size_t buffLength, - const unsigned int timeoutMs) -{ - return object->mRecv(object, buff, buffLength, timeoutMs); -} -static inline void IUartTcflush(UartDevice *object) { return object->mTcflush(object); } -static inline void IUartDeviceFree(UartDevice *object) { object->mFree(object); } +void *CreateUartDevice(const UartInfo info); +const StatusCode IUartOpen(void *object); +const size_t IUartSend(void *object, const char *buff, const size_t buffLength); +const size_t IUartRecv(void *object, char *buff, const size_t buffLength, const unsigned int timeoutMs); +void IUartTcflush(void *object); +void IUartDeviceFree(void *object); #ifdef __cplusplus } #endif diff --git a/utils/UartDevice/src/UartDevice.cpp b/utils/UartDevice/src/UartDevice.cpp index 6c31106..e4f10f8 100644 --- a/utils/UartDevice/src/UartDevice.cpp +++ b/utils/UartDevice/src/UartDevice.cpp @@ -13,5 +13,67 @@ * limitations under the License. */ #include "UartDevice.h" +#include "ILog.h" +#include "StatusCode.h" #include "UartDeviceImpl.h" -UartDevice *CreateUartDevice(const UartInfo info) { return NewUartDeviceImpl(info); } \ No newline at end of file +void *CreateUartDevice(const UartInfo info) { return NewUartDeviceImpl(info); } +const StatusCode IUartOpen(void *object) +{ + if (nullptr == object) { + LogError("nullptr object!\n"); + return CreateStatusCode(STATUS_CODE_NOT_OK); + } + if (*((const char **)(((char *)object) - sizeof(UartDeviceHeader))) != GetUartDeviceModuleName()) { + LogError("Illegal object!\n"); + return CreateStatusCode(STATUS_CODE_NOT_OK); + } + return ((UartDevice *)object)->mOpen((UartDevice *)object); +} +const size_t IUartSend(void *object, const char *buff, const size_t buffLength) +{ + if (nullptr == object) { + LogError("nullptr object!\n"); + return 0; + } + if (*((const char **)(((char *)object) - sizeof(UartDeviceHeader))) != GetUartDeviceModuleName()) { + LogError("Illegal object!\n"); + return 0; + } + return ((UartDevice *)object)->mSend((UartDevice *)object, buff, buffLength); +} +const size_t IUartRecv(void *object, char *buff, const size_t buffLength, const unsigned int timeoutMs) +{ + if (nullptr == object) { + LogError("nullptr object!\n"); + return 0; + } + if (*((const char **)(((char *)object) - sizeof(UartDeviceHeader))) != GetUartDeviceModuleName()) { + LogError("Illegal object!\n"); + return 0; + } + return ((UartDevice *)object)->mRecv((UartDevice *)object, buff, buffLength, timeoutMs); +} +void IUartTcflush(void *object) +{ + if (nullptr == object) { + LogError("nullptr object!\n"); + return; + } + if (*((const char **)(((char *)object) - sizeof(UartDeviceHeader))) != GetUartDeviceModuleName()) { + LogError("Illegal object!\n"); + return; + } + ((UartDevice *)object)->mTcflush((UartDevice *)object); +} +void IUartDeviceFree(void *object) +{ + if (nullptr == object) { + LogError("nullptr object!\n"); + return; + } + if (*((const char **)(((char *)object) - sizeof(UartDeviceHeader))) != GetUartDeviceModuleName()) { + LogError("Illegal object!\n"); + return; + } + ((UartDevice *)object)->mFree((UartDevice *)object); +} \ No newline at end of file diff --git a/utils/UartDevice/src/UartDeviceImpl.cpp b/utils/UartDevice/src/UartDeviceImpl.cpp index 4ad6878..cb1aa05 100644 --- a/utils/UartDevice/src/UartDeviceImpl.cpp +++ b/utils/UartDevice/src/UartDeviceImpl.cpp @@ -14,6 +14,7 @@ */ #include "UartDeviceImpl.h" #include "ILog.h" +#include "LinuxApi.h" #include #include #include @@ -24,10 +25,11 @@ #include constexpr int INVALID_FD = -1; static const char *UART_DEVICE_NAME = "uart_device"; +const char *GetUartDeviceModuleName(void) { return UART_DEVICE_NAME; } UartDeviceImpl::UartDeviceImpl(const UartInfo &uatrInfo) : mUatrInfo(uatrInfo) { mFd = -1; } const StatusCode UartDeviceImpl::UartOpen(void) { - mFd = open(mUatrInfo.mDevice, O_RDWR | O_NOCTTY | O_NONBLOCK); + mFd = fx_open(mUatrInfo.mDevice, O_RDWR | O_NOCTTY | O_NONBLOCK); if (INVALID_FD == mFd) { perror("Can't Open Serial Port"); return CreateStatusCode(STATUS_CODE_NOT_OK); @@ -148,7 +150,7 @@ const StatusCode UartDeviceImpl::SetConfig(void) options.c_cflag |= CS8; break; default: - fprintf(stderr, "Unsupported data size\n"); + LogError("Unsupported data size\n"); return CreateStatusCode(STATUS_CODE_NOT_OK); } @@ -242,6 +244,7 @@ static void UartImpllFree(void *ptr) } UartDevice *NewUartDeviceImpl(const UartInfo &uartInfo) { + LogInfo("Create the uart device object.\n"); UartDeviceImpl_S *impl = (UartDeviceImpl_S *)malloc(sizeof(UartDeviceImpl_S)); UartDeviceImpl_S tmp; memcpy((void *)impl, (void *)&tmp, sizeof(UartDeviceImpl_S)); diff --git a/utils/UartDevice/src/UartDeviceImpl.h b/utils/UartDevice/src/UartDeviceImpl.h index b240b92..b6f4bae 100644 --- a/utils/UartDevice/src/UartDeviceImpl.h +++ b/utils/UartDevice/src/UartDeviceImpl.h @@ -41,6 +41,15 @@ private: const UartInfo mUatrInfo; int mFd; }; +typedef struct uart_device UartDevice; +typedef struct uart_device +{ + const StatusCode (*mOpen)(UartDevice *); + const size_t (*mSend)(UartDevice *, const char *, const size_t); + const size_t (*mRecv)(UartDevice *, char *, const size_t, const unsigned int); + void (*mTcflush)(UartDevice *); + void (*mFree)(void *); +} UartDevice; typedef struct uart_device_impl UartDeviceImpl_S; typedef struct uart_device_impl { @@ -53,4 +62,5 @@ static inline UartDeviceImpl_S *UartDeviceImplConvert(UartDevice *object) { return ((UartDeviceImpl_S *)(((char *)object) - sizeof(UartDeviceHeader))); } +const char *GetUartDeviceModuleName(void); #endif \ No newline at end of file