Backup McuManager module.

This commit is contained in:
Fancy code 2024-02-03 00:06:45 -08:00
parent a2c4fa60ec
commit 9e912b240f
10 changed files with 231 additions and 6 deletions

View File

@ -13,7 +13,13 @@
* limitations under the License.
*/
#include "McuDevice.h"
McuDevice::McuDevice() { mUartDevice = nullptr; }
#include "ILog.h"
#include <string.h>
McuDevice::McuDevice()
{
mThreadRuning = false;
mUartDevice = nullptr;
}
McuDevice::~McuDevice() {}
const StatusCode McuDevice::Init(void)
{
@ -26,14 +32,85 @@ const StatusCode McuDevice::Init(void)
'N',
};
mUartDevice = CreateUartDevice(uartDevice);
if (nullptr == mUartDevice) {
LogError("CreateUartDevice failed.\n");
return CreateStatusCode(STATUS_CODE_NOT_OK);
}
StatusCode code = IUartOpen(mUartDevice);
if (IsCodeOK(code) == false) {
LogError("IUartOpen failed.\n");
return code;
}
auto recvThread = [](std::shared_ptr<McuDevice> device) { device->DeviceRecvThread(); };
std::shared_ptr<McuDevice> device = std::dynamic_pointer_cast<McuDevice>(SharedFromThis());
mUartRecvThread = std::thread(recvThread, device);
return CreateStatusCode(STATUS_CODE_OK);
}
const StatusCode McuDevice::UnInit(void)
{
mThreadRuning = false;
if (mUartRecvThread.joinable()) {
mUartRecvThread.join();
}
if (nullptr != mUartDevice) {
IUartDeviceFree(mUartDevice);
}
mUartDevice = nullptr;
return CreateStatusCode(STATUS_CODE_OK);
}
void McuDevice::DeviceRecvThread(void)
{
constexpr int RECV_TIMEOUT_MS = 1000;
size_t recvTotalLength = 0;
const size_t keyHeadLength = GetKeyHeadLength();
char *keyHeadBuf = (char *)malloc(keyHeadLength);
if (nullptr == keyHeadBuf) {
LogError("malloc failed, DeviceRecvThread return.\n");
return;
}
mThreadRuning = true;
while (mThreadRuning) {
size_t recvLength =
IUartRecv(mUartDevice, keyHeadBuf + recvTotalLength, keyHeadLength - recvTotalLength, RECV_TIMEOUT_MS);
recvTotalLength += recvLength;
if (keyHeadLength == recvTotalLength) {
DeviceRecvData(keyHeadBuf, keyHeadLength);
memset(keyHeadBuf, 0, keyHeadLength);
recvTotalLength = 0;
}
}
free(keyHeadBuf);
}
void McuDevice::DeviceRecvData(const char *keyHead, const size_t headLength)
{
constexpr int RECV_TIMEOUT_MS = 1000;
size_t recvTotalLength = 0;
size_t dataLength = 0;
// const size_t keyHeadLength = GetKeyHeadLength();
const StatusCode code = GetDataLength(keyHead, headLength, dataLength);
if (IsCodeOK(code) == false || 0 == dataLength || dataLength <= headLength) {
LogError("Recv data error.\n");
return;
}
char *dataBuf = (char *)malloc(dataLength);
if (nullptr == dataBuf) {
LogError("malloc failed, DeviceRecvData return.\n");
return;
}
memset(dataBuf, 0, dataLength);
memcpy(dataBuf, keyHead, headLength);
while (mThreadRuning) {
size_t recvLength = IUartRecv(mUartDevice,
dataBuf + headLength + recvTotalLength,
dataLength - headLength - recvTotalLength,
RECV_TIMEOUT_MS);
recvTotalLength += recvLength;
if (dataLength - headLength == recvTotalLength) {
PushMcuData(dataBuf, dataLength);
break;
}
}
free(dataBuf);
}

View File

@ -17,6 +17,7 @@
#include "IMcuManager.h"
#include "McuProtocol.h"
#include "UartDevice.h"
#include <thread>
class McuDevice : public IMcuManager, virtual public VProtocolBase
{
public:
@ -25,7 +26,15 @@ public:
const StatusCode Init(void) override;
const StatusCode UnInit(void) override;
public:
void DeviceRecvThread(void);
private:
void DeviceRecvData(const char *keyHead, const size_t headLength);
private:
void *mUartDevice;
std::thread mUartRecvThread;
bool mThreadRuning;
};
#endif

View File

@ -13,6 +13,19 @@
* limitations under the License.
*/
#include "McuManagerImpl.h"
std::shared_ptr<VProtocolBase> McuManagerImpl::SharedFromThis(void) { return shared_from_this(); }
const StatusCode McuManagerImpl::Init(void)
{
McuDevice::Init();
McuProtocol::Init();
return CreateStatusCode(STATUS_CODE_OK);
}
const StatusCode McuManagerImpl::UnInit(void)
{
McuDevice::UnInit();
McuProtocol::UnInit();
return CreateStatusCode(STATUS_CODE_OK);
}
const StatusCode McuManagerImpl::GetIpcMissiony(std::shared_ptr<VMcuAsk> ask)
{
std::shared_ptr<VProtocolContext> context = std::make_shared<ProtocolContext<std::shared_ptr<VMcuAsk>>>(ask);

View File

@ -17,11 +17,14 @@
#include "IMcuManager.h"
#include "McuDevice.h"
#include "McuProtocol.h"
class McuManagerImpl : public McuDevice, public McuProtocol
class McuManagerImpl : public McuDevice, public McuProtocol, public std::enable_shared_from_this<McuManagerImpl>
{
public:
McuManagerImpl() = default;
virtual ~McuManagerImpl() = default;
std::shared_ptr<VProtocolBase> SharedFromThis(void) override;
const StatusCode Init(void) override;
const StatusCode UnInit(void) override;
const StatusCode GetIpcMissiony(std::shared_ptr<VMcuAsk> ask) override;
};
#endif

View File

@ -37,6 +37,10 @@ public:
public:
std::shared_ptr<LinuxTest> mLinuxTest;
};
// ../output_files/test/bin/UartDeviceTest --gtest_filter=McuManagerTest.UNIT_UartDevice_EXAMPLE_AUTO_Demo
TEST_F(McuManagerMockTest, UNIT_UartDevice_EXAMPLE_AUTO_Demo) {}
// ../output_files/test/bin/McuManagerTest --gtest_filter=McuManagerMockTest.UNIT_McuManager_EXAMPLE_AUTO_Demo
TEST_F(McuManagerMockTest, UNIT_McuManager_EXAMPLE_AUTO_Demo)
{
IMcuManager::GetInstance()->Init();
IMcuManager::GetInstance()->UnInit();
}
} // namespace McuManagerMockTest

View File

@ -19,7 +19,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
aux_source_directory(./src TEST_TOOL_SRC_FILES)
set(TEST_TOOL_TARGET UartDeviceTestTool)
add_library(${TEST_TOOL_TARGET} STATIC ${TEST_TOOL_SRC_FILES})
target_link_libraries(${TEST_TOOL_TARGET} UartDevice LinuxApiMock Log)
target_link_libraries(${TEST_TOOL_TARGET} LinuxApiMock Log)
if ("${CLANG_TIDY_SUPPORT}" MATCHES "true")
add_custom_target(

View File

@ -16,7 +16,11 @@
#define MCU_PROTOCOL_H
#include "StatusCode.h"
#include <cstddef>
#include <list>
#include <memory>
#include <mutex>
#include <semaphore.h>
#include <thread>
/**
* @brief The context of protocol processing is used for the association binding of protocol data transmission and
* reception, ensuring the correct logic of protocol question and answer.
@ -39,15 +43,32 @@ public:
public:
T mData;
};
class SingleMcuPacket
{
public:
SingleMcuPacket(const void *buf, const size_t &length) : mBuf(buf), mLength(length) {}
~SingleMcuPacket() = default;
const void *mBuf;
const size_t mLength;
};
class VProtocolBase
{
public:
VProtocolBase() = default;
virtual ~VProtocolBase() = default;
public:
protected:
virtual std::shared_ptr<VProtocolBase> SharedFromThis(void) { return std::make_shared<VProtocolBase>(); }
virtual size_t WriteData(const void *buff, const size_t buffLength) { return 0; }
protected:
virtual size_t GetKeyHeadLength(void) { return 0; }
virtual StatusCode GetDataLength(const void *keyHead, const size_t &headLength, size_t &dataLength)
{
return CreateStatusCode(STATUS_CODE_INVALID_PARAMENTER);
}
virtual void PushMcuData(const void *buf, const size_t &length) {}
public:
};
class McuProtocol : virtual public VProtocolBase
@ -55,6 +76,21 @@ class McuProtocol : virtual public VProtocolBase
public:
McuProtocol() = default;
virtual ~McuProtocol() = default;
const StatusCode Init(void);
const StatusCode UnInit(void);
const StatusCode GetIpcMissiony(std::shared_ptr<VProtocolContext> &context);
void DataHandleThread(void);
protected:
size_t GetKeyHeadLength(void) override;
StatusCode GetDataLength(const void *keyHead, const size_t &headLength, size_t &dataLength) override;
void PushMcuData(const void *buf, const size_t &length) override;
private:
std::mutex mMutex;
sem_t mSem;
std::thread mDataHandleThread;
bool mThreadRuning;
std::list<SingleMcuPacket> mMcuDataList;
};
#endif

View File

@ -13,7 +13,29 @@
* limitations under the License.
*/
#include "McuProtocol.h"
#include "ILog.h"
#include "ProtocolHandle.h"
#include <string.h>
constexpr int THREAD_SHARING = 0;
constexpr int INITIAL_VALUE_OF_SEMAPHORE = 0;
const StatusCode McuProtocol::Init(void)
{
sem_init(&mSem, THREAD_SHARING, INITIAL_VALUE_OF_SEMAPHORE);
auto dataHandleThread = [](std::shared_ptr<McuProtocol> handle) { handle->DataHandleThread(); };
std::shared_ptr<McuProtocol> handle = std::dynamic_pointer_cast<McuProtocol>(SharedFromThis());
mDataHandleThread = std::thread(dataHandleThread, handle);
return CreateStatusCode(STATUS_CODE_OK);
}
const StatusCode McuProtocol::UnInit(void)
{
mThreadRuning = false;
sem_post(&mSem);
if (mDataHandleThread.joinable()) {
mDataHandleThread.join();
}
sem_destroy(&mSem);
return CreateStatusCode(STATUS_CODE_OK);
}
const StatusCode McuProtocol::GetIpcMissiony(std::shared_ptr<VProtocolContext> &context)
{
char data = 0;
@ -22,4 +44,37 @@ const StatusCode McuProtocol::GetIpcMissiony(std::shared_ptr<VProtocolContext> &
std::shared_ptr<ProtocolHandle> handle = ProtocolHandle::CreateProtocolData(param);
WriteData(handle->GetProtocolDataBuff(), handle->GetProtocolDataLength());
return CreateStatusCode(STATUS_CODE_OK);
}
void McuProtocol::DataHandleThread(void)
{
mThreadRuning = true;
while (mThreadRuning) {
sem_wait(&mSem);
if (mMcuDataList.size() == 0) {
continue;
}
mMutex.lock();
SingleMcuPacket packet = mMcuDataList.front();
mMutex.unlock();
ProtocolHandle::ProtocolAnalysis(packet.mBuf, packet.mLength);
mMcuDataList.pop_front();
free((void *)packet.mBuf);
}
}
size_t McuProtocol::GetKeyHeadLength(void) { return ProtocolHandle::GetKeyHeadLength(); }
StatusCode McuProtocol::GetDataLength(const void *keyHead, const size_t &headLength, size_t &dataLength)
{
return ProtocolHandle::GetDataLength(keyHead, headLength, dataLength);
}
void McuProtocol::PushMcuData(const void *buf, const size_t &length)
{
char *data = (char *)malloc(length);
if (nullptr == data) {
LogError("malloc failed, PushMcuData failed.\n");
return;
}
std::lock_guard<std::mutex> locker(mMutex);
SingleMcuPacket packet(data, length);
mMcuDataList.push_back(packet);
sem_post(&mSem);
}

View File

@ -13,11 +13,15 @@
* limitations under the License.
*/
#include "ProtocolHandle.h"
#include "ILog.h"
#include <string.h>
constexpr unsigned short PROTOCOL_HEAD = 0xFAC1;
constexpr size_t KEY_HEAD_LENGTH = sizeof(short) + sizeof(unsigned int) + sizeof(short) + sizeof(short);
#pragma pack(1)
typedef struct protocol_packet
{
short mHead;
unsigned int mSerialNumber;
short mCommand;
short mLength;
char *mData;
@ -28,4 +32,24 @@ std::shared_ptr<ProtocolHandle> ProtocolHandle::CreateProtocolData(const std::sh
{
std::shared_ptr<ProtocolHandle> handle = std::make_shared<ProtocolHandle>();
return handle;
}
void ProtocolHandle::ProtocolAnalysis(const void *data, const size_t &length)
{
//
}
size_t ProtocolHandle::GetKeyHeadLength(void) { return KEY_HEAD_LENGTH; }
StatusCode ProtocolHandle::GetDataLength(const void *keyHead, const size_t &headLength, size_t &dataLength)
{
if (KEY_HEAD_LENGTH != headLength) {
LogError("key head buf error.\n");
return CreateStatusCode(STATUS_CODE_NOT_OK);
}
ProtocolPacket packet = {0};
memcpy(&packet, keyHead, headLength);
if (PROTOCOL_HEAD != packet.mHead) {
LogError("Protocol head unmatch.\n");
return CreateStatusCode(STATUS_CODE_NOT_OK);
}
dataLength = packet.mLength;
return CreateStatusCode(STATUS_CODE_OK);
}

View File

@ -14,6 +14,7 @@
*/
#ifndef PROTOCOL_HANDLE_H
#define PROTOCOL_HANDLE_H
#include "StatusCode.h"
#include <memory>
enum PROTOCOL_COMMAND
{
@ -53,5 +54,8 @@ public:
public:
static std::shared_ptr<ProtocolHandle> CreateProtocolData(const std::shared_ptr<VProtocolParam> &param);
static void ProtocolAnalysis(const void *data, const size_t &length);
static size_t GetKeyHeadLength(void);
static StatusCode GetDataLength(const void *keyHead, const size_t &headLength, size_t &dataLength);
};
#endif