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) {}