*add unit test.

This commit is contained in:
Gatsby Van
2024-01-24 11:42:57 +08:00
parent be2c11d229
commit 8bfff9431a
2 changed files with 367 additions and 0 deletions
@@ -0,0 +1,366 @@
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
#include "error.h"
#include "unit_test_framework.h"
#include "time_ctrl/time_ctrl.h"
#include "networking/phy_layer/phy_layer.h"
#include "networking/link_layer/link_layer.h"
#include "networking/link_layer/link_layer_types.h"
#include "networking/link_layer/msg_def.h"
#define TIME_INT_REG (0x00000008 >> 2)
#define TIME_FRAC_REG (0x0000000C >> 2)
#define TIME_ADJ_INT (0x0000001C >> 2)
#define TIME_ADJ_FRAC (0x00000020 >> 2)
#define TIME_ADJ_TRIG (0x00000024 >> 2)
#define CNTSTEP_OPT (0x00000028 >> 2)
#define SIM_STEP (TIME_FRAC_MAX/100)
TMC_INST *tmcInstPtr = NULL;
PHY_INST *phyInstPtr = NULL;
L2_INST *linkInstPtr = NULL;
uint32_t tmcReg[32] = {0};
uint32_t phycReg[512] = {0};
L2_CONFIG l2Config =
{
.myType = L2_NODE_HEAD,
.isInterHead = false,
.myId = 1,
.clustId = 1,
.headId = 1,
.bkpHeadId = 1,
.netScale = 2,
.phyInstPtr = NULL,
.tmcInstPtr = NULL
};
PHY_CONFIG l1Config =
{
.devId = 0,
.txBramId = 0,
.rxBramId = 0,
.antBramId = 0,
.hwXadcId = 0,
.baseAddr = (uintptr_t)phycReg
};
TMC_CONFIG tmcConfig =
{
.baseAddr = (uintptr_t)tmcReg,
.reset = 10
};
int32_t rand_range(int32_t a, int32_t b);
inline int32_t rand_range(int32_t a, int32_t b)
{
ASSERT(b > a);
return (rand() % (b + 1 - a) + a);
}
void linklayer_setup(void)
{
int32_t Status;
Status = SysMonitor_Init();
ASSERT_EQUAL(SUCCESS, Status);
Status = TimeCtrl_Init(&tmcInstPtr, &tmcConfig);
ASSERT_EQUAL(SUCCESS, Status);
Status = Phy_InstInit(&phyInstPtr, &l1Config);
ASSERT_EQUAL(SUCCESS, Status);
// Update l2 config
l2Config.phyInstPtr = phyInstPtr;
l2Config.tmcInstPtr = tmcInstPtr;
Status = Linklayer_Init(&linkInstPtr, &l2Config);
ASSERT_EQUAL(SUCCESS, Status);
}
void linklayer_teardown(void)
{
Linklayer_Destroy(linkInstPtr);
Phy_Destroy(phyInstPtr);
TimeCtrl_Destroy(tmcInstPtr);
SysMonitor_Destroy();
}
void forge_adv_frame(uint8_t *buff, uint8_t srcId, uint8_t destId,
uint32_t frameNum, uint32_t slotNum, uint32_t netStartTime)
{
uint8_t type = L2_ADV_FRAME;
L2_FrameInsertChunk(buff, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &type);
L2_FrameInsertChunk(buff, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum);
L2_FrameInsertChunk(buff, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum);
L2_FrameInsertChunk(buff, L2_MSG_SRC_ID, L2_MSG_SRC_ID_LEN, &srcId);
L2_FrameInsertChunk(buff, L2_MSG_DST_ID, L2_MSG_DST_ID_LEN, &destId);
float testData = 3.14;
L2_FrameInsertChunk(buff, L2_MSG_ADV_SRC_POSX, L2_MSG_ADV_SRC_POSX_LEN, &testData);
L2_FrameInsertChunk(buff, L2_MSG_ADV_SRC_POSY, L2_MSG_ADV_SRC_POSY_LEN, &testData);
L2_FrameInsertChunk(buff, L2_MSG_ADV_SRC_POSZ, L2_MSG_ADV_SRC_POSZ_LEN, &testData);
// Insert net start time
L2_FrameInsertChunk(buff, L2_MSG_ADV_SRC_NETSTART_TIME, L2_MSG_ADV_SRC_NETSTART_TIME_LEN, &netStartTime);
// Append CRC
if (L2_CrcAppend(buff, L2_ADV_PACK_LEN - L2_MSG_ADV_SVC_CRC_LEN, L2_MSG_ADV_SVC_CRC, L2_CRC16_1021) != SUCCESS)
{
DBG_ERROR("Fail to append CRC.\n");
ASSERT(false);
}
}
void forge_cfm_frame(uint8_t *buff, uint16_t srcId, uint16_t destId,
uint32_t frameNum, uint32_t slotNum)
{
uint8_t type = L2_CFM_FRAME;
L2_FrameInsertChunk(buff, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &type);
L2_FrameInsertChunk(buff, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum);
L2_FrameInsertChunk(buff, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum);
L2_FrameInsertChunk(buff, L2_MSG_SRC_ID, L2_MSG_SRC_ID_LEN, &srcId);
L2_FrameInsertChunk(buff, L2_MSG_DST_ID, L2_MSG_DST_ID_LEN, &destId);
float testData = 3.14;
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_POSX, L2_MSG_CFM_SRC_POSX_LEN, &testData);
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_POSY, L2_MSG_CFM_SRC_POSY_LEN, &testData);
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_POSZ, L2_MSG_CFM_SRC_POSZ_LEN, &testData);
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_SPEEDX, L2_MSG_CFM_SRC_SPEEDX_LEN, &testData);
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_SPEEDY, L2_MSG_CFM_SRC_SPEEDY_LEN, &testData);
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_SPEEDZ, L2_MSG_CFM_SRC_SPEEDZ_LEN, &testData);
if (L2_CrcAppend(buff, L2_CMF_PACK_LEN - L2_MSG_CFM_CRC_LEN, L2_MSG_CFM_CRC, L2_CRC16_1021) != SUCCESS)
{
DBG_ERROR("Fail to append CRC.\n");
ASSERT(false);
}
}
void forge_svc_frame(uint8_t *buff, uint16_t srcId, uint16_t destId,
uint32_t frameNum, uint32_t slotNum)
{
uint8_t type = L2_SVC_FRAME;
L2_FrameInsertChunk(buff, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &type);
L2_FrameInsertChunk(buff, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum);
L2_FrameInsertChunk(buff, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum);
L2_FrameInsertChunk(buff, L2_MSG_SRC_ID, L2_MSG_SRC_ID_LEN, &srcId);
L2_FrameInsertChunk(buff, L2_MSG_DST_ID, L2_MSG_DST_ID_LEN, &destId);
}
TEST(linklayer_reconfig)
{
int32_t Status;
Status = Linklayer_Reconfig(linkInstPtr, &l2Config);
ASSERT_EQUAL(SUCCESS, Status);
ASSERT_EQUAL(false, linkInstPtr->isEnable);
ASSERT_EQUAL(false, linkInstPtr->isEnable);
ASSERT_EQUAL(0, linkInstPtr->nodeList->len);
ASSERT_EQUAL(0, linkInstPtr->schdEventPool->envCnt);
}
TEST(linklayer_master_routine)
{
int32_t Status;
l2Config.myType = L2_NODE_HEAD;
l2Config.myId = 1;
Status = Linklayer_Reconfig(linkInstPtr, &l2Config);
ASSERT_EQUAL(SUCCESS, Status);
Linklayer_Start(linkInstPtr);
// 6 seconds
for (int i = 0; i < 6 * L2_SLOTS_PER_FRAME; i++)
{
tmcReg[TIME_INT_REG]++;
uint32_t slotNum = tmcReg[TIME_INT_REG]%L2_SLOTS_PER_FRAME;
if (L2_GetCurrentTor(linkInstPtr) == L2_TOR_RX)
{
if (L2_GetCurrentFrameType(linkInstPtr) == L2_ADV_FRAME && slotNum % 4 == 1)
{
forge_adv_frame((uint8_t *)phyInstPtr->recvDataAddr, 1, 2, 0, 0, 0);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, L2_ADV_PACK_LEN);
PhyWrite(phyInstPtr, COASE_FREQEST, COASE_TYPE_10KBPS_20MS);
}
if (L2_GetCurrentFrameType(linkInstPtr) == L2_CFM_FRAME && slotNum % 4 == 1)
{
forge_cfm_frame((uint8_t *)phyInstPtr->recvDataAddr, 2, 1,
L2_GetCurrentFrameNum(linkInstPtr), L2_GetCurrentSlotNum(linkInstPtr) - 4);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, L2_CMF_PACK_LEN);
PhyWrite(phyInstPtr, COASE_FREQEST, COASE_TYPE_40KBPS_20MS);
}
if (L2_GetCurrentFrameType(linkInstPtr) == L2_SVC_FRAME && slotNum % 4 == 1)
{
forge_svc_frame((uint8_t *)phyInstPtr->recvDataAddr, 2, 1,
L2_GetCurrentFrameNum(linkInstPtr), L2_GetCurrentSlotNum(linkInstPtr) - 4);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, L2_SVC_PACK_LEN);
PhyWrite(phyInstPtr, COASE_FREQEST, COASE_TYPE_40KBPS_20MS);
}
}
else
{
PhyWrite(phyInstPtr, TXRX_STATE, 0x02020202);
}
if (PhyRead(phyInstPtr, TXRX_STATE) != 0x02020202)
{
Phy_UpdateState(phyInstPtr);
PhyWrite(phyInstPtr, TXRX_STATE, 0x02020202);
}
Status = Linklayer_Proc(linkInstPtr);
if ((tmcReg[TIME_INT_REG] + 1) / 200 < linkInstPtr->netStartTime)
{
ASSERT_EQUAL(EIGNORE, Status);
}
else
{
ASSERT_EQUAL(SUCCESS, Status);
}
if (L2_isDataAvail(linkInstPtr))
{
if (L2_GetLastOptFrameType(linkInstPtr) == L2_CFM_FRAME)
{
ASSERT_EQUAL(1, L2_GetNodeListLen(linkInstPtr->nodeList));
ASSERT_TRUE(L2_isNodeInList(linkInstPtr->nodeList, 2));
}
}
}
}
TEST(linklayer_slave_netsetup)
{
int32_t Status;
TIME_WORD advTime;
uint32_t netStart;
uint32_t frameSyncSlot;
// 30 seconds
l2Config.myType = L2_NODE_MEMBER;
l2Config.myId = 2;
Status = Linklayer_Reconfig(linkInstPtr, &l2Config);
tmcReg[TIME_FRAC_REG] = rand_range(0, TIME_FRAC_MAX)/SIM_STEP*SIM_STEP;
tmcReg[TIME_INT_REG] = rand_range(0, 60 * L2_SLOTS_PER_FRAME); // 0~60s
advTime.frac_part = rand_range(0, TIME_FRAC_MAX)/SIM_STEP*SIM_STEP;
advTime.int_part = rand_range(tmcReg[TIME_INT_REG], tmcReg[TIME_INT_REG] + 5 * L2_SLOTS_PER_FRAME);
// 74 is the index of bm frame in routine table.
netStart = advTime.int_part / L2_SLOTS_PER_FRAME + rand_range(-4, 0);
Linklayer_Start(linkInstPtr);
for (int i = 0; i < 12 * L2_SLOTS_PER_FRAME * TIME_FRAC_MAX; i += SIM_STEP)
{
tmcReg[TIME_FRAC_REG] += SIM_STEP;
if (tmcReg[TIME_FRAC_REG] >= TIME_FRAC_MAX)
{
tmcReg[TIME_FRAC_REG] = 0;
tmcReg[TIME_INT_REG]++;
}
uint32_t slotNum = (tmcReg[TIME_INT_REG] - advTime.int_part%L2_SLOTS_PER_FRAME) % L2_SLOTS_PER_FRAME;
if (L2_GetNextTor(linkInstPtr) == L2_TOR_TX)
{
// TODO:
}
if (L2_GetCurrentTor(linkInstPtr) == L2_TOR_RX)
{
if (tmcReg[TIME_FRAC_REG] == advTime.frac_part && tmcReg[TIME_INT_REG] == advTime.int_part + 4)
{
frameSyncSlot = advTime.int_part;
forge_adv_frame((uint8_t *)phyInstPtr->recvDataAddr, 1, 2, netStart, 74, netStart);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, L2_ADV_PACK_LEN);
PhyWrite(phyInstPtr, COASE_FREQEST, COASE_TYPE_10KBPS_20MS);
PhyWrite(phyInstPtr, FSTIME_H, frameSyncSlot);
PhyWrite(phyInstPtr, FSTIME_L, Phy_GetTimeComp(L1_10KBPS_20MS_FRAME));
}
if (L2_GetCurrentFrameType(linkInstPtr) == L2_CFM_FRAME && slotNum % 4 == 1)
{
frameSyncSlot = L2_GetCurrentFrameNum(linkInstPtr) * L2_SLOTS_PER_FRAME
+ L2_GetCurrentSlotNum(linkInstPtr) - 4;
forge_cfm_frame((uint8_t *)phyInstPtr->recvDataAddr, 1, 2,
frameSyncSlot/L2_SLOTS_PER_FRAME, frameSyncSlot%L2_SLOTS_PER_FRAME);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, L2_CMF_PACK_LEN);
PhyWrite(phyInstPtr, COASE_FREQEST, COASE_TYPE_40KBPS_20MS);
PhyWrite(phyInstPtr, FSTIME_H, frameSyncSlot);
PhyWrite(phyInstPtr, FSTIME_L, Phy_GetTimeComp(L1_10KBPS_20MS_FRAME));
}
if (L2_GetCurrentFrameType(linkInstPtr) == L2_SVC_FRAME && slotNum % 4 == 1)
{
frameSyncSlot = L2_GetCurrentFrameNum(linkInstPtr) * L2_SLOTS_PER_FRAME
+ L2_GetCurrentSlotNum(linkInstPtr) - 4;
forge_svc_frame((uint8_t *)phyInstPtr->recvDataAddr, 1, 2,
frameSyncSlot/L2_SLOTS_PER_FRAME, frameSyncSlot%L2_SLOTS_PER_FRAME);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, L2_SVC_PACK_LEN);
PhyWrite(phyInstPtr, COASE_FREQEST, COASE_TYPE_40KBPS_20MS);
PhyWrite(phyInstPtr, FSTIME_H, frameSyncSlot);
PhyWrite(phyInstPtr, FSTIME_L, Phy_GetTimeComp(L1_10KBPS_20MS_FRAME));
}
}
else
{
PhyWrite(phyInstPtr, TXRX_STATE, 0x02020202);
}
if (PhyRead(phyInstPtr, TXRX_STATE) != 0x02020202)
{
Phy_UpdateState(phyInstPtr);
PhyWrite(phyInstPtr, TXRX_STATE, 0x02020202);
}
// 2ms interrupt
if (tmcReg[TIME_FRAC_REG] == 200000)
{
Status = Linklayer_Proc(linkInstPtr);
if ((tmcReg[TIME_INT_REG] + 1) / 200 < linkInstPtr->netStartTime)
{
ASSERT_EQUAL(EIGNORE, Status);
}
else
{
ASSERT_EQUAL(SUCCESS, Status);
}
if (L2_isDataAvail(linkInstPtr))
{
if (L2_GetLastFrameType(linkInstPtr) == L2_CFM_FRAME)
{
ASSERT_EQUAL(1, L2_GetNodeListLen(linkInstPtr->nodeList));
ASSERT_TRUE(L2_isNodeInList(linkInstPtr->nodeList, 1));
}
}
}
}
}
TEST_SUITE(linklayer_unit_test)
{
TEST_SUITE_CONFIGURE(linklayer_setup, linklayer_teardown);
RUN_TEST(linklayer_reconfig);
RUN_TEST(linklayer_master_routine);
RUN_TEST(linklayer_slave_netsetup);
}
int main(void)
{
RUN_TEST_SUITE(linklayer_unit_test);
TEST_REPORT();
return TEST_EXIT_CODE;
}
+1
View File
@@ -0,0 +1 @@
../../unit_test_framework.h