From 63bcd37b66158fa71f04f07e1f9a21ddf69e6146 Mon Sep 17 00:00:00 2001 From: Fancy code <258828110.@qq.com> Date: Fri, 9 Feb 2024 00:08:56 -0800 Subject: [PATCH] Add:Set feeding cycle for watch dog. --- doc/design.md | 15 ++- middleware/McuManager/include/IMcuManager.h | 9 +- middleware/McuManager/src/McuDevice.cpp | 16 +++ middleware/McuManager/src/McuDevice.h | 1 + middleware/McuManager/src/McuManagerImpl.cpp | 6 + middleware/McuManager/src/McuManagerImpl.h | 2 + .../src_mock/McuManager_Mock_Test.cpp | 112 ++++++++++++++++++ .../tool/include/McuProtocolTestTool.h | 2 + .../tool/src/McuProtocolTestTool.cpp | 62 +++++++++- utils/McuProtocol/include/McuProtocol.h | 10 ++ utils/McuProtocol/src/McuProtocol.cpp | 11 ++ utils/McuProtocol/src/ProtocolHandle.cpp | 62 +++++++++- utils/McuProtocol/src/ProtocolHandle.h | 18 +++ 13 files changed, 311 insertions(+), 15 deletions(-) diff --git a/doc/design.md b/doc/design.md index cda152e..847d3b3 100644 --- a/doc/design.md +++ b/doc/design.md @@ -528,14 +528,23 @@ end ###### 1.4.3.2.5.1. 协议格式 -| 协议头 | 命令字 | 长度 | 数据段 | 校验码 | -|----|----|----|----|----| -| 2字节
0xFAC1 | 2字节 | 2字节 | - | 2字节 | +| 协议头 | 流水号 | 命令字 | 长度 | 数据段 | 校验码 | +|----|----|----|----|----|----| +| 2字节
0xFAC1 | 4字节 | 2字节 | 2字节 | - | 2字节 | +**流水号** + +   流水号用于强绑定问答型协议的发送数据和回复数据,回复者原数据回传即可。例如: + +``` +unsigned char ASK_IPC_MISSION[] = {0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x0C, 0x71, 0x88}; +unsigned char REPLY_IPC_MISSION[] = {0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x0D, 0x01, 0xAA, 0x89}; +``` **校验码算法**    校验码算法使用ModBus CRC16方法计算。 + **参考代码(查表法)** ``` diff --git a/middleware/McuManager/include/IMcuManager.h b/middleware/McuManager/include/IMcuManager.h index 7e59f83..c3908ad 100644 --- a/middleware/McuManager/include/IMcuManager.h +++ b/middleware/McuManager/include/IMcuManager.h @@ -25,9 +25,9 @@ enum class IpcMission }; enum class ASK_RESULT { - SUCCEED = 0, - TIMEOUT, + SUCCEED = 1, FAILED, + TIMEOUT, END }; class VMcuAsk @@ -89,5 +89,10 @@ public: { return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); } + virtual const StatusCode SetFeedingCycleForWatchDog(std::shared_ptr &ask, const unsigned char &hour, + const unsigned char &min, const unsigned char &second) + { + return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); + } }; #endif \ No newline at end of file diff --git a/middleware/McuManager/src/McuDevice.cpp b/middleware/McuManager/src/McuDevice.cpp index 68f84bd..c7c250d 100644 --- a/middleware/McuManager/src/McuDevice.cpp +++ b/middleware/McuManager/src/McuDevice.cpp @@ -109,6 +109,22 @@ void McuDevice::GetIpcMissionReply(const unsigned int &serialNumber, const unsig DeleteMcuAsk(ask); } } +void McuDevice::SetFeedingCycleForWatchDogReply(const unsigned int &serialNumber, const ReplyResult &result) +{ + std::shared_ptr ask; + SearchMcuAsk(serialNumber, ask); + if (ask) { + std::shared_ptr> realAsk = std::dynamic_pointer_cast>(ask); + if (realAsk) { + realAsk->mDataReply = static_cast(result); + ask->ReplyFinished(true); + } + else { + ask->ReplyFinished(false); + } + DeleteMcuAsk(ask); + } +} void McuDevice::DeviceRecvThread(void) { constexpr int RECV_TIMEOUT_MS = 1000; diff --git a/middleware/McuManager/src/McuDevice.h b/middleware/McuManager/src/McuDevice.h index 1bff0bf..71321c9 100644 --- a/middleware/McuManager/src/McuDevice.h +++ b/middleware/McuManager/src/McuDevice.h @@ -34,6 +34,7 @@ public: public: void GetIpcMissionReply(const unsigned int &serialNumber, const unsigned char &mission) override; + void SetFeedingCycleForWatchDogReply(const unsigned int &serialNumber, const ReplyResult &result) override; public: void DeviceRecvThread(void); diff --git a/middleware/McuManager/src/McuManagerImpl.cpp b/middleware/McuManager/src/McuManagerImpl.cpp index eb978ce..4f2cddd 100644 --- a/middleware/McuManager/src/McuManagerImpl.cpp +++ b/middleware/McuManager/src/McuManagerImpl.cpp @@ -40,4 +40,10 @@ const StatusCode McuManagerImpl::FeedWatchDog(std::shared_ptr &ask) { std::shared_ptr context = std::make_shared>>(ask); return McuProtocol::FeedWatchDog(context); +} +const StatusCode McuManagerImpl::SetFeedingCycleForWatchDog(std::shared_ptr &ask, const unsigned char &hour, + const unsigned char &min, const unsigned char &second) +{ + std::shared_ptr context = std::make_shared>>(ask); + return McuProtocol::SetFeedingCycleForWatchDog(hour, min, second, context); } \ No newline at end of file diff --git a/middleware/McuManager/src/McuManagerImpl.h b/middleware/McuManager/src/McuManagerImpl.h index 27477cd..def9b78 100644 --- a/middleware/McuManager/src/McuManagerImpl.h +++ b/middleware/McuManager/src/McuManagerImpl.h @@ -28,5 +28,7 @@ public: const StatusCode GetIpcMission(std::shared_ptr &ask) override; const StatusCode CutOffPowerSupply(std::shared_ptr &ask) override; const StatusCode FeedWatchDog(std::shared_ptr &ask) override; + const StatusCode SetFeedingCycleForWatchDog(std::shared_ptr &ask, const unsigned char &hour, + const unsigned char &min, const unsigned char &second) override; }; #endif \ No newline at end of file diff --git a/test/middleware/McuManager/src_mock/McuManager_Mock_Test.cpp b/test/middleware/McuManager/src_mock/McuManager_Mock_Test.cpp index 9fc04fd..9218481 100644 --- a/test/middleware/McuManager/src_mock/McuManager_Mock_Test.cpp +++ b/test/middleware/McuManager/src_mock/McuManager_Mock_Test.cpp @@ -159,6 +159,25 @@ TEST_F(McuManagerMockTest, INTEGRATION_McuManager_EXAMPLE_FeedWatchDog) IMcuManager::GetInstance()->UnInit(); } // ../output_files/test/bin/McuManagerTest +// --gtest_filter=McuManagerMockTest.INTEGRATION_McuManager_EXAMPLE_SetFeedingCycleForWatchDog +TEST_F(McuManagerMockTest, INTEGRATION_McuManager_EXAMPLE_SetFeedingCycleForWatchDog) +{ + class McuAskTest : public McuAskBase + { + public: + McuAskTest() : McuAskBase(McuAskBlock::BLOCK, McuAskReply::NEED_REPLY) {} // using McuAskBlock::BLOCK + virtual ~McuAskTest() = default; + }; + IMcuManager::GetInstance()->Init(); + std::shared_ptr ask = std::make_shared(); + StatusCode code = IMcuManager::GetInstance()->SetFeedingCycleForWatchDog(ask, 0, 0, 0); + if (IsCodeOK(code) == true) { + LogInfo("Write data to mcu succeed.\n"); + } + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + IMcuManager::GetInstance()->UnInit(); +} +// ../output_files/test/bin/McuManagerTest // --gtest_filter=McuManagerMockTest.INTEGRATION_McuManager_AUTO_GetIpcMission TEST_F(McuManagerMockTest, INTEGRATION_McuManager_AUTO_GetIpcMission) { @@ -241,4 +260,97 @@ TEST_F(McuManagerMockTest, INTEGRATION_McuManager_AUTO_CutOffPowerSupply) std::this_thread::sleep_for(std::chrono::milliseconds(2000)); IMcuManager::GetInstance()->UnInit(); } +// ../output_files/test/bin/McuManagerTest +// --gtest_filter=McuManagerMockTest.INTEGRATION_McuManager_AUTO_FeedWatchDog +TEST_F(McuManagerMockTest, INTEGRATION_McuManager_AUTO_FeedWatchDog) +{ + class McuAskTest : public McuAskBaseTestTool + { + public: + McuAskTest() + : McuAskBaseTestTool(McuAskBlock::UNRELATED, + McuAskReply::NEED_NOT_REPLY) // using McuAskReply::NEED_NOT_REPLY + { + } + virtual ~McuAskTest() = default; + }; + IMcuManager::GetInstance()->Init(); + std::shared_ptr ask = std::make_shared(); + std::shared_ptr testTool = std::dynamic_pointer_cast(ask); + testTool->McuAskDefaultFeatures(testTool); + StatusCode code = IMcuManager::GetInstance()->FeedWatchDog(ask); + EXPECT_EQ(CheckAskExist(ask), false); // Ensure that the request has been processed and deleted. + EXPECT_EQ(code.mStatusCode, STATUS_CODE_OK); // STATUS_CODE_OK means write data to mcu succeed. + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + IMcuManager::GetInstance()->UnInit(); +} +// ../output_files/test/bin/McuManagerTest +// --gtest_filter=McuManagerMockTest.INTEGRATION_McuManager_AUTO_SetFeedingCycleForWatchDog +TEST_F(McuManagerMockTest, INTEGRATION_McuManager_AUTO_SetFeedingCycleForWatchDog) +{ + class McuAskTest : public McuAsk, public McuAskBaseTestTool + { + public: + McuAskTest() : McuAskBaseTestTool(McuAskBlock::BLOCK, + McuAskReply::NEED_REPLY) // using McuAskBlock::BLOCK, + { + } + virtual ~McuAskTest() = default; + void ReplyFinished(const bool result) override + { + McuAskBaseTestTool::ReplyFinished(result); + if (result) { + LogInfo("Ask data succeed, mDataReply = %d.\n", static_cast(mDataReply)); + // Do something here. + } + else { + LogError("Ask data falied.\n"); + } + } + }; + IMcuManager::GetInstance()->Init(); + std::shared_ptr ask = std::make_shared(); + std::shared_ptr testTool = std::dynamic_pointer_cast(ask); + testTool->McuAskDefaultFeatures(testTool); + StatusCode code = IMcuManager::GetInstance()->SetFeedingCycleForWatchDog(ask, 1, 1, 1); + EXPECT_EQ(CheckAskExist(ask), false); // Ensure that the request has been processed and deleted. + EXPECT_EQ(code.mStatusCode, STATUS_CODE_OK); // STATUS_CODE_OK means write data to mcu succeed. + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + IMcuManager::GetInstance()->UnInit(); +} +// ../output_files/test/bin/McuManagerTest +// --gtest_filter=McuManagerMockTest.INTEGRATION_McuManager_AUTO_SetFeedingCycleForWatchDog2 +TEST_F(McuManagerMockTest, INTEGRATION_McuManager_AUTO_SetFeedingCycleForWatchDog2) +{ + class McuAskTest : public McuAsk, public McuAskBaseTestTool + { + public: + McuAskTest() + : McuAskBaseTestTool(McuAskBlock::NOT_BLOCK, + McuAskReply::NEED_REPLY) // using McuAskBlock::NOT_BLOCK + { + } + virtual ~McuAskTest() = default; + void ReplyFinished(const bool result) override + { + McuAskBaseTestTool::ReplyFinished(result); + if (result) { + LogInfo("Ask data succeed, mDataReply = %d.\n", static_cast(mDataReply)); + // Do something here. + } + else { + LogError("Ask data falied.\n"); + } + } + }; + IMcuManager::GetInstance()->Init(); + std::shared_ptr ask = std::make_shared(); + std::shared_ptr testTool = std::dynamic_pointer_cast(ask); + testTool->McuAskDefaultFeatures(testTool); + StatusCode code = IMcuManager::GetInstance()->SetFeedingCycleForWatchDog(ask, 1, 1, 1); + EXPECT_EQ(code.mStatusCode, STATUS_CODE_OK); // STATUS_CODE_OK means write data to mcu succeed. + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + EXPECT_EQ(CheckAskExist(ask), false); // Ensure that the request has been processed and deleted. + IMcuManager::GetInstance()->UnInit(); +} } // namespace McuManagerMockTest \ No newline at end of file diff --git a/test/utils/McuProtocol/tool/include/McuProtocolTestTool.h b/test/utils/McuProtocol/tool/include/McuProtocolTestTool.h index 94e352f..d0267e0 100644 --- a/test/utils/McuProtocol/tool/include/McuProtocolTestTool.h +++ b/test/utils/McuProtocol/tool/include/McuProtocolTestTool.h @@ -27,7 +27,9 @@ public: void UnInit(void); private: + void ReplySelectSucceed(std::shared_ptr &mock, const int &uartFd); void IpcMissionProtocolInit(std::shared_ptr &mock, const int &uartFd); + void FeedingCycleProtocolInit(std::shared_ptr &mock, const int &uartFd); private: static void PrintHexadecimalData(const void *buf, const size_t &bufLength, const int event); diff --git a/test/utils/McuProtocol/tool/src/McuProtocolTestTool.cpp b/test/utils/McuProtocol/tool/src/McuProtocolTestTool.cpp index 95d6ce6..25f1755 100644 --- a/test/utils/McuProtocol/tool/src/McuProtocolTestTool.cpp +++ b/test/utils/McuProtocol/tool/src/McuProtocolTestTool.cpp @@ -19,12 +19,17 @@ #include #include constexpr size_t PROTOCOL_DATA_KEY_HEAD_LENGTH = 10; +constexpr size_t PROTOCOL_COMMAND_LENGTH = 6; const unsigned char ASK_IPC_MISSION[] = {0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x0C, 0x71, 0x88}; const unsigned char REPLY_IPC_MISSION[] = { 0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x0D, 0x01, 0xAA, 0x89}; const unsigned char ASK_CUT_OFF_POWER_SUPPLY[] = { 0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x81, 0x02, 0x00, 0x0C, 0x81, 0x88}; const unsigned char ASK_FEED_WATCH_DOG[] = {0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x81, 0x03, 0x00, 0x0C, 0xD0, 0x48}; +const unsigned char ASK_SET_FEEDING_CYCLE[] = { + 0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x81, 0x04, 0x00, 0x0F, 0x01, 0x01, 0x01, 0xA7, 0x9A}; +const unsigned char REPLY_SET_FEEDING_CYCLE[] = { + 0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x0F, 0x01, 0x01, 0x01, 0x52, 0x26}; void McuProtocolTestTool::Init(std::shared_ptr &mock, const UartInfo &uart) { int uartFd = GetDeviceMockFd(uart); @@ -32,18 +37,46 @@ void McuProtocolTestTool::Init(std::shared_ptr &mock, const UartInfo static size_t WRITE_COUNT = -1; auto api_write = [=, &mock](int fd, const void *buf, size_t count) { McuProtocolTestTool::PrintHexadecimalData(buf, count, WRITE_PRINT); - if (sizeof(ASK_IPC_MISSION) == count && memcmp(ASK_IPC_MISSION, buf, count) == 0) { + if (sizeof(ASK_IPC_MISSION) == count && + memcmp(ASK_IPC_MISSION + PROTOCOL_COMMAND_LENGTH, (unsigned char *)buf + PROTOCOL_COMMAND_LENGTH, 2) == 0) { LogInfo("Set REPLY_IPC_MISSION\n"); + short askCheckCode = calculate_check_sum(ASK_IPC_MISSION, sizeof(ASK_IPC_MISSION) - sizeof(short)); + askCheckCode = htons(askCheckCode); + EXPECT_EQ(memcmp((unsigned char *)ASK_IPC_MISSION + count - sizeof(short), &askCheckCode, 2), 0); IpcMissionProtocolInit(mock, uartFd); } - if (sizeof(ASK_CUT_OFF_POWER_SUPPLY) == count && memcmp(ASK_CUT_OFF_POWER_SUPPLY, buf, count) == 0) { + if (sizeof(ASK_CUT_OFF_POWER_SUPPLY) == count && memcmp(ASK_CUT_OFF_POWER_SUPPLY + PROTOCOL_COMMAND_LENGTH, + (unsigned char *)buf + PROTOCOL_COMMAND_LENGTH, + 2) == 0) { LogInfo("Set ASK_CUT_OFF_POWER_SUPPLY\n"); + short askCheckCode = + calculate_check_sum(ASK_CUT_OFF_POWER_SUPPLY, sizeof(ASK_CUT_OFF_POWER_SUPPLY) - sizeof(short)); + askCheckCode = htons(askCheckCode); + EXPECT_EQ(memcmp((unsigned char *)ASK_CUT_OFF_POWER_SUPPLY + count - sizeof(short), &askCheckCode, 2), 0); // IpcMissionProtocolInit(mock, uartFd); } - if (sizeof(ASK_FEED_WATCH_DOG) == count && memcmp(ASK_FEED_WATCH_DOG, buf, count) == 0) { + if (sizeof(ASK_FEED_WATCH_DOG) == count && + memcmp(ASK_FEED_WATCH_DOG + PROTOCOL_COMMAND_LENGTH, (unsigned char *)buf + PROTOCOL_COMMAND_LENGTH, 2) == + 0) { LogInfo("Set ASK_FEED_WATCH_DOG\n"); + short askCheckCode = calculate_check_sum(ASK_FEED_WATCH_DOG, sizeof(ASK_FEED_WATCH_DOG) - sizeof(short)); + askCheckCode = htons(askCheckCode); + EXPECT_EQ(memcmp((unsigned char *)ASK_FEED_WATCH_DOG + count - sizeof(short), &askCheckCode, 2), 0); // IpcMissionProtocolInit(mock, uartFd); } + if (sizeof(ASK_SET_FEEDING_CYCLE) == count && memcmp(ASK_SET_FEEDING_CYCLE + PROTOCOL_COMMAND_LENGTH, + (unsigned char *)buf + PROTOCOL_COMMAND_LENGTH, + 2) == 0) { + short replyCheckCode = + calculate_check_sum(REPLY_SET_FEEDING_CYCLE, sizeof(REPLY_SET_FEEDING_CYCLE) - sizeof(short)); + replyCheckCode = htons(replyCheckCode); + LogInfo("Set ASK_SET_FEEDING_CYCLE, reply data check code = 0x%x\n", replyCheckCode); + short askCheckCode = + calculate_check_sum(ASK_SET_FEEDING_CYCLE, sizeof(ASK_SET_FEEDING_CYCLE) - sizeof(short)); + askCheckCode = htons(askCheckCode); + EXPECT_EQ(memcmp((unsigned char *)ASK_SET_FEEDING_CYCLE + count - sizeof(short), &askCheckCode, 2), 0); + FeedingCycleProtocolInit(mock, uartFd); + } }; EXPECT_CALL(*mock.get(), fx_write(uartFd, _, _)) .WillRepeatedly( @@ -53,7 +86,7 @@ void McuProtocolTestTool::UnInit(void) { // } -void McuProtocolTestTool::IpcMissionProtocolInit(std::shared_ptr &mock, const int &uartFd) +void McuProtocolTestTool::ReplySelectSucceed(std::shared_ptr &mock, const int &uartFd) { auto selectReadable = [=, &mock](int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { @@ -69,6 +102,10 @@ void McuProtocolTestTool::IpcMissionProtocolInit(std::shared_ptr &moc .WillOnce(DoAll(WithArgs<0, 1, 2, 3, 4>(Invoke(selectReadable)), Return(1))) .WillOnce(DoAll(WithArgs<0, 1, 2, 3, 4>(Invoke(selectReadable)), Return(1))) .WillRepeatedly(DoAll(WithArgs<0, 1, 2, 3, 4>(Invoke(selectTimeOut)), Return(MOCK_SELECT_TIME_OUT))); +} +void McuProtocolTestTool::IpcMissionProtocolInit(std::shared_ptr &mock, const int &uartFd) +{ + ReplySelectSucceed(mock, uartFd); constexpr int LEFT_DATA_LENGTH = sizeof(REPLY_IPC_MISSION) - PROTOCOL_DATA_KEY_HEAD_LENGTH; auto apiReadKeyHead = [=](int fd, void *buf, size_t count) { memcpy(buf, REPLY_IPC_MISSION, PROTOCOL_DATA_KEY_HEAD_LENGTH); @@ -83,6 +120,23 @@ void McuProtocolTestTool::IpcMissionProtocolInit(std::shared_ptr &moc .WillOnce(DoAll(WithArgs<0, 1, 2>(Invoke(apiReadLeftData)), Return(LEFT_DATA_LENGTH))) .WillRepeatedly(DoAll(Return(UART_DEVICE_READ_NOTHING))); } +void McuProtocolTestTool::FeedingCycleProtocolInit(std::shared_ptr &mock, const int &uartFd) +{ + ReplySelectSucceed(mock, uartFd); + constexpr int LEFT_DATA_LENGTH = sizeof(REPLY_SET_FEEDING_CYCLE) - PROTOCOL_DATA_KEY_HEAD_LENGTH; + auto apiReadKeyHead = [=](int fd, void *buf, size_t count) { + memcpy(buf, REPLY_SET_FEEDING_CYCLE, PROTOCOL_DATA_KEY_HEAD_LENGTH); + McuProtocolTestTool::PrintHexadecimalData(buf, PROTOCOL_DATA_KEY_HEAD_LENGTH, READ_PRINT); + }; + auto apiReadLeftData = [=](int fd, void *buf, size_t count) { + memcpy(buf, REPLY_SET_FEEDING_CYCLE + PROTOCOL_DATA_KEY_HEAD_LENGTH, LEFT_DATA_LENGTH); + McuProtocolTestTool::PrintHexadecimalData(buf, LEFT_DATA_LENGTH, READ_PRINT); + }; + EXPECT_CALL(*mock.get(), fx_read(uartFd, _, _)) + .WillOnce(DoAll(WithArgs<0, 1, 2>(Invoke(apiReadKeyHead)), Return(PROTOCOL_DATA_KEY_HEAD_LENGTH))) + .WillOnce(DoAll(WithArgs<0, 1, 2>(Invoke(apiReadLeftData)), Return(LEFT_DATA_LENGTH))) + .WillRepeatedly(DoAll(Return(UART_DEVICE_READ_NOTHING))); +} void McuProtocolTestTool::PrintHexadecimalData(const void *buf, const size_t &bufLength, const int event) { if (WRITE_PRINT == event) { diff --git a/utils/McuProtocol/include/McuProtocol.h b/utils/McuProtocol/include/McuProtocol.h index dd5efcf..cf89163 100644 --- a/utils/McuProtocol/include/McuProtocol.h +++ b/utils/McuProtocol/include/McuProtocol.h @@ -75,6 +75,12 @@ protected: public: }; +enum ReplyResult +{ + SUCCEED = 1, + FAILED, + END +}; class VProtocolRecv { public: @@ -82,6 +88,7 @@ public: virtual ~VProtocolRecv() = default; static std::shared_ptr &GetInstance(std::shared_ptr *impl = nullptr); virtual void GetIpcMissionReply(const unsigned int &serialNumber, const unsigned char &mission) {} + virtual void SetFeedingCycleForWatchDogReply(const unsigned int &serialNumber, const ReplyResult &result) {} }; class McuProtocol : virtual public VProtocolBase { @@ -93,6 +100,9 @@ public: const StatusCode GetIpcMission(std::shared_ptr &context); const StatusCode CutOffPowerSupply(std::shared_ptr &context); const StatusCode FeedWatchDog(std::shared_ptr &context); + const StatusCode SetFeedingCycleForWatchDog(const unsigned char &hour, const unsigned char &min, + const unsigned char &second, + std::shared_ptr &context); void DataHandleThread(void); protected: diff --git a/utils/McuProtocol/src/McuProtocol.cpp b/utils/McuProtocol/src/McuProtocol.cpp index 310e786..f95a0b5 100644 --- a/utils/McuProtocol/src/McuProtocol.cpp +++ b/utils/McuProtocol/src/McuProtocol.cpp @@ -75,6 +75,17 @@ const StatusCode McuProtocol::FeedWatchDog(std::shared_ptr &co return WriteProtocolData( handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber()); } +const StatusCode McuProtocol::SetFeedingCycleForWatchDog(const unsigned char &hour, const unsigned char &min, + const unsigned char &second, + std::shared_ptr &context) +{ + WatchDogParam watchDogParam(hour, min, second); + std::shared_ptr param = + std::make_shared>(PROTOCOL_COMMAND::ASK_SET_FEEDING_CYCLE, watchDogParam); + std::shared_ptr handle = ProtocolHandle::CreateProtocolData(param); + return WriteProtocolData( + handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber()); +} void McuProtocol::DataHandleThread(void) { mThreadRuning = true; diff --git a/utils/McuProtocol/src/ProtocolHandle.cpp b/utils/McuProtocol/src/ProtocolHandle.cpp index 11f70b1..bc9ee3e 100644 --- a/utils/McuProtocol/src/ProtocolHandle.cpp +++ b/utils/McuProtocol/src/ProtocolHandle.cpp @@ -32,6 +32,8 @@ ProtocolHandle::ProtocolHandle(const std::shared_ptr ¶m) : m std::bind(&ProtocolHandle::MakeAskCutOffPowerSupplyPacket, this, std::placeholders::_1); mMakePacketFunc[ASK_FEED_WATCH_DOG] = std::bind(&ProtocolHandle::MakeAskFeedWatchDogPacket, this, std::placeholders::_1); + mMakePacketFunc[ASK_SET_FEEDING_CYCLE] = + std::bind(&ProtocolHandle::MakeAskSetFeedingCyclePacket, this, std::placeholders::_1); } ProtocolHandle::ProtocolHandle(const void *data, const size_t &length) { @@ -42,6 +44,8 @@ ProtocolHandle::ProtocolHandle(const void *data, const size_t &length) mProtocolDataLength = length; mAnalyzePacketFunc[REPLY_IPC_MISSION] = std::bind(&ProtocolHandle::AnalyzeReplyIpcMissionPacket, this, std::placeholders::_1); + mAnalyzePacketFunc[REPLY_SET_FEEDING_CYCLE] = + std::bind(&ProtocolHandle::AnalyzeReplySetFeedingCyclePacket, this, std::placeholders::_1); } ProtocolHandle::~ProtocolHandle() { @@ -99,6 +103,40 @@ void ProtocolHandle::MakeAskFeedWatchDogPacket(const std::shared_ptr ¶m) +{ + constexpr int PARAM_DATA_LENGTH = 3; + size_t dataLength = KEY_HEAD_LENGTH + PARAM_DATA_LENGTH + sizeof(short); + mProtocolData = (unsigned char *)malloc(dataLength); + if (nullptr == mProtocolData) { + LogError("malloc failed, MakeAskIpcMissionPacket return.\n"); + return; + } + std::shared_ptr> SetParam = + std::dynamic_pointer_cast>(param); + if (!SetParam) { + LogError("Invalid param.\n"); + return; + } + char feedingCycle[PARAM_DATA_LENGTH] = {0}; + feedingCycle[0] = SetParam->mData.mHour; + feedingCycle[1] = SetParam->mData.mMin; + feedingCycle[2] = SetParam->mData.mSecond; + ProtocolPacket packet; + packet.mHead = PROTOCOL_HEAD; + packet.mCommand = param->mCommand; + packet.mLength = dataLength; + packet.mSerialNumber = mSerialNumber; + mProtocolSerialNumber = packet.mSerialNumber; + mSerialNumber++; + BigEndianConversion(packet); + memcpy(mProtocolData, &packet, KEY_HEAD_LENGTH); + memcpy(mProtocolData + KEY_HEAD_LENGTH, feedingCycle, PARAM_DATA_LENGTH); + packet.mCheckCode = calculate_check_sum(mProtocolData, dataLength - sizeof(short)); + packet.mCheckCode = BigEndianConversion(packet.mCheckCode); + memcpy(mProtocolData + dataLength - sizeof(short), &packet.mCheckCode, sizeof(short)); + mProtocolDataLength = dataLength; +} void ProtocolHandle::AnalyzeProtocolPacket(void) { ProtocolPacket packet = {0}; @@ -122,21 +160,33 @@ void ProtocolHandle::AnalyzeProtocolPacket(void) LogError("Unknown command.\n"); } } -void ProtocolHandle::AnalyzeReplyIpcMissionPacket(const ProtocolPacket &packet) +unsigned char ProtocolHandle::ReplyOneBytePacketResult(const ProtocolPacket &packet) { - LogInfo("AnalyzeReplyIpcMissionPacket\n"); - constexpr unsigned char UNKNOWN_MISSION = 0xFF; + constexpr unsigned char UNKNOWN_RESULT = 0xFF; constexpr unsigned int PROTOCOL_DATA_START_ADDRESS = KEY_HEAD_LENGTH; - unsigned char ipcMission = UNKNOWN_MISSION; - ipcMission = mProtocolData[PROTOCOL_DATA_START_ADDRESS]; - LogInfo("ipc mission = 0x%02X\n", ipcMission); + unsigned char replyResult = UNKNOWN_RESULT; + replyResult = mProtocolData[PROTOCOL_DATA_START_ADDRESS]; /** * @brief unsigned int number = packet.mSerialNumber This line of code is for * avoiding errors: runtime error: reference binding to misaligned address xxxx */ mProtocolSerialNumber = packet.mSerialNumber; + LogInfo("reply result = 0x%02X\n", replyResult); + return replyResult; +} +void ProtocolHandle::AnalyzeReplyIpcMissionPacket(const ProtocolPacket &packet) +{ + LogInfo("AnalyzeReplyIpcMissionPacket\n"); + unsigned char ipcMission = ReplyOneBytePacketResult(packet); VProtocolRecv::GetInstance()->GetIpcMissionReply(mProtocolSerialNumber, ipcMission); } +void ProtocolHandle::AnalyzeReplySetFeedingCyclePacket(const ProtocolPacket &packet) +{ + LogInfo("AnalyzeReplySetFeedingCyclePacket\n"); + unsigned char replyResult = ReplyOneBytePacketResult(packet); + VProtocolRecv::GetInstance()->SetFeedingCycleForWatchDogReply(mProtocolSerialNumber, + static_cast(replyResult)); +} bool ProtocolHandle::CheckoutTheCheckCode(const ProtocolPacket &packet) { short code = calculate_check_sum(mProtocolData, mProtocolDataLength - sizeof(short)); diff --git a/utils/McuProtocol/src/ProtocolHandle.h b/utils/McuProtocol/src/ProtocolHandle.h index 33a0beb..cbfbda4 100644 --- a/utils/McuProtocol/src/ProtocolHandle.h +++ b/utils/McuProtocol/src/ProtocolHandle.h @@ -37,8 +37,23 @@ enum PROTOCOL_COMMAND REPLY_IPC_MISSION = 0x0101, ASK_CUT_OFF_PWOER_SUPPLY = 0x8102, ASK_FEED_WATCH_DOG = 0x8103, + ASK_SET_FEEDING_CYCLE = 0x8104, + REPLY_SET_FEEDING_CYCLE = 0x0104, PROTOCOL_COMMAND_END }; +constexpr unsigned char ZERO_MEANS_SHUTDOWN_WATCH_DOG = 0x00; +class WatchDogParam +{ +public: + WatchDogParam(const unsigned char &hour, const unsigned char &min, const unsigned char &second) + : mHour(hour), mMin(min), mSecond(second) + { + } + ~WatchDogParam() = default; + const unsigned char mHour; + const unsigned char mMin; + const unsigned char mSecond; +}; class VProtocolParam { public: @@ -87,6 +102,7 @@ private: void MakeAskIpcMissionPacket(const std::shared_ptr ¶m); void MakeAskCutOffPowerSupplyPacket(const std::shared_ptr ¶m); void MakeAskFeedWatchDogPacket(const std::shared_ptr ¶m); + void MakeAskSetFeedingCyclePacket(const std::shared_ptr ¶m); /** * @brief These function implementations parse the received frame by frame continuous data into the data required by @@ -94,7 +110,9 @@ private: */ private: void AnalyzeProtocolPacket(void); + unsigned char ReplyOneBytePacketResult(const ProtocolPacket &packet); void AnalyzeReplyIpcMissionPacket(const ProtocolPacket &packet); + void AnalyzeReplySetFeedingCyclePacket(const ProtocolPacket &packet); private: virtual void BigEndianConversion(ProtocolPacket &packet) {}