Changes requested during the initial review
This commit is contained in:
parent
53e65e566a
commit
c4c6ac8bb3
8 changed files with 186 additions and 89 deletions
|
@ -21,42 +21,42 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct crcslottask_t {
|
||||
struct crctask_t {
|
||||
void * volatile address;
|
||||
uint16_t wordCount;
|
||||
void (*callback)(void*, uint32_t, uint8_t);
|
||||
void *callbackParam;
|
||||
};
|
||||
|
||||
struct crcslotlistitem_t {
|
||||
struct crcslot_t {
|
||||
uint16_t count;
|
||||
struct crcslotlistitem_t *next;
|
||||
struct crcslottask_t *tasks;
|
||||
struct crcslot_t *next;
|
||||
struct crctask_t *tasks;
|
||||
};
|
||||
|
||||
struct crcstatus_t {
|
||||
CRC_TypeDef *crcUnit;
|
||||
struct dmainfo_t dmaInfo;
|
||||
struct crcslotlistitem_t *activeSlot;
|
||||
struct crcslot_t *activeSlot;
|
||||
uint8_t activeTask;
|
||||
struct crcslotlistitem_t *firstSlot;
|
||||
struct crcslot_t *firstSlot;
|
||||
};
|
||||
|
||||
void Crc_InitStatus(struct crcstatus_t *status, CRC_TypeDef *crcUnit, DMA_TypeDef *dma, uint32_t stream);
|
||||
|
||||
uint8_t Crc_GetActiveTask(struct crcslotlistitem_t **slot_out, struct crcstatus_t volatile *status);
|
||||
uint8_t Crc_GetActiveTask(struct crcslot_t **slot_out, struct crcstatus_t volatile *status);
|
||||
|
||||
uint8_t Crc_IsSlotQueued(struct crcslotlistitem_t *slot, uint8_t task);
|
||||
uint8_t Crc_IsTaskQueued(struct crcslot_t *slot, uint8_t task);
|
||||
|
||||
uint8_t Crc_IsSlotBusy(struct crcslotlistitem_t *slot, uint8_t task);
|
||||
uint8_t Crc_IsTaskBusy(struct crcslot_t *slot, uint8_t task);
|
||||
|
||||
void Crc_WaitResults(struct crcstatus_t *status, struct crcslotlistitem_t *slot, uint8_t task);
|
||||
void Crc_WaitResults(struct crcstatus_t *status, struct crcslot_t *slot, uint8_t task);
|
||||
|
||||
void Crc_AttachTask(struct crcstatus_t *status, struct crcslotlistitem_t *slot, struct crcslottask_t *tasks, uint8_t taskCount);
|
||||
void Crc_AttachTasks(struct crcstatus_t *status, struct crcslot_t *slot, struct crctask_t *tasks, uint8_t taskCount);
|
||||
|
||||
uint8_t Crc_Enqueue(struct crcstatus_t *status, struct crcslotlistitem_t *slot, uint8_t task,
|
||||
uint8_t Crc_Enqueue(struct crcstatus_t *status, struct crcslot_t *slot, uint8_t task,
|
||||
void *address, uint16_t len, void (*callback)(void*, uint32_t, uint8_t), void* callbackParam);
|
||||
uint32_t Crc_Compute(struct crcstatus_t *status, struct crcslotlistitem_t *slot, uint8_t task, void *address, uint16_t len);
|
||||
uint32_t Crc_Compute(struct crcstatus_t *status, struct crcslot_t *slot, uint8_t task, void *address, uint16_t len);
|
||||
void Crc_HandleDmaIrq(struct crcstatus_t *status);
|
||||
|
||||
// !!!PRIVATE!!! exposed only to make mocking possible
|
||||
|
@ -66,10 +66,10 @@ void Crc_StartNextTask(struct crcstatus_t *status);
|
|||
#ifdef UNITTEST
|
||||
DECLARE_MOCK(Crc_InitStatus);
|
||||
DECLARE_MOCK(Crc_GetActiveTask);
|
||||
DECLARE_MOCK(Crc_IsSlotQueued);
|
||||
DECLARE_MOCK(Crc_IsSlotBusy);
|
||||
DECLARE_MOCK(Crc_IsTaskQueued);
|
||||
DECLARE_MOCK(Crc_IsTaskBusy);
|
||||
DECLARE_MOCK(Crc_WaitResults);
|
||||
DECLARE_MOCK(Crc_AttachTask);
|
||||
DECLARE_MOCK(Crc_AttachTasks);
|
||||
DECLARE_MOCK(Crc_Enqueue);
|
||||
DECLARE_MOCK(Crc_Compute);
|
||||
DECLARE_MOCK(Crc_HandleDmaIrq);
|
||||
|
|
|
@ -104,8 +104,8 @@ struct usartstatus_t {
|
|||
struct dmainfo_t rxDmaInfo;
|
||||
struct dmainfo_t txDmaInfo;
|
||||
struct crcstatus_t *crcStatus;
|
||||
struct crcslotlistitem_t crcSlot;
|
||||
struct crcslottask_t crcTasks[2];
|
||||
struct crcslot_t crcSlot;
|
||||
struct crctask_t crcTasks[2];
|
||||
|
||||
uint8_t rxSerial;
|
||||
uint8_t txSerial;
|
||||
|
|
|
@ -46,7 +46,7 @@ void MOCKABLE(Crc_InitStatus)(struct crcstatus_t *st, CRC_TypeDef *crcUnit, DMA_
|
|||
}
|
||||
|
||||
|
||||
void MOCKABLE(Crc_AttachTask)(struct crcstatus_t *status, struct crcslotlistitem_t *slot, struct crcslottask_t *tasks, uint8_t taskCount)
|
||||
void MOCKABLE(Crc_AttachTasks)(struct crcstatus_t *status, struct crcslot_t *slot, struct crctask_t *tasks, uint8_t taskCount)
|
||||
{
|
||||
slot->count = taskCount;
|
||||
slot->tasks = tasks;
|
||||
|
@ -60,7 +60,7 @@ void MOCKABLE(Crc_AttachTask)(struct crcstatus_t *status, struct crcslotlistitem
|
|||
}
|
||||
|
||||
|
||||
uint8_t MOCKABLE(Crc_GetActiveTask)(struct crcslotlistitem_t **slot_out, struct crcstatus_t volatile *status)
|
||||
uint8_t MOCKABLE(Crc_GetActiveTask)(struct crcslot_t **slot_out, struct crcstatus_t volatile *status)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
|
@ -69,36 +69,36 @@ uint8_t MOCKABLE(Crc_GetActiveTask)(struct crcslotlistitem_t **slot_out, struct
|
|||
__disable_irq();
|
||||
ret = status->activeTask;
|
||||
if(slot_out)
|
||||
*slot_out = (struct crcslotlistitem_t *) status->activeSlot;
|
||||
*slot_out = (struct crcslot_t *) status->activeSlot;
|
||||
__set_PRIMASK(prim);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint8_t MOCKABLE(Crc_IsSlotQueued)(struct crcslotlistitem_t *slot, uint8_t task) {
|
||||
return ((struct crcslottask_t volatile)slot->tasks[task]).address != NULL;
|
||||
uint8_t MOCKABLE(Crc_IsTaskQueued)(struct crcslot_t *slot, uint8_t task) {
|
||||
return ((struct crctask_t volatile)slot->tasks[task]).address != NULL;
|
||||
}
|
||||
|
||||
|
||||
uint8_t MOCKABLE(Crc_IsSlotBusy)(struct crcslotlistitem_t *slot, uint8_t task) {
|
||||
struct crcslottask_t volatile *taskPtr = &slot->tasks[task];
|
||||
uint8_t MOCKABLE(Crc_IsTaskBusy)(struct crcslot_t *slot, uint8_t task) {
|
||||
struct crctask_t volatile *taskPtr = &slot->tasks[task];
|
||||
return taskPtr->callback != NULL || taskPtr->callbackParam != NULL;
|
||||
}
|
||||
|
||||
|
||||
void MOCKABLE(Crc_WaitResults)(struct crcstatus_t *status, struct crcslotlistitem_t *slot, uint8_t task) {
|
||||
while(Crc_IsSlotBusy(slot, task));
|
||||
void MOCKABLE(Crc_WaitResults)(struct crcstatus_t *status, struct crcslot_t *slot, uint8_t task) {
|
||||
while(Crc_IsTaskBusy(slot, task));
|
||||
}
|
||||
|
||||
|
||||
uint8_t MOCKABLE(Crc_Enqueue)(struct crcstatus_t *status, struct crcslotlistitem_t *slot, uint8_t task,
|
||||
uint8_t MOCKABLE(Crc_Enqueue)(struct crcstatus_t *status, struct crcslot_t *slot, uint8_t task,
|
||||
void *address, uint16_t len, void (*callback)(void*, uint32_t, uint8_t), void* callbackParam)
|
||||
{
|
||||
uint32_t prim = __get_PRIMASK();
|
||||
uint16_t need_start;
|
||||
struct crcstatus_t volatile *st = status;
|
||||
|
||||
while(Crc_IsSlotBusy(slot, task));
|
||||
while(Crc_IsTaskBusy(slot, task));
|
||||
__disable_irq();
|
||||
need_start = (st->activeSlot == NULL);
|
||||
slot->tasks[task].address = need_start ? NULL : address;
|
||||
|
@ -123,11 +123,11 @@ uint8_t MOCKABLE(Crc_Enqueue)(struct crcstatus_t *status, struct crcslotlistitem
|
|||
}
|
||||
|
||||
|
||||
uint32_t MOCKABLE(Crc_Compute)(struct crcstatus_t *status, struct crcslotlistitem_t *slot, uint8_t task, void *address, uint16_t len)
|
||||
uint32_t MOCKABLE(Crc_Compute)(struct crcstatus_t *status, struct crcslot_t *slot, uint8_t task, void *address, uint16_t len)
|
||||
{
|
||||
uint32_t result;
|
||||
Crc_Enqueue(status, slot, task, address, len, NULL, &result);
|
||||
while((struct crcslotlistitem_t volatile *)slot->tasks[task].callbackParam);
|
||||
while((struct crcslot_t volatile *)slot->tasks[task].callbackParam);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ void MOCKABLE(Crc_StartNextTask)(struct crcstatus_t *status)
|
|||
uint8_t index = 0;
|
||||
|
||||
do {
|
||||
struct crcslotlistitem_t *slot = status->firstSlot;
|
||||
struct crcslot_t *slot = status->firstSlot;
|
||||
moreTasks = 0;
|
||||
while(slot) {
|
||||
if(index < slot->count) {
|
||||
|
@ -178,7 +178,7 @@ void MOCKABLE(Crc_HandleDmaIrq)(struct crcstatus_t *status)
|
|||
*status->dmaInfo.ifcReg = *status->dmaInfo.isReg & (status->dmaInfo.tcMask | status->dmaInfo.teMask);
|
||||
LL_DMA_DisableStream(status->dmaInfo.dma, status->dmaInfo.stream);
|
||||
if(status->activeSlot) {
|
||||
struct crcslottask_t *tsk = &status->activeSlot->tasks[status->activeTask];
|
||||
struct crctask_t *tsk = &status->activeSlot->tasks[status->activeTask];
|
||||
if(tsk->callback)
|
||||
tsk->callback(tsk->callbackParam, status->crcUnit->DR, success);
|
||||
else if(tsk->callbackParam)
|
||||
|
|
|
@ -112,7 +112,7 @@ void MOCKABLE(Pu_Init)(
|
|||
st->txSerial = 0;
|
||||
st->activeRxBuf = 0;
|
||||
st->crcStatus = crcStatus;
|
||||
Crc_AttachTask(crcStatus, &st->crcSlot, st->crcTasks, 2);
|
||||
Crc_AttachTasks(crcStatus, &st->crcSlot, st->crcTasks, 2);
|
||||
memset(&st->stats, 0, sizeof(st->stats));
|
||||
|
||||
*Dma_GetIfcReg(dma, stream_rx) =
|
||||
|
@ -161,7 +161,7 @@ uint8_t MOCKABLE(Pu_Post)(struct usartstatus_t *status, uint8_t const *payload,
|
|||
status->txBuffer.error = 0;
|
||||
Crc_Enqueue(status->crcStatus, &status->crcSlot, 0, &status->txBuffer.packet, sizeof(status->txBuffer.packet.header) + payloadLength,
|
||||
NULL, (uint32_t*)(status->txBuffer.packet.payload + payloadLength));
|
||||
while(waitForCrcQueue && Crc_IsSlotQueued(&status->crcSlot, 0));
|
||||
while(waitForCrcQueue && Crc_IsTaskQueued(&status->crcSlot, 0));
|
||||
Pu_SetupTransmit(status->usart, status->txDmaInfo.dma, status->txDmaInfo.stream, &status->txBuffer.packet, status->txBuffer.requestedLength);
|
||||
|
||||
StatsIncSent(&status->stats);
|
||||
|
|
|
@ -25,8 +25,8 @@ DMA_TypeDef * DMA2 __attribute__((weak));
|
|||
|
||||
static DMA_TypeDef dma1, dma2;
|
||||
static crcstatus_t crcStatus;
|
||||
static crcslotlistitem_t slot1, slot2;
|
||||
static crcslottask_t tasks1[2], tasks2[2];
|
||||
static crcslot_t slot1, slot2;
|
||||
static crctask_t tasks1[2], tasks2[2];
|
||||
static CRC_TypeDef fakeCrc;
|
||||
|
||||
static DMA_TypeDef *expectedDma;
|
||||
|
@ -49,7 +49,7 @@ DEFINE_MOCK(__set_PRIMASK, mock, uint32_t primask) {
|
|||
LEAVE_MOCK;
|
||||
}
|
||||
|
||||
DEFINE_MOCK_VAR(crcslotlistitem_t *, __disable_irq, mock, compare);
|
||||
DEFINE_MOCK_VAR(crcslot_t *, __disable_irq, mock, compare);
|
||||
DEFINE_MOCK(__disable_irq, mock) {
|
||||
if(!MOCK_VAR(__disable_irq, mock, callcount)) {
|
||||
EXPECT_EQ(crcStatus.firstSlot, MOCK_VAR(__disable_irq, mock, compare));
|
||||
|
@ -157,7 +157,7 @@ TEST(CrcScheduler, AttachTask_single)
|
|||
DMA2 = &dma2;
|
||||
Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
|
||||
|
||||
Crc_AttachTask(&crcStatus, &slot1, tasks1, 2);
|
||||
Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
|
||||
|
||||
EXPECT_EQ(MOCK_VAR(__get_PRIMASK, mock, callcount), 1);
|
||||
EXPECT_EQ(MOCK_VAR(__set_PRIMASK, mock, callcount), 1);
|
||||
|
@ -168,6 +168,7 @@ TEST(CrcScheduler, AttachTask_single)
|
|||
EXPECT_EQ(crcStatus.activeSlot, nullptr);
|
||||
}
|
||||
|
||||
// Are tasks attached in the expected order internally
|
||||
TEST(CrcScheduler, AttachTask_multiple)
|
||||
{
|
||||
ACTIVATE_MOCK_RV(__get_PRIMASK, mock, 1);
|
||||
|
@ -178,9 +179,9 @@ TEST(CrcScheduler, AttachTask_multiple)
|
|||
DMA2 = &dma2;
|
||||
Crc_InitStatus(&crcStatus, NULL, DMA2, LL_DMA_STREAM_4);
|
||||
|
||||
Crc_AttachTask(&crcStatus, &slot1, tasks1, 2);
|
||||
Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
|
||||
MOCK_STORE(__disable_irq, mock, compare, &slot1);
|
||||
Crc_AttachTask(&crcStatus, &slot2, tasks2, 2);
|
||||
Crc_AttachTasks(&crcStatus, &slot2, tasks2, 2);
|
||||
|
||||
EXPECT_EQ(__get_PRIMASK_mock_callcount, 2);
|
||||
EXPECT_EQ(__set_PRIMASK_mock_callcount, 2);
|
||||
|
@ -192,6 +193,7 @@ TEST(CrcScheduler, AttachTask_multiple)
|
|||
EXPECT_EQ(crcStatus.activeSlot, nullptr);
|
||||
}
|
||||
|
||||
// No blocking should occur if the the task is not busy
|
||||
TEST(CrcScheduler, Enqueue_nowait)
|
||||
{
|
||||
uint32_t fakeCrcResult;
|
||||
|
@ -204,7 +206,7 @@ TEST(CrcScheduler, Enqueue_nowait)
|
|||
memset(&fakeCrc, 0, sizeof(fakeCrc));
|
||||
|
||||
Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
|
||||
Crc_AttachTask(&crcStatus, &slot1, tasks1, 2);
|
||||
Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
|
||||
expectedLength = 2;
|
||||
|
||||
ACTIVATE_MOCK(LL_DMA_SetM2MSrcAddress, mock);
|
||||
|
@ -233,6 +235,9 @@ TEST(CrcScheduler, Enqueue_nowait)
|
|||
EXPECT_EQ(MOCK_VAR(LL_DMA_EnableStream, mock, callcount), 1);
|
||||
}
|
||||
|
||||
// When trying to enqueue for a busy task it should blok firs
|
||||
// then when the previously blocked task finishes it should
|
||||
// enqueue the new one
|
||||
TEST(CrcScheduler, Enqueue_shouldblockthencontinue)
|
||||
{
|
||||
uint8_t testData[] = "qwerty";
|
||||
|
@ -242,7 +247,7 @@ TEST(CrcScheduler, Enqueue_shouldblockthencontinue)
|
|||
memset(&fakeCrc, 0, sizeof(fakeCrc));
|
||||
|
||||
Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
|
||||
Crc_AttachTask(&crcStatus, &slot1, tasks1, 2);
|
||||
Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
|
||||
Crc_Enqueue(&crcStatus, &slot1, 0, testData, sizeof(testData), FakeCallback_1, &fakeCrcResult);
|
||||
|
||||
// black magic to test if the function blocks (at least for 100ms)
|
||||
|
@ -265,6 +270,7 @@ TEST(CrcScheduler, Enqueue_shouldblockthencontinue)
|
|||
pthread_cancel(th);
|
||||
}
|
||||
|
||||
// StartNextTask should start the scheduled tasks in predefined order
|
||||
TEST(CrcScheduler, Crc_StartNextTask)
|
||||
{
|
||||
uint8_t testData[] = "qwerty";
|
||||
|
@ -275,8 +281,8 @@ TEST(CrcScheduler, Crc_StartNextTask)
|
|||
memset(&fakeCrc, 0, sizeof(fakeCrc));
|
||||
|
||||
Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
|
||||
Crc_AttachTask(&crcStatus, &slot1, tasks1, 2);
|
||||
Crc_AttachTask(&crcStatus, &slot2, tasks2, 2);
|
||||
Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
|
||||
Crc_AttachTasks(&crcStatus, &slot2, tasks2, 2);
|
||||
Crc_Enqueue(&crcStatus, &slot1, 0, testData, sizeof(testData), FakeCallback_1, &fakeCrcResult1);
|
||||
Crc_Enqueue(&crcStatus, &slot1, 1, testData, sizeof(testData), FakeCallback_2, &fakeCrcResult2);
|
||||
Crc_Enqueue(&crcStatus, &slot2, 0, testData, sizeof(testData), FakeCallback_3, &fakeCrcResult3);
|
||||
|
@ -314,6 +320,8 @@ TEST(CrcScheduler, Crc_StartNextTask)
|
|||
EXPECT_EQ(LL_DMA_EnableStream_mock_callcount, 2);
|
||||
}
|
||||
|
||||
// HandleDmaIrq should start the next scheduled task or
|
||||
// disable the CRC DMA engine if there is no other task scheduled.
|
||||
TEST(CrcScheduler, HandleDmaIrq_callback)
|
||||
{
|
||||
uint8_t testData[] = "qwerty";
|
||||
|
@ -327,8 +335,8 @@ TEST(CrcScheduler, HandleDmaIrq_callback)
|
|||
fakeCrc.DR = 0xa5a55a5a;
|
||||
|
||||
Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
|
||||
Crc_AttachTask(&crcStatus, &slot1, tasks1, 2);
|
||||
Crc_AttachTask(&crcStatus, &slot2, tasks2, 2);
|
||||
Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
|
||||
Crc_AttachTasks(&crcStatus, &slot2, tasks2, 2);
|
||||
Crc_Enqueue(&crcStatus, &slot1, 1, testData, sizeof(testData), FakeCallbackCheck, &FakeCustomData1);
|
||||
// we need to set this up here to check if HandleDmaIrq calls Crc_StartNextTask or not;
|
||||
Crc_Enqueue(&crcStatus, &slot2, 0, testData, sizeof(testData), FakeCallbackCheck, &FakeCustomData2);
|
||||
|
@ -367,46 +375,51 @@ TEST(CrcScheduler, HandleDmaIrq_callback)
|
|||
EXPECT_EQ(LL_DMA_DisableStream_mock_callcount, 2);
|
||||
}
|
||||
|
||||
TEST(CrcScheduler, IsSlotQueued)
|
||||
// Crc_StartNextTask starts executing the next task and removes it from the queue
|
||||
// Test if IsTaskQueued reflects this behaviour correctly
|
||||
TEST(CrcScheduler, IsTaskQueued)
|
||||
{
|
||||
uint8_t testData[] = "qwerty";
|
||||
uint32_t FakeCustomData1;
|
||||
|
||||
Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
|
||||
Crc_AttachTask(&crcStatus, &slot1, tasks1, 2);
|
||||
Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
|
||||
Crc_Enqueue(&crcStatus, &slot1, 0, testData, sizeof(testData), FakeCallback_1, &FakeCustomData1);
|
||||
Crc_Enqueue(&crcStatus, &slot1, 1, testData, sizeof(testData), FakeCallback_1, &FakeCustomData1);
|
||||
|
||||
EXPECT_EQ(Crc_IsSlotQueued(&slot1, 0), 0);
|
||||
EXPECT_NE(Crc_IsSlotQueued(&slot1, 1), 0);
|
||||
EXPECT_EQ(Crc_IsTaskQueued(&slot1, 0), 0);
|
||||
EXPECT_NE(Crc_IsTaskQueued(&slot1, 1), 0);
|
||||
|
||||
Crc_StartNextTask(&crcStatus);
|
||||
|
||||
EXPECT_EQ(Crc_IsSlotQueued(&slot1, 1), 0);
|
||||
EXPECT_EQ(Crc_IsTaskQueued(&slot1, 1), 0);
|
||||
}
|
||||
|
||||
TEST(CrcScheduler, IsSlotBusy)
|
||||
// Crc_HandleDmaIrq completes the active task and start executing the next (by calling StartNextTask)
|
||||
// Crc_IsTaskBusy should reflect these changes
|
||||
TEST(CrcScheduler, IsTaskBusy)
|
||||
{
|
||||
uint8_t testData[] = "qwerty";
|
||||
uint32_t FakeCustomData1;
|
||||
|
||||
Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
|
||||
Crc_AttachTask(&crcStatus, &slot1, tasks1, 2);
|
||||
Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
|
||||
Crc_Enqueue(&crcStatus, &slot1, 0, testData, sizeof(testData), FakeCallback_1, &FakeCustomData1);
|
||||
Crc_Enqueue(&crcStatus, &slot1, 1, testData, sizeof(testData), FakeCallback_1, &FakeCustomData1);
|
||||
|
||||
EXPECT_NE(Crc_IsSlotBusy(&slot1, 0), 0);
|
||||
EXPECT_NE(Crc_IsSlotBusy(&slot1, 1), 0);
|
||||
EXPECT_NE(Crc_IsTaskBusy(&slot1, 0), 0);
|
||||
EXPECT_NE(Crc_IsTaskBusy(&slot1, 1), 0);
|
||||
|
||||
DMA2->HISR |= DMA_HISR_TCIF4;
|
||||
Crc_HandleDmaIrq(&crcStatus);
|
||||
|
||||
EXPECT_EQ(Crc_IsSlotBusy(&slot1, 0), 0);
|
||||
EXPECT_NE(Crc_IsSlotBusy(&slot1, 1), 0);
|
||||
EXPECT_EQ(Crc_IsTaskBusy(&slot1, 0), 0);
|
||||
EXPECT_NE(Crc_IsTaskBusy(&slot1, 1), 0);
|
||||
|
||||
DMA2->HISR |= DMA_HISR_TCIF4;
|
||||
Crc_HandleDmaIrq(&crcStatus);
|
||||
|
||||
EXPECT_EQ(Crc_IsSlotBusy(&slot1, 0), 0);
|
||||
EXPECT_EQ(Crc_IsSlotBusy(&slot1, 1), 0);
|
||||
EXPECT_EQ(Crc_IsTaskBusy(&slot1, 0), 0);
|
||||
EXPECT_EQ(Crc_IsTaskBusy(&slot1, 1), 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@ uint8_t testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
|||
//static struct usartstatus_t * expectedUsartStatus;
|
||||
static uint32_t expectedStreams[2] = { 0,7 };
|
||||
struct crcstatus_t *expectedCrcStatus;
|
||||
struct crcslotlistitem_t *expectedCrcSlotListItem;
|
||||
struct crcslottask_t *expectedTasks;
|
||||
struct crcslot_t *expectedCrcSlotListItem;
|
||||
struct crctask_t *expectedTasks;
|
||||
uint8_t expectedTaskCount;
|
||||
uint32_t expectedCrcLength;
|
||||
uint32_t expectedLength;
|
||||
|
@ -55,6 +55,8 @@ uint32_t expectedDirection;
|
|||
uint32_t fakePacketReceivedCallbackParam;
|
||||
|
||||
|
||||
// this isn't a real mov but we use the mockinginfrastructure
|
||||
// to automate administration (call count, etc)
|
||||
DEFINE_MOCK(FakePacketReceivedCallback, mock, void* userParam, struct usart_buffer_t *buffer)
|
||||
{
|
||||
EXPECT_EQ((void*)&fakePacketReceivedCallbackParam, userParam);
|
||||
|
@ -67,13 +69,13 @@ DEFINE_MOCK(Dma_Init, mock, struct dmainfo_t* dmaInfo, DMA_TypeDef *dma, uint32_
|
|||
LEAVE_MOCK
|
||||
}
|
||||
|
||||
DEFINE_MOCK(Crc_AttachTask, mock, struct crcstatus_t *status, struct crcslotlistitem_t *slot, struct crcslottask_t *tasks, uint8_t taskCount)
|
||||
DEFINE_MOCK(Crc_AttachTasks, mock, struct crcstatus_t *status, struct crcslot_t *slot, struct crctask_t *tasks, uint8_t taskCount)
|
||||
{
|
||||
EXPECT_EQ(status, expectedCrcStatus);
|
||||
EXPECT_EQ(slot, expectedCrcSlotListItem);
|
||||
EXPECT_EQ(tasks, expectedTasks);
|
||||
EXPECT_EQ(taskCount, expectedTaskCount);
|
||||
Crc_AttachTask__(status, slot, tasks, taskCount);
|
||||
Crc_AttachTasks__(status, slot, tasks, taskCount);
|
||||
LEAVE_MOCK
|
||||
}
|
||||
|
||||
|
@ -213,7 +215,7 @@ DEFINE_MOCK(LL_USART_ClearFlag_ORE, mock, USART_TypeDef *usart)
|
|||
LEAVE_MOCK
|
||||
}
|
||||
|
||||
DEFINE_MOCK_RET(uint8_t, Crc_Enqueue, mock, struct crcstatus_t *status, struct crcslotlistitem_t *slot, uint8_t task,
|
||||
DEFINE_MOCK_RET(uint8_t, Crc_Enqueue, mock, struct crcstatus_t *status, struct crcslot_t *slot, uint8_t task,
|
||||
void *address, uint16_t len, void (*callback)(void*, uint32_t, uint8_t), void* callbackParam)
|
||||
{
|
||||
EXPECT_EQ(expectedCrcLength, len);
|
||||
|
@ -221,9 +223,9 @@ DEFINE_MOCK_RET(uint8_t, Crc_Enqueue, mock, struct crcstatus_t *status, struct c
|
|||
RETURN_MOCK_PREDEF(Crc_Enqueue, mock);
|
||||
}
|
||||
|
||||
DEFINE_MOCK_RET(uint8_t, Crc_IsSlotQueued, mock, struct crcslotlistitem_t *slot, uint8_t task)
|
||||
DEFINE_MOCK_RET(uint8_t, Crc_IsTaskQueued, mock, struct crcslot_t *slot, uint8_t task)
|
||||
{
|
||||
RETURN_MOCK_PREDEF(Crc_IsSlotQueued, mock);
|
||||
RETURN_MOCK_PREDEF(Crc_IsTaskQueued, mock);
|
||||
}
|
||||
|
||||
DEFINE_MOCK(Pu_SetupTransmit, mock, USART_TypeDef *usart, DMA_TypeDef* dma, uint32_t stream, void *buffer, uint32_t length)
|
||||
|
@ -263,7 +265,7 @@ struct PacketUsart : public ::testing::Test {
|
|||
TEST_F(PacketUsart, Init)
|
||||
{
|
||||
ACTIVATE_MOCK(Dma_Init, mock);
|
||||
ACTIVATE_MOCK(Crc_AttachTask, mock);
|
||||
ACTIVATE_MOCK(Crc_AttachTasks, mock);
|
||||
ACTIVATE_MOCK(LL_DMA_EnableIT_TC, init);
|
||||
ACTIVATE_MOCK(LL_DMA_EnableIT_TE, init);
|
||||
ACTIVATE_MOCK(LL_USART_EnableIT_IDLE, mock);
|
||||
|
@ -303,6 +305,7 @@ TEST_F(PacketUsart, GetTxBuffer)
|
|||
EXPECT_EQ(Pu_GetTxBuffer(&usartStatus), (unsigned char*)&usartStatus.txBuffer.packet.payload);
|
||||
}
|
||||
|
||||
// SetupTransmit should set all engines (DMA, USART) up properly for starting the transmission
|
||||
TEST_F(PacketUsart, SetupTransmit)
|
||||
{
|
||||
Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
|
||||
|
@ -319,8 +322,15 @@ TEST_F(PacketUsart, SetupTransmit)
|
|||
ACTIVATE_MOCK_RV(LL_USART_DMA_GetRegAddr, mock, expectedDstAddress);
|
||||
|
||||
Pu_SetupTransmit(&fakeUsart, &fakeDma1, 7, testData, sizeof(testData));
|
||||
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_ConfigAddresses, mock), 1);
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_SetDataLength, mock), 1);
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(LL_DMA_EnableStream, mock), 1);
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_EnableDMAReq_TX, mock), 1);
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_DMA_GetRegAddr, mock), 1);
|
||||
}
|
||||
|
||||
// Testing Pu_Post, not waiting for the crc scheduler to start processing our block
|
||||
TEST_F(PacketUsart, Post_copy_nowait)
|
||||
{
|
||||
struct usartpacketheader_t expectedHeader = { 0x95, 0, sizeof(testData), 0x95 ^ 0 ^ sizeof(testData) };
|
||||
|
@ -333,7 +343,7 @@ TEST_F(PacketUsart, Post_copy_nowait)
|
|||
|
||||
ACTIVATE_MOCK_RV(Crc_Enqueue, mock, 1);
|
||||
ACTIVATE_MOCK(Pu_SetupTransmit, mock);
|
||||
ACTIVATE_MOCK_RV(Crc_IsSlotQueued, mock, 1);
|
||||
ACTIVATE_MOCK_RV(Crc_IsTaskQueued, mock, 1);
|
||||
|
||||
Pu_Post(&usartStatus, testData, sizeof(testData), &crcStatus, false);
|
||||
|
||||
|
@ -342,9 +352,10 @@ TEST_F(PacketUsart, Post_copy_nowait)
|
|||
EXPECT_EQ(memcmp(&usartStatus.txBuffer.packet.header, &expectedHeader, sizeof(expectedHeader)), 0);
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(Crc_Enqueue, mock), 1);
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(Pu_SetupTransmit, mock), 1);
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(Crc_IsSlotQueued, mock), 0);
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(Crc_IsTaskQueued, mock), 0);
|
||||
}
|
||||
|
||||
// Posting with free CRC engine (will execute our block immediately)
|
||||
TEST_F(PacketUsart, Post_copy_wait_nodelay)
|
||||
{
|
||||
expectedCrcLength = sizeof(usartStatus.txBuffer.packet.header) + 12;
|
||||
|
@ -356,13 +367,14 @@ TEST_F(PacketUsart, Post_copy_wait_nodelay)
|
|||
|
||||
ACTIVATE_MOCK_RV(Crc_Enqueue, mock, 1);
|
||||
ACTIVATE_MOCK(Pu_SetupTransmit, mock);
|
||||
ACTIVATE_MOCK_RV(Crc_IsSlotQueued, mock, 0);
|
||||
ACTIVATE_MOCK_RV(Crc_IsTaskQueued, mock, 0);
|
||||
|
||||
Pu_Post(&usartStatus, testData, sizeof(testData), &crcStatus, true);
|
||||
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(Crc_IsSlotQueued, mock), 1);
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(Crc_IsTaskQueued, mock), 1);
|
||||
}
|
||||
|
||||
// Posting with with busy CRC engine should block our call
|
||||
TEST_F(PacketUsart, Post_copy_wait_delay)
|
||||
{
|
||||
expectedCrcLength = sizeof(usartStatus.txBuffer.packet.header) + 12;
|
||||
|
@ -374,7 +386,7 @@ TEST_F(PacketUsart, Post_copy_wait_delay)
|
|||
|
||||
ACTIVATE_MOCK_RV(Crc_Enqueue, mock, 1);
|
||||
ACTIVATE_MOCK(Pu_SetupTransmit, mock);
|
||||
ACTIVATE_MOCK_RV(Crc_IsSlotQueued, mock, 1);
|
||||
ACTIVATE_MOCK_RV(Crc_IsTaskQueued, mock, 1);
|
||||
|
||||
// black magic to test if the function blocks (at least for 100ms)
|
||||
std::promise<bool> promiseFinished;
|
||||
|
@ -388,13 +400,14 @@ TEST_F(PacketUsart, Post_copy_wait_delay)
|
|||
th = t.native_handle();
|
||||
t.detach();
|
||||
EXPECT_EQ(futureResult.wait_for(std::chrono::milliseconds(100)), std::future_status::timeout);
|
||||
Crc_IsSlotQueued_mock_retval = 0;
|
||||
Crc_IsTaskQueued_mock_retval = 0;
|
||||
auto waitResult(futureResult.wait_for(std::chrono::milliseconds(100)));
|
||||
EXPECT_NE(waitResult, std::future_status::timeout);
|
||||
if(waitResult == std::future_status::timeout)
|
||||
pthread_cancel(th);
|
||||
}
|
||||
|
||||
// HandleTxDmaIrq_tc should enable USART TC interrupt and disable DMA stream
|
||||
TEST_F(PacketUsart, HandleTxDmaIrq_tc)
|
||||
{
|
||||
Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
|
||||
|
@ -414,6 +427,7 @@ TEST_F(PacketUsart, HandleTxDmaIrq_tc)
|
|||
EXPECT_EQ(fakeDma1.HIFCR, DMA_HIFCR_CTCIF7);
|
||||
}
|
||||
|
||||
// HandleTxDmaIrq_te should enable USART TC interrupt disable DMA stream and set the error flag
|
||||
TEST_F(PacketUsart, HandleTxDmaIrq_te)
|
||||
{
|
||||
Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
|
||||
|
@ -431,6 +445,8 @@ TEST_F(PacketUsart, HandleTxDmaIrq_te)
|
|||
EXPECT_EQ(usartStatus.txBuffer.error, 1);
|
||||
}
|
||||
|
||||
// HandleUsartIrq_tc should disable USART TC interrupt, pulse TX direction enabled to enforce an idle frame
|
||||
// and mark the tx buffer as free
|
||||
TEST_F(PacketUsart, HandleUsartIrq_tc)
|
||||
{
|
||||
Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
|
||||
|
@ -452,7 +468,8 @@ TEST_F(PacketUsart, HandleUsartIrq_tc)
|
|||
EXPECT_EQ(usartStatus.txBuffer.busy, 0);
|
||||
}
|
||||
|
||||
TEST_F(PacketUsart, setupReceive)
|
||||
// SetupReceive must set USART and DMA engine up for reception
|
||||
TEST_F(PacketUsart, SetupReceive)
|
||||
{
|
||||
Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
|
||||
expectedStream = 0;
|
||||
|
@ -479,6 +496,7 @@ TEST_F(PacketUsart, setupReceive)
|
|||
EXPECT_EQ(MOCK_CALLCOUNT(LL_USART_DMA_GetRegAddr, mock), 1);
|
||||
}
|
||||
|
||||
// Test HandleUsartIrq with a received packet having a correct header checksum
|
||||
TEST_F(PacketUsart, HandleUsartIrq_idle_fullpacket_hdr_ok)
|
||||
{
|
||||
struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0x95 ^ 0 ^ sizeof(testData) };
|
||||
|
@ -510,6 +528,7 @@ TEST_F(PacketUsart, HandleUsartIrq_idle_fullpacket_hdr_ok)
|
|||
EXPECT_EQ(usartStatus.rxBuffers[0].error, 0);
|
||||
}
|
||||
|
||||
// Test HandleUsartIrq with a received packet having a incorrect header checksum
|
||||
TEST_F(PacketUsart, HandleUsartIrq_idle_fullpacket_hdr_bad)
|
||||
{
|
||||
struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0xff ^ 0 ^ sizeof(testData) };
|
||||
|
@ -541,6 +560,7 @@ TEST_F(PacketUsart, HandleUsartIrq_idle_fullpacket_hdr_bad)
|
|||
EXPECT_NE(usartStatus.rxBuffers[0].busy, 0);
|
||||
}
|
||||
|
||||
// Packet reception should continue if the packet is not fully received yet
|
||||
TEST_F(PacketUsart, HandleUsartIrq_idle_tooshort)
|
||||
{
|
||||
struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0x95 ^ 0 ^ sizeof(testData) };
|
||||
|
@ -572,6 +592,7 @@ TEST_F(PacketUsart, HandleUsartIrq_idle_tooshort)
|
|||
EXPECT_EQ(usartStatus.rxBuffers[0].error, 0);
|
||||
}
|
||||
|
||||
// Packet reception should continue if the packet is shorter than the packet header
|
||||
TEST_F(PacketUsart, HandleUsartIrq_idle_tooshortforheadercheck)
|
||||
{
|
||||
struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0x95 ^ 0 ^ sizeof(testData) };
|
||||
|
@ -603,6 +624,8 @@ TEST_F(PacketUsart, HandleUsartIrq_idle_tooshortforheadercheck)
|
|||
EXPECT_EQ(usartStatus.rxBuffers[0].busy, 0);
|
||||
}
|
||||
|
||||
// Reception DMA engine transfer complete interrupt is the real verification point of the packet
|
||||
// verify that the packet is really checked
|
||||
TEST_F(PacketUsart, HandleRxDmaIrq_tc_hdrok)
|
||||
{
|
||||
struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0x95 ^ 0 ^ sizeof(testData) };
|
||||
|
@ -623,11 +646,15 @@ TEST_F(PacketUsart, HandleRxDmaIrq_tc_hdrok)
|
|||
|
||||
Pu_HandleRxDmaIrq(&usartStatus);
|
||||
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(Pu_CheckHeader, proxy), 1);
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(Crc_Enqueue, mock), 1);
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(Pu_SetupReceive, mock), 1);
|
||||
EXPECT_EQ(fakeDma1.LIFCR, DMA_LIFCR_CTCIF0);
|
||||
EXPECT_EQ(usartStatus.rxBuffers[0].error, 0);
|
||||
EXPECT_EQ(usartStatus.rxBuffers[0].busy, 0);
|
||||
}
|
||||
|
||||
// In case of the header fails on the end of packet reception error flag should be set
|
||||
TEST_F(PacketUsart, HandleRxDmaIrq_tc_hdrfail)
|
||||
{
|
||||
struct usartpacketheader_t fakeHeader = { 0x95, 0, sizeof(testData), 0xff ^ 0 ^ sizeof(testData) };
|
||||
|
@ -655,6 +682,7 @@ TEST_F(PacketUsart, HandleRxDmaIrq_tc_hdrfail)
|
|||
EXPECT_EQ(usartStatus.rxBuffers[0].busy, 0);
|
||||
}
|
||||
|
||||
// successfull CRC32 check, CRC32 match, callback should be called, busy flag should be set
|
||||
TEST_F(PacketUsart, HandleRxCrcComputedCallback_success_match)
|
||||
{
|
||||
Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
|
||||
|
@ -673,6 +701,8 @@ TEST_F(PacketUsart, HandleRxCrcComputedCallback_success_match)
|
|||
EXPECT_EQ(usartStatus.rxBuffers[0].error, 0);
|
||||
}
|
||||
|
||||
// successfull CRC32 check, CRC32 mismatch, callback should be called,
|
||||
// both busy and error flag should be set
|
||||
TEST_F(PacketUsart, HandleRxCrcComputedCallback_success_mismatch)
|
||||
{
|
||||
Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
|
||||
|
@ -691,6 +721,8 @@ TEST_F(PacketUsart, HandleRxCrcComputedCallback_success_mismatch)
|
|||
EXPECT_NE(usartStatus.rxBuffers[0].error, 0);
|
||||
}
|
||||
|
||||
//failed CRC32 check, callback should be called,
|
||||
// both busy and error flag should be set
|
||||
TEST_F(PacketUsart, HandleRxCrcComputedCallback_failure)
|
||||
{
|
||||
Pu_Init(&usartStatus, &fakeUsart, DMA1, 0, 7, &crcStatus, FakePacketReceivedCallback_mock, &fakePacketReceivedCallbackParam);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue