Add:Set feeding cycle for watch dog.

This commit is contained in:
Fancy code 2024-02-09 00:08:56 -08:00
parent 2feccc7d36
commit 63bcd37b66
13 changed files with 311 additions and 15 deletions

View File

@ -528,14 +528,23 @@ end
###### 1.4.3.2.5.1. 协议格式 ###### 1.4.3.2.5.1. 协议格式
| 协议头 | 命令字 | 长度 | 数据段 | 校验码 | | 协议头 | 流水号 | 命令字 | 长度 | 数据段 | 校验码 |
|----|----|----|----|----| |----|----|----|----|----|----|
| 2字节<br>0xFAC1 | 2字节 | 2字节 | - | 2字节 | | 2字节<br>0xFAC1 | 4字节 | 2字节 | 2字节 | - | 2字节 |
**流水号**
&emsp;&emsp; 流水号用于强绑定问答型协议的发送数据和回复数据,回复者原数据回传即可。例如:
```
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};
```
**校验码算法** **校验码算法**
&emsp;&emsp; 校验码算法使用ModBus CRC16方法计算。 &emsp;&emsp; 校验码算法使用ModBus CRC16方法计算。
**参考代码(查表法)** **参考代码(查表法)**
``` ```

View File

@ -25,9 +25,9 @@ enum class IpcMission
}; };
enum class ASK_RESULT enum class ASK_RESULT
{ {
SUCCEED = 0, SUCCEED = 1,
TIMEOUT,
FAILED, FAILED,
TIMEOUT,
END END
}; };
class VMcuAsk class VMcuAsk
@ -89,5 +89,10 @@ public:
{ {
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
} }
virtual const StatusCode SetFeedingCycleForWatchDog(std::shared_ptr<VMcuAsk> &ask, const unsigned char &hour,
const unsigned char &min, const unsigned char &second)
{
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
}
}; };
#endif #endif

View File

@ -109,6 +109,22 @@ void McuDevice::GetIpcMissionReply(const unsigned int &serialNumber, const unsig
DeleteMcuAsk(ask); DeleteMcuAsk(ask);
} }
} }
void McuDevice::SetFeedingCycleForWatchDogReply(const unsigned int &serialNumber, const ReplyResult &result)
{
std::shared_ptr<VMcuAsk> ask;
SearchMcuAsk(serialNumber, ask);
if (ask) {
std::shared_ptr<McuAsk<ASK_RESULT>> realAsk = std::dynamic_pointer_cast<McuAsk<ASK_RESULT>>(ask);
if (realAsk) {
realAsk->mDataReply = static_cast<ASK_RESULT>(result);
ask->ReplyFinished(true);
}
else {
ask->ReplyFinished(false);
}
DeleteMcuAsk(ask);
}
}
void McuDevice::DeviceRecvThread(void) void McuDevice::DeviceRecvThread(void)
{ {
constexpr int RECV_TIMEOUT_MS = 1000; constexpr int RECV_TIMEOUT_MS = 1000;

View File

@ -34,6 +34,7 @@ public:
public: public:
void GetIpcMissionReply(const unsigned int &serialNumber, const unsigned char &mission) override; void GetIpcMissionReply(const unsigned int &serialNumber, const unsigned char &mission) override;
void SetFeedingCycleForWatchDogReply(const unsigned int &serialNumber, const ReplyResult &result) override;
public: public:
void DeviceRecvThread(void); void DeviceRecvThread(void);

View File

@ -41,3 +41,9 @@ const StatusCode McuManagerImpl::FeedWatchDog(std::shared_ptr<VMcuAsk> &ask)
std::shared_ptr<VProtocolContext> context = std::make_shared<ProtocolContext<std::shared_ptr<VMcuAsk>>>(ask); std::shared_ptr<VProtocolContext> context = std::make_shared<ProtocolContext<std::shared_ptr<VMcuAsk>>>(ask);
return McuProtocol::FeedWatchDog(context); return McuProtocol::FeedWatchDog(context);
} }
const StatusCode McuManagerImpl::SetFeedingCycleForWatchDog(std::shared_ptr<VMcuAsk> &ask, const unsigned char &hour,
const unsigned char &min, const unsigned char &second)
{
std::shared_ptr<VProtocolContext> context = std::make_shared<ProtocolContext<std::shared_ptr<VMcuAsk>>>(ask);
return McuProtocol::SetFeedingCycleForWatchDog(hour, min, second, context);
}

View File

@ -28,5 +28,7 @@ public:
const StatusCode GetIpcMission(std::shared_ptr<VMcuAsk> &ask) override; const StatusCode GetIpcMission(std::shared_ptr<VMcuAsk> &ask) override;
const StatusCode CutOffPowerSupply(std::shared_ptr<VMcuAsk> &ask) override; const StatusCode CutOffPowerSupply(std::shared_ptr<VMcuAsk> &ask) override;
const StatusCode FeedWatchDog(std::shared_ptr<VMcuAsk> &ask) override; const StatusCode FeedWatchDog(std::shared_ptr<VMcuAsk> &ask) override;
const StatusCode SetFeedingCycleForWatchDog(std::shared_ptr<VMcuAsk> &ask, const unsigned char &hour,
const unsigned char &min, const unsigned char &second) override;
}; };
#endif #endif

View File

@ -159,6 +159,25 @@ TEST_F(McuManagerMockTest, INTEGRATION_McuManager_EXAMPLE_FeedWatchDog)
IMcuManager::GetInstance()->UnInit(); IMcuManager::GetInstance()->UnInit();
} }
// ../output_files/test/bin/McuManagerTest // ../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<VMcuAsk> ask = std::make_shared<McuAskTest>();
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 // --gtest_filter=McuManagerMockTest.INTEGRATION_McuManager_AUTO_GetIpcMission
TEST_F(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)); std::this_thread::sleep_for(std::chrono::milliseconds(2000));
IMcuManager::GetInstance()->UnInit(); 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<VMcuAsk> ask = std::make_shared<McuAskTest>();
std::shared_ptr<McuAskBaseTestTool> testTool = std::dynamic_pointer_cast<McuAskBaseTestTool>(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<ASK_RESULT>, 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<int>(mDataReply));
// Do something here.
}
else {
LogError("Ask data falied.\n");
}
}
};
IMcuManager::GetInstance()->Init();
std::shared_ptr<VMcuAsk> ask = std::make_shared<McuAskTest>();
std::shared_ptr<McuAskBaseTestTool> testTool = std::dynamic_pointer_cast<McuAskBaseTestTool>(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<ASK_RESULT>, 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<int>(mDataReply));
// Do something here.
}
else {
LogError("Ask data falied.\n");
}
}
};
IMcuManager::GetInstance()->Init();
std::shared_ptr<VMcuAsk> ask = std::make_shared<McuAskTest>();
std::shared_ptr<McuAskBaseTestTool> testTool = std::dynamic_pointer_cast<McuAskBaseTestTool>(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 } // namespace McuManagerMockTest

View File

@ -27,7 +27,9 @@ public:
void UnInit(void); void UnInit(void);
private: private:
void ReplySelectSucceed(std::shared_ptr<LinuxTest> &mock, const int &uartFd);
void IpcMissionProtocolInit(std::shared_ptr<LinuxTest> &mock, const int &uartFd); void IpcMissionProtocolInit(std::shared_ptr<LinuxTest> &mock, const int &uartFd);
void FeedingCycleProtocolInit(std::shared_ptr<LinuxTest> &mock, const int &uartFd);
private: private:
static void PrintHexadecimalData(const void *buf, const size_t &bufLength, const int event); static void PrintHexadecimalData(const void *buf, const size_t &bufLength, const int event);

View File

@ -19,12 +19,17 @@
#include <string.h> #include <string.h>
#include <thread> #include <thread>
constexpr size_t PROTOCOL_DATA_KEY_HEAD_LENGTH = 10; 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 ASK_IPC_MISSION[] = {0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x0C, 0x71, 0x88};
const unsigned char REPLY_IPC_MISSION[] = { const unsigned char REPLY_IPC_MISSION[] = {
0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x0D, 0x01, 0xAA, 0x89}; 0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x0D, 0x01, 0xAA, 0x89};
const unsigned char ASK_CUT_OFF_POWER_SUPPLY[] = { const unsigned char ASK_CUT_OFF_POWER_SUPPLY[] = {
0xFA, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x81, 0x02, 0x00, 0x0C, 0x81, 0x88}; 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_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<LinuxTest> &mock, const UartInfo &uart) void McuProtocolTestTool::Init(std::shared_ptr<LinuxTest> &mock, const UartInfo &uart)
{ {
int uartFd = GetDeviceMockFd(uart); int uartFd = GetDeviceMockFd(uart);
@ -32,18 +37,46 @@ void McuProtocolTestTool::Init(std::shared_ptr<LinuxTest> &mock, const UartInfo
static size_t WRITE_COUNT = -1; static size_t WRITE_COUNT = -1;
auto api_write = [=, &mock](int fd, const void *buf, size_t count) { auto api_write = [=, &mock](int fd, const void *buf, size_t count) {
McuProtocolTestTool::PrintHexadecimalData(buf, count, WRITE_PRINT); 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"); 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); 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"); 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); // 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"); 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); // 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, _, _)) EXPECT_CALL(*mock.get(), fx_write(uartFd, _, _))
.WillRepeatedly( .WillRepeatedly(
@ -53,7 +86,7 @@ void McuProtocolTestTool::UnInit(void)
{ {
// //
} }
void McuProtocolTestTool::IpcMissionProtocolInit(std::shared_ptr<LinuxTest> &mock, const int &uartFd) void McuProtocolTestTool::ReplySelectSucceed(std::shared_ptr<LinuxTest> &mock, const int &uartFd)
{ {
auto selectReadable = auto selectReadable =
[=, &mock](int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { [=, &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<LinuxTest> &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)))
.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))); .WillRepeatedly(DoAll(WithArgs<0, 1, 2, 3, 4>(Invoke(selectTimeOut)), Return(MOCK_SELECT_TIME_OUT)));
}
void McuProtocolTestTool::IpcMissionProtocolInit(std::shared_ptr<LinuxTest> &mock, const int &uartFd)
{
ReplySelectSucceed(mock, uartFd);
constexpr int LEFT_DATA_LENGTH = sizeof(REPLY_IPC_MISSION) - PROTOCOL_DATA_KEY_HEAD_LENGTH; constexpr int LEFT_DATA_LENGTH = sizeof(REPLY_IPC_MISSION) - PROTOCOL_DATA_KEY_HEAD_LENGTH;
auto apiReadKeyHead = [=](int fd, void *buf, size_t count) { auto apiReadKeyHead = [=](int fd, void *buf, size_t count) {
memcpy(buf, REPLY_IPC_MISSION, PROTOCOL_DATA_KEY_HEAD_LENGTH); memcpy(buf, REPLY_IPC_MISSION, PROTOCOL_DATA_KEY_HEAD_LENGTH);
@ -83,6 +120,23 @@ void McuProtocolTestTool::IpcMissionProtocolInit(std::shared_ptr<LinuxTest> &moc
.WillOnce(DoAll(WithArgs<0, 1, 2>(Invoke(apiReadLeftData)), Return(LEFT_DATA_LENGTH))) .WillOnce(DoAll(WithArgs<0, 1, 2>(Invoke(apiReadLeftData)), Return(LEFT_DATA_LENGTH)))
.WillRepeatedly(DoAll(Return(UART_DEVICE_READ_NOTHING))); .WillRepeatedly(DoAll(Return(UART_DEVICE_READ_NOTHING)));
} }
void McuProtocolTestTool::FeedingCycleProtocolInit(std::shared_ptr<LinuxTest> &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) void McuProtocolTestTool::PrintHexadecimalData(const void *buf, const size_t &bufLength, const int event)
{ {
if (WRITE_PRINT == event) { if (WRITE_PRINT == event) {

View File

@ -75,6 +75,12 @@ protected:
public: public:
}; };
enum ReplyResult
{
SUCCEED = 1,
FAILED,
END
};
class VProtocolRecv class VProtocolRecv
{ {
public: public:
@ -82,6 +88,7 @@ public:
virtual ~VProtocolRecv() = default; virtual ~VProtocolRecv() = default;
static std::shared_ptr<VProtocolRecv> &GetInstance(std::shared_ptr<VProtocolRecv> *impl = nullptr); static std::shared_ptr<VProtocolRecv> &GetInstance(std::shared_ptr<VProtocolRecv> *impl = nullptr);
virtual void GetIpcMissionReply(const unsigned int &serialNumber, const unsigned char &mission) {} 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 class McuProtocol : virtual public VProtocolBase
{ {
@ -93,6 +100,9 @@ public:
const StatusCode GetIpcMission(std::shared_ptr<VProtocolContext> &context); const StatusCode GetIpcMission(std::shared_ptr<VProtocolContext> &context);
const StatusCode CutOffPowerSupply(std::shared_ptr<VProtocolContext> &context); const StatusCode CutOffPowerSupply(std::shared_ptr<VProtocolContext> &context);
const StatusCode FeedWatchDog(std::shared_ptr<VProtocolContext> &context); const StatusCode FeedWatchDog(std::shared_ptr<VProtocolContext> &context);
const StatusCode SetFeedingCycleForWatchDog(const unsigned char &hour, const unsigned char &min,
const unsigned char &second,
std::shared_ptr<VProtocolContext> &context);
void DataHandleThread(void); void DataHandleThread(void);
protected: protected:

View File

@ -75,6 +75,17 @@ const StatusCode McuProtocol::FeedWatchDog(std::shared_ptr<VProtocolContext> &co
return WriteProtocolData( return WriteProtocolData(
handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber()); 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<VProtocolContext> &context)
{
WatchDogParam watchDogParam(hour, min, second);
std::shared_ptr<VProtocolParam> param =
std::make_shared<ProtocolParam<WatchDogParam>>(PROTOCOL_COMMAND::ASK_SET_FEEDING_CYCLE, watchDogParam);
std::shared_ptr<ProtocolHandle> handle = ProtocolHandle::CreateProtocolData(param);
return WriteProtocolData(
handle->GetProtocolDataBuff(), handle->GetProtocolDataLength(), context, handle->GetSerialNumber());
}
void McuProtocol::DataHandleThread(void) void McuProtocol::DataHandleThread(void)
{ {
mThreadRuning = true; mThreadRuning = true;

View File

@ -32,6 +32,8 @@ ProtocolHandle::ProtocolHandle(const std::shared_ptr<VProtocolParam> &param) : m
std::bind(&ProtocolHandle::MakeAskCutOffPowerSupplyPacket, this, std::placeholders::_1); std::bind(&ProtocolHandle::MakeAskCutOffPowerSupplyPacket, this, std::placeholders::_1);
mMakePacketFunc[ASK_FEED_WATCH_DOG] = mMakePacketFunc[ASK_FEED_WATCH_DOG] =
std::bind(&ProtocolHandle::MakeAskFeedWatchDogPacket, this, std::placeholders::_1); 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) ProtocolHandle::ProtocolHandle(const void *data, const size_t &length)
{ {
@ -42,6 +44,8 @@ ProtocolHandle::ProtocolHandle(const void *data, const size_t &length)
mProtocolDataLength = length; mProtocolDataLength = length;
mAnalyzePacketFunc[REPLY_IPC_MISSION] = mAnalyzePacketFunc[REPLY_IPC_MISSION] =
std::bind(&ProtocolHandle::AnalyzeReplyIpcMissionPacket, this, std::placeholders::_1); std::bind(&ProtocolHandle::AnalyzeReplyIpcMissionPacket, this, std::placeholders::_1);
mAnalyzePacketFunc[REPLY_SET_FEEDING_CYCLE] =
std::bind(&ProtocolHandle::AnalyzeReplySetFeedingCyclePacket, this, std::placeholders::_1);
} }
ProtocolHandle::~ProtocolHandle() ProtocolHandle::~ProtocolHandle()
{ {
@ -99,6 +103,40 @@ void ProtocolHandle::MakeAskFeedWatchDogPacket(const std::shared_ptr<VProtocolPa
{ {
MakeNoUserDataPacket(param); MakeNoUserDataPacket(param);
} }
void ProtocolHandle::MakeAskSetFeedingCyclePacket(const std::shared_ptr<VProtocolParam> &param)
{
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<ProtocolParam<WatchDogParam>> SetParam =
std::dynamic_pointer_cast<ProtocolParam<WatchDogParam>>(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) void ProtocolHandle::AnalyzeProtocolPacket(void)
{ {
ProtocolPacket packet = {0}; ProtocolPacket packet = {0};
@ -122,21 +160,33 @@ void ProtocolHandle::AnalyzeProtocolPacket(void)
LogError("Unknown command.\n"); LogError("Unknown command.\n");
} }
} }
void ProtocolHandle::AnalyzeReplyIpcMissionPacket(const ProtocolPacket &packet) unsigned char ProtocolHandle::ReplyOneBytePacketResult(const ProtocolPacket &packet)
{ {
LogInfo("AnalyzeReplyIpcMissionPacket\n"); constexpr unsigned char UNKNOWN_RESULT = 0xFF;
constexpr unsigned char UNKNOWN_MISSION = 0xFF;
constexpr unsigned int PROTOCOL_DATA_START_ADDRESS = KEY_HEAD_LENGTH; constexpr unsigned int PROTOCOL_DATA_START_ADDRESS = KEY_HEAD_LENGTH;
unsigned char ipcMission = UNKNOWN_MISSION; unsigned char replyResult = UNKNOWN_RESULT;
ipcMission = mProtocolData[PROTOCOL_DATA_START_ADDRESS]; replyResult = mProtocolData[PROTOCOL_DATA_START_ADDRESS];
LogInfo("ipc mission = 0x%02X\n", ipcMission);
/** /**
* @brief unsigned int number = packet.mSerialNumber This line of code is for * @brief unsigned int number = packet.mSerialNumber This line of code is for
* avoiding errors: runtime error: reference binding to misaligned address xxxx * avoiding errors: runtime error: reference binding to misaligned address xxxx
*/ */
mProtocolSerialNumber = packet.mSerialNumber; 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); 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>(replyResult));
}
bool ProtocolHandle::CheckoutTheCheckCode(const ProtocolPacket &packet) bool ProtocolHandle::CheckoutTheCheckCode(const ProtocolPacket &packet)
{ {
short code = calculate_check_sum(mProtocolData, mProtocolDataLength - sizeof(short)); short code = calculate_check_sum(mProtocolData, mProtocolDataLength - sizeof(short));

View File

@ -37,8 +37,23 @@ enum PROTOCOL_COMMAND
REPLY_IPC_MISSION = 0x0101, REPLY_IPC_MISSION = 0x0101,
ASK_CUT_OFF_PWOER_SUPPLY = 0x8102, ASK_CUT_OFF_PWOER_SUPPLY = 0x8102,
ASK_FEED_WATCH_DOG = 0x8103, ASK_FEED_WATCH_DOG = 0x8103,
ASK_SET_FEEDING_CYCLE = 0x8104,
REPLY_SET_FEEDING_CYCLE = 0x0104,
PROTOCOL_COMMAND_END 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 class VProtocolParam
{ {
public: public:
@ -87,6 +102,7 @@ private:
void MakeAskIpcMissionPacket(const std::shared_ptr<VProtocolParam> &param); void MakeAskIpcMissionPacket(const std::shared_ptr<VProtocolParam> &param);
void MakeAskCutOffPowerSupplyPacket(const std::shared_ptr<VProtocolParam> &param); void MakeAskCutOffPowerSupplyPacket(const std::shared_ptr<VProtocolParam> &param);
void MakeAskFeedWatchDogPacket(const std::shared_ptr<VProtocolParam> &param); void MakeAskFeedWatchDogPacket(const std::shared_ptr<VProtocolParam> &param);
void MakeAskSetFeedingCyclePacket(const std::shared_ptr<VProtocolParam> &param);
/** /**
* @brief These function implementations parse the received frame by frame continuous data into the data required by * @brief These function implementations parse the received frame by frame continuous data into the data required by
@ -94,7 +110,9 @@ private:
*/ */
private: private:
void AnalyzeProtocolPacket(void); void AnalyzeProtocolPacket(void);
unsigned char ReplyOneBytePacketResult(const ProtocolPacket &packet);
void AnalyzeReplyIpcMissionPacket(const ProtocolPacket &packet); void AnalyzeReplyIpcMissionPacket(const ProtocolPacket &packet);
void AnalyzeReplySetFeedingCyclePacket(const ProtocolPacket &packet);
private: private:
virtual void BigEndianConversion(ProtocolPacket &packet) {} virtual void BigEndianConversion(ProtocolPacket &packet) {}