builds with make

This commit is contained in:
Attila Body 2025-05-27 16:31:02 +02:00
parent 8709bcb465
commit 549d4f3403
Signed by: abody
GPG key ID: BD0C6214E68FB5CF
17 changed files with 1513 additions and 1234 deletions

View file

@ -19,12 +19,6 @@ void Mcd_Init(DMA_TypeDef *dma, uint32_t stream);
void * Mcd_Copy(void *dst, void const *src, size_t length);
void Mcd_HandleDmaIrq(void);
#ifdef UNITTEST
DECLARE_MOCK(Mcd_Init);
DECLARE_MOCK(Mcd_Copy);
DECLARE_MOCK(Mcd_HandleDmaIrq);
#endif // UNITTEST
#ifdef __cplusplus
}
#endif

View file

@ -27,14 +27,10 @@
# define DIAG_INTERRUPT_OUT()
#endif
#ifndef MOCKABLE
#define MOCKABLE(x) x
#endif
void Crc_StartNextTask(struct crcstatus_t *status);
void MOCKABLE(Crc_InitStatus)(struct crcstatus_t *st, CRC_TypeDef *crcUnit, DMA_TypeDef *dma, uint32_t stream)
void Crc_InitStatus(struct crcstatus_t *st, CRC_TypeDef *crcUnit, DMA_TypeDef *dma, uint32_t stream)
{
st->crcUnit = crcUnit;
Dma_Init(&st->dmaInfo, dma, stream);
@ -46,7 +42,7 @@ void MOCKABLE(Crc_InitStatus)(struct crcstatus_t *st, CRC_TypeDef *crcUnit, DMA_
}
void MOCKABLE(Crc_AttachTasks)(struct crcstatus_t *status, struct crcslot_t *slot, struct crctask_t *tasks, uint8_t taskCount)
void 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 +56,7 @@ void MOCKABLE(Crc_AttachTasks)(struct crcstatus_t *status, struct crcslot_t *slo
}
uint8_t MOCKABLE(Crc_GetActiveTask)(struct crcslot_t **slot_out, struct crcstatus_t volatile *status)
uint8_t Crc_GetActiveTask(struct crcslot_t **slot_out, struct crcstatus_t volatile *status)
{
uint8_t ret;
@ -75,23 +71,23 @@ uint8_t MOCKABLE(Crc_GetActiveTask)(struct crcslot_t **slot_out, struct crcstatu
}
uint8_t MOCKABLE(Crc_IsTaskQueued)(struct crcslot_t *slot, uint8_t task) {
uint8_t Crc_IsTaskQueued(struct crcslot_t *slot, uint8_t task) {
return ((struct crctask_t volatile)slot->tasks[task]).address != NULL;
}
uint8_t MOCKABLE(Crc_IsTaskBusy)(struct crcslot_t *slot, uint8_t task) {
uint8_t 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 crcslot_t *slot, uint8_t task) {
void 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 crcslot_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 prim = __get_PRIMASK();
@ -123,7 +119,7 @@ uint8_t MOCKABLE(Crc_Enqueue)(struct crcstatus_t *status, struct crcslot_t *slot
}
uint32_t MOCKABLE(Crc_Compute)(struct crcstatus_t *status, struct crcslot_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)
{
uint32_t result;
Crc_Enqueue(status, slot, task, address, len, NULL, &result);
@ -133,7 +129,7 @@ uint32_t MOCKABLE(Crc_Compute)(struct crcstatus_t *status, struct crcslot_t *slo
// only called from ISR context
void MOCKABLE(Crc_StartNextTask)(struct crcstatus_t *status)
void Crc_StartNextTask(struct crcstatus_t *status)
{
char moreTasks;
uint8_t index = 0;
@ -166,7 +162,7 @@ void MOCKABLE(Crc_StartNextTask)(struct crcstatus_t *status)
// !!!PORTABILITY WARNING!!! using registers and bits directly. should be reviewed extremely when porting to a different MCU
void MOCKABLE(Crc_HandleDmaIrq)(struct crcstatus_t *status)
void Crc_HandleDmaIrq(struct crcstatus_t *status)
{
uint8_t success = 1;

View file

@ -5,11 +5,8 @@
* Author: abody
*/
#include <f4ll_c/dmahelper.h>
#ifndef MOCKABLE
#define MOCKABLE(x) x
#endif
volatile uint32_t* MOCKABLE(Dma_GetIsReg)(DMA_TypeDef *dma, uint32_t stream)
volatile uint32_t* Dma_GetIsReg(DMA_TypeDef *dma, uint32_t stream)
{
if(dma == DMA1)
return (stream < LL_DMA_STREAM_4) ? &DMA1->LISR : &DMA1->HISR;
@ -18,7 +15,7 @@ volatile uint32_t* MOCKABLE(Dma_GetIsReg)(DMA_TypeDef *dma, uint32_t stream)
}
volatile uint32_t* MOCKABLE(Dma_GetIfcReg)(DMA_TypeDef *dma, uint32_t stream)
volatile uint32_t* Dma_GetIfcReg(DMA_TypeDef *dma, uint32_t stream)
{
if(dma == DMA1)
return (stream < LL_DMA_STREAM_4) ? &DMA1->LIFCR : &DMA1->HIFCR;
@ -26,7 +23,7 @@ volatile uint32_t* MOCKABLE(Dma_GetIfcReg)(DMA_TypeDef *dma, uint32_t stream)
return (stream < LL_DMA_STREAM_4) ? &DMA2->LIFCR : &DMA2->HIFCR;
}
uint32_t MOCKABLE(Dma_GetFeMask)(uint32_t stream)
uint32_t Dma_GetFeMask(uint32_t stream)
{
static const uint32_t feMasks[8] = {
DMA_LISR_FEIF0, DMA_LISR_FEIF1, DMA_LISR_FEIF2, DMA_LISR_FEIF3, DMA_HISR_FEIF4, DMA_HISR_FEIF5, DMA_HISR_FEIF6, DMA_HISR_FEIF7
@ -34,7 +31,7 @@ uint32_t MOCKABLE(Dma_GetFeMask)(uint32_t stream)
return feMasks[stream];
}
uint32_t MOCKABLE(Dma_GetDmeMask)(uint32_t stream)
uint32_t Dma_GetDmeMask(uint32_t stream)
{
static const uint32_t dmeMasks[8] = {
DMA_LISR_DMEIF0, DMA_LISR_DMEIF1, DMA_LISR_DMEIF2, DMA_LISR_DMEIF3, DMA_HISR_DMEIF4, DMA_HISR_DMEIF5, DMA_HISR_DMEIF6, DMA_HISR_DMEIF7
@ -42,7 +39,7 @@ uint32_t MOCKABLE(Dma_GetDmeMask)(uint32_t stream)
return dmeMasks[stream];
}
uint32_t MOCKABLE(Dma_GetTeMask)(uint32_t stream)
uint32_t Dma_GetTeMask(uint32_t stream)
{
static const uint32_t teMasks[8] = {
DMA_LISR_TEIF0, DMA_LISR_TEIF1, DMA_LISR_TEIF2, DMA_LISR_TEIF3, DMA_HISR_TEIF4, DMA_HISR_TEIF5, DMA_HISR_TEIF6, DMA_HISR_TEIF7
@ -50,7 +47,7 @@ uint32_t MOCKABLE(Dma_GetTeMask)(uint32_t stream)
return teMasks[stream];
}
uint32_t MOCKABLE(Dma_GetHtMask)(uint32_t stream)
uint32_t Dma_GetHtMask(uint32_t stream)
{
static const uint32_t htMasks[8] = {
DMA_LISR_HTIF0, DMA_LISR_HTIF1, DMA_LISR_HTIF2, DMA_LISR_HTIF3, DMA_HISR_HTIF4, DMA_HISR_HTIF5, DMA_HISR_HTIF6, DMA_HISR_HTIF7
@ -58,7 +55,7 @@ uint32_t MOCKABLE(Dma_GetHtMask)(uint32_t stream)
return htMasks[stream];
}
uint32_t MOCKABLE(Dma_GetTcMask)(uint32_t stream)
uint32_t Dma_GetTcMask(uint32_t stream)
{
static const uint32_t tcMasks[8] = {
DMA_LISR_TCIF0, DMA_LISR_TCIF1, DMA_LISR_TCIF2, DMA_LISR_TCIF3, DMA_HISR_TCIF4, DMA_HISR_TCIF5, DMA_HISR_TCIF6, DMA_HISR_TCIF7
@ -67,7 +64,7 @@ uint32_t MOCKABLE(Dma_GetTcMask)(uint32_t stream)
return tcMasks[stream];
}
void MOCKABLE(Dma_Init)(struct dmainfo_t *info, DMA_TypeDef *dma, uint32_t stream)
void Dma_Init(struct dmainfo_t *info, DMA_TypeDef *dma, uint32_t stream)
{
info->dma = dma;
info->stream = stream;

View file

@ -15,21 +15,17 @@
# define DIAG_INTERRUPT_OUT()
#endif
#ifndef MOCKABLE
#define MOCKABLE(x) x
#endif // MOCKABLE
volatile uint8_t g_memcpyDmaBusy = 0;
static struct dmainfo_t g_memcpyDmaInfo;
void MOCKABLE(Mcd_Init)(DMA_TypeDef *dma, uint32_t stream)
void Mcd_Init(DMA_TypeDef *dma, uint32_t stream)
{
Dma_Init(&g_memcpyDmaInfo, dma, stream);
LL_DMA_EnableIT_TC(dma, stream);
}
void * MOCKABLE(Mcd_Copy)(void *dst, void const *src, size_t length)
void * Mcd_Copy(void *dst, void const *src, size_t length)
{
LL_DMA_SetM2MSrcAddress(g_memcpyDmaInfo.dma, g_memcpyDmaInfo.stream, (uint32_t)src);
LL_DMA_SetM2MDstAddress(g_memcpyDmaInfo.dma, g_memcpyDmaInfo.stream, (uint32_t)dst);
@ -40,7 +36,7 @@ void * MOCKABLE(Mcd_Copy)(void *dst, void const *src, size_t length)
return dst;
}
void MOCKABLE(Mcd_HandleDmaIrq)(void)
void Mcd_HandleDmaIrq(void)
{
DIAG_INTERRUPT_IN();
if(*g_memcpyDmaInfo.isReg & g_memcpyDmaInfo.tcMask) { // DMA transfer complete

View file

@ -15,10 +15,6 @@
#include "f4ll_c/dmahelper.h"
#include "f4ll_c/crcscheduler.h"
#ifndef MOCKABLE
#define MOCKABLE(x) x
#endif
#ifndef DIAG_RX_BUFFER_SWITCH
# define DIAG_RX_BUFFER_SWITCH(x)
#endif
@ -80,7 +76,7 @@ static inline void StatsAddSkiped(struct usart_stats *s, uint8_t cnt) {
#define StatsAddSkiped(x)
#endif // USART_STATS_DISABLED
void MOCKABLE(Pu_Init)(
void Pu_Init(
struct usartstatus_t *st, USART_TypeDef *usart, DMA_TypeDef *dma,
uint32_t stream_rx, uint32_t stream_tx,
struct crcstatus_t *crcStatus,
@ -130,19 +126,19 @@ void MOCKABLE(Pu_Init)(
}
uint8_t* MOCKABLE(Pu_GetTxBuffer)(struct usartstatus_t *status)
uint8_t* Pu_GetTxBuffer(struct usartstatus_t *status)
{
return status->txBuffer.packet.payload;
}
uint8_t MOCKABLE(Pu_CheckHeader)(struct usartpacket_t *packet)
uint8_t Pu_CheckHeader(struct usartpacket_t *packet)
{
return packet->header.startByte == STARTMARKER && (packet->header.startByte ^ packet->header.serial ^ packet->header.payloadLength) == packet->header.hash;
}
uint8_t MOCKABLE(Pu_Post)(struct usartstatus_t *status, uint8_t const *payload, uint8_t length, uint8_t waitForCrcQueue)
uint8_t Pu_Post(struct usartstatus_t *status, uint8_t const *payload, uint8_t length, uint8_t waitForCrcQueue)
{
struct usart_buffer_t *buffer = &status->txBuffer;
uint8_t hash = STARTMARKER;
@ -169,7 +165,7 @@ uint8_t MOCKABLE(Pu_Post)(struct usartstatus_t *status, uint8_t const *payload,
}
void MOCKABLE(Pu_SetupReceive)(struct usartstatus_t *status)
void Pu_SetupReceive(struct usartstatus_t *status)
{
uint8_t packetIndex = status->activeRxBuf;
@ -183,7 +179,7 @@ void MOCKABLE(Pu_SetupReceive)(struct usartstatus_t *status)
}
void MOCKABLE(Pu_SetupTransmit)(USART_TypeDef *usart, DMA_TypeDef* dma, uint32_t stream, void *buffer, uint32_t length)
void Pu_SetupTransmit(USART_TypeDef *usart, DMA_TypeDef* dma, uint32_t stream, void *buffer, uint32_t length)
{
LL_DMA_ConfigAddresses(dma, stream, (uint32_t)buffer, LL_USART_DMA_GetRegAddr(usart), LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
LL_DMA_SetDataLength(dma, stream, length);
@ -192,7 +188,7 @@ void MOCKABLE(Pu_SetupTransmit)(USART_TypeDef *usart, DMA_TypeDef* dma, uint32_t
}
void MOCKABLE(Pu_ConsumePacket)(struct usartstatus_t *status, uint8_t packetIndex)
void Pu_ConsumePacket(struct usartstatus_t *status, uint8_t packetIndex)
{
struct usart_buffer_t *buffer = &status->rxBuffers[packetIndex];
if(buffer->busy) {
@ -210,7 +206,7 @@ void MOCKABLE(Pu_ConsumePacket)(struct usartstatus_t *status, uint8_t packetInde
}
void MOCKABLE(Pu_HandleRxDmaIrq)(struct usartstatus_t *status)
void Pu_HandleRxDmaIrq(struct usartstatus_t *status)
{
DIAG_INTERRUPT_IN();
StatsIncRcvd(&status->stats);
@ -242,7 +238,7 @@ void MOCKABLE(Pu_HandleRxDmaIrq)(struct usartstatus_t *status)
}
void MOCKABLE(Pu_RxCrcComputedCallback)(void *callbackParm, uint32_t calculatedCrc, uint8_t success)
void Pu_RxCrcComputedCallback(void *callbackParm, uint32_t calculatedCrc, uint8_t success)
{
struct usart_buffer_t *ub = (struct usart_buffer_t*) callbackParm;
if(!success)
@ -258,7 +254,7 @@ void MOCKABLE(Pu_RxCrcComputedCallback)(void *callbackParm, uint32_t calculatedC
}
void MOCKABLE(Pu_HandleTxDmaIrq)(struct usartstatus_t *status)
void Pu_HandleTxDmaIrq(struct usartstatus_t *status)
{
DIAG_INTERRUPT_IN();
if(*status->txDmaInfo.isReg & status->txDmaInfo.tcMask) { // DMA transfer complete
@ -283,7 +279,7 @@ void MOCKABLE(Pu_HandleTxDmaIrq)(struct usartstatus_t *status)
}
void MOCKABLE(Pu_HandleUsartIrq)(struct usartstatus_t *status)
void Pu_HandleUsartIrq(struct usartstatus_t *status)
{
DIAG_INTERRUPT_IN();
if(LL_USART_IsActiveFlag_IDLE(status->usart) && LL_USART_IsEnabledIT_IDLE(status->usart)) { // receiver idle

View file

@ -11,415 +11,421 @@
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <platform/dma_ll.h>
#include <f4ll_c/crcscheduler.h>
#include <gtest/gtest.h>
#include <platform/mockme.h>
#include <thread>
#include <future>
#include <platform/dma_ll.h>
#include <f4ll_c/crcscheduler.h>
#include <CppUTest/TestHarness.h>
#include <CppUTestExt/MockSupport.h>
#include <subhook.h>
extern "C" void Crc_StartNextTask(struct crcstatus_t *status);
DMA_TypeDef * DMA1 __attribute__((weak));
DMA_TypeDef * DMA2 __attribute__((weak));
static DMA_TypeDef dma1, dma2;
static crcstatus_t crcStatus;
static crcslot_t slot1, slot2;
static crctask_t tasks1[2], tasks2[2];
static CRC_TypeDef fakeCrc;
static DMA_TypeDef *expectedDma;
static uint32_t expectedStream;
static uint32_t expectedSrcAddress;
static uint32_t expectedDstAddress;
static uint32_t expectedLength;
static void *expectedCustomPtr;
static uint8_t expectedSuccess;
static uint32_t expectedCrc;
//////////////////////////////////////////////////////////////////////////////
uint32_t effective_primask = 0;
DEFINE_MOCK(__set_PRIMASK, mock, uint32_t primask) {
effective_primask = primask;
LEAVE_MOCK;
}
DEFINE_MOCK_RET(uint32_t, __get_PRIMASK, mock) {
RETURN_MOCK(__get_PRIMASK, mock, effective_primask);
}
DEFINE_MOCK_VAR(crcslot_t *, __disable_irq, mock, firstslot_required);
DEFINE_MOCK(__disable_irq, mock) {
if(MOCK_CALLCOUNT(__disable_irq, mock) < 2) {
EXPECT_EQ(crcStatus.firstSlot, MOCK_VAR(__disable_irq, mock, firstslot_required));
}
effective_primask = 1;
LEAVE_MOCK;
}
DEFINE_MOCK(LL_DMA_EnableIT_TC, mock, DMA_TypeDef *dma, uint32_t stream) {
EXPECT_EQ(expectedDma, dma);
EXPECT_EQ(expectedStream, stream);
LEAVE_MOCK;
}
DEFINE_MOCK(LL_DMA_EnableIT_TE, mock, DMA_TypeDef *dma, uint32_t stream) {
EXPECT_EQ(expectedDma, dma);
EXPECT_EQ(expectedStream, stream);
LEAVE_MOCK;
}
DEFINE_MOCK(LL_DMA_SetM2MDstAddress, mock, DMA_TypeDef *dma, uint32_t stream, uint32_t address) {
EXPECT_EQ(expectedDma, dma);
EXPECT_EQ(expectedStream, stream);
EXPECT_EQ(expectedDstAddress, address);
LEAVE_MOCK;
}
DEFINE_MOCK(LL_DMA_SetM2MSrcAddress, mock, DMA_TypeDef *dma, uint32_t stream, uint32_t address) {
EXPECT_EQ(expectedDma, dma);
EXPECT_EQ(expectedStream, stream);
EXPECT_EQ(expectedSrcAddress, address);
LEAVE_MOCK;
}
DEFINE_MOCK(LL_DMA_SetDataLength, mock, DMA_TypeDef *dma, uint32_t stream, uint32_t length) {
EXPECT_EQ(expectedDma, dma);
EXPECT_EQ(expectedStream, stream);
EXPECT_EQ(expectedLength, length);
LEAVE_MOCK;
}
DEFINE_MOCK(LL_DMA_EnableStream, mock, DMA_TypeDef *dma, uint32_t stream) {
EXPECT_EQ(expectedDma, dma);
EXPECT_EQ(expectedStream, stream);
LEAVE_MOCK;
}
DEFINE_MOCK(LL_DMA_DisableStream, mock, DMA_TypeDef *dma, uint32_t stream) {
EXPECT_EQ(expectedDma, dma);
EXPECT_EQ(expectedStream, stream);
LEAVE_MOCK;
}
DEFINE_MOCK(Crc_StartNextTask, mock, struct crcstatus_t *status) {
EXPECT_EQ(status, &crcStatus);
LEAVE_MOCK
}
void FakeCallback_1(void*, uint32_t, uint8_t) {}
void FakeCallback_2(void*, uint32_t, uint8_t) {}
void FakeCallback_3(void*, uint32_t, uint8_t) {}
void FakeCallbackCheck(void* ptr, uint32_t crc, uint8_t success)
{
EXPECT_EQ(ptr, expectedCustomPtr);
EXPECT_EQ(crc, expectedCrc);
EXPECT_EQ(success, expectedSuccess);
}
DEFINE_MOCK(Dma_Init, mock, struct dmainfo_t * info, DMA_TypeDef *dma, uint32_t stream)
{
LEAVE_MOCK;
}
//////////////////////////////////////////////////////////////////////////////
TEST(CrcScheduler, InitStatus)
{
expectedDma = DMA2;
expectedStream = LL_DMA_STREAM_4;
expectedDstAddress = (uint32_t)&fakeCrc;
memset(&crcStatus, 0xff, sizeof(crcStatus));
ACTIVATE_MOCK(LL_DMA_EnableIT_TC, mock);
ACTIVATE_MOCK(LL_DMA_EnableIT_TE, mock);
ACTIVATE_MOCK(LL_DMA_SetM2MDstAddress, mock);
ACTIVATE_MOCK(Dma_Init, mock);
Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
EXPECT_EQ(crcStatus.crcUnit, &fakeCrc);
EXPECT_EQ(crcStatus.activeSlot, nullptr);
EXPECT_EQ(crcStatus.firstSlot, nullptr);
EXPECT_EQ(MOCK_VAR(Dma_Init, mock, callcount), 1);
}
TEST(CrcScheduler, AttachTask_single)
{
DMA1 = &dma1;
DMA2 = &dma2;
effective_primask = 0;
Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
ACTIVATE_MOCK_RV(__get_PRIMASK, mock, 0);
ACTIVATE_MOCK(__set_PRIMASK, mock);
ACTIVATE_MOCK(__disable_irq, mock);
MOCK_STORE(__disable_irq, mock, firstslot_required, nullptr);
Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
EXPECT_EQ(MOCK_CALLCOUNT(__get_PRIMASK, mock), 1);
EXPECT_EQ(MOCK_CALLCOUNT(__set_PRIMASK, mock), 1);
EXPECT_EQ(MOCK_CALLCOUNT(__disable_irq, mock), 1);
EXPECT_EQ(crcStatus.firstSlot, &slot1);
EXPECT_EQ(slot1.next, nullptr);
EXPECT_EQ(slot1.count, 2);
EXPECT_EQ(crcStatus.activeSlot, nullptr);
}
// Are tasks attached in the expected order internally
TEST(CrcScheduler, AttachTask_multiple)
{
ACTIVATE_MOCK_RV(__get_PRIMASK, mock, 1);
ACTIVATE_MOCK(__set_PRIMASK, mock);
ACTIVATE_MOCK(__disable_irq, mock);
MOCK_STORE(__disable_irq, mock, firstslot_required, nullptr);
DMA1 = &dma1;
DMA2 = &dma2;
Crc_InitStatus(&crcStatus, NULL, DMA2, LL_DMA_STREAM_4);
Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
MOCK_STORE(__disable_irq, mock, firstslot_required, &slot1);
Crc_AttachTasks(&crcStatus, &slot2, tasks2, 2);
EXPECT_EQ(MOCK_CALLCOUNT(__get_PRIMASK, mock), 2);
EXPECT_EQ(MOCK_CALLCOUNT(__set_PRIMASK, mock), 2);
EXPECT_EQ(MOCK_CALLCOUNT(__disable_irq, mock), 2);
EXPECT_EQ(crcStatus.firstSlot, &slot2);
EXPECT_EQ(slot2.next, &slot1);
EXPECT_EQ(slot1.next, nullptr);
EXPECT_EQ(slot2.count, 2);
EXPECT_EQ(crcStatus.activeSlot, nullptr);
}
// No blocking should occur if the the task is not busy
TEST(CrcScheduler, Enqueue_nowait)
{
uint32_t fakeCrcResult;
uint8_t testData[] = "qwerty";
expectedDma = DMA2;
expectedStream = LL_DMA_STREAM_4;
expectedSrcAddress = (uint32_t)testData;
memset(tasks1, 0, sizeof(tasks1));
memset(&fakeCrc, 0, sizeof(fakeCrc));
Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
expectedLength = 2;
ACTIVATE_MOCK(LL_DMA_SetM2MSrcAddress, mock);
ACTIVATE_MOCK(LL_DMA_SetDataLength, mock);
ACTIVATE_MOCK(LL_DMA_EnableStream, mock);
EXPECT_TRUE(Crc_Enqueue(&crcStatus, &slot1, 0, testData, sizeof(testData), FakeCallback_1, &fakeCrcResult));
//first task should be picked up before return;
EXPECT_EQ(slot1.tasks[0].address, nullptr);
EXPECT_EQ((uintptr_t)slot1.tasks[0].callback, (uintptr_t)FakeCallback_1);
EXPECT_EQ(MOCK_VAR(LL_DMA_SetM2MSrcAddress, mock, callcount), 1);
EXPECT_EQ(MOCK_VAR(LL_DMA_SetDataLength, mock, callcount), 1);
EXPECT_EQ(MOCK_VAR(LL_DMA_EnableStream, mock, callcount), 1);
EXPECT_FALSE(Crc_Enqueue(&crcStatus, &slot1, 1, testData, 4, FakeCallback_1, &fakeCrcResult));
// second task should be queued
EXPECT_EQ(slot1.tasks[1].address, testData);
EXPECT_EQ((uintptr_t)slot1.tasks[1].callback, (uintptr_t)FakeCallback_1);
EXPECT_EQ(slot1.tasks[1].wordCount, 1);
// should be no new calls to hardware handling functions
EXPECT_EQ(MOCK_VAR(LL_DMA_SetM2MSrcAddress, mock, callcount), 1);
EXPECT_EQ(MOCK_VAR(LL_DMA_SetDataLength, mock, callcount), 1);
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";
uint32_t fakeCrcResult;
memset(tasks1, 0, sizeof(tasks1));
memset(&fakeCrc, 0, sizeof(fakeCrc));
Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
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)
std::promise<bool> promisedFinished;
auto futureResult = promisedFinished.get_future();
pthread_t th;
std::thread t([&testData](std::promise<bool>& finished) {
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
Crc_Enqueue(&crcStatus, &slot1, 0, testData, sizeof(testData), FakeCallback_1, nullptr);
finished.set_value(true);
}, std::ref(promisedFinished));
th = t.native_handle();
t.detach();
EXPECT_EQ(futureResult.wait_for(std::chrono::milliseconds(100)), std::future_status::timeout);
tasks1[0].callback = nullptr;
tasks1[0].callbackParam = nullptr;
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);
}
// StartNextTask should start the scheduled tasks in predefined order
TEST(CrcScheduler, Crc_StartNextTask)
{
uint8_t testData[] = "qwerty";
uint32_t fakeCrcResult1, fakeCrcResult2, fakeCrcResult3;
memset(tasks1, 0, sizeof(tasks1));
memset(tasks2, 0, sizeof(tasks2));
memset(&fakeCrc, 0, sizeof(fakeCrc));
Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
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);
EXPECT_EQ(crcStatus.activeSlot, &slot1);
EXPECT_EQ(crcStatus.activeTask, 0);
crcStatus.activeSlot->tasks[crcStatus.activeTask].callback = nullptr;
crcStatus.activeSlot->tasks[crcStatus.activeTask].callbackParam = nullptr;
ACTIVATE_MOCK(LL_DMA_SetM2MSrcAddress, mock);
ACTIVATE_MOCK(LL_DMA_SetDataLength, mock);
ACTIVATE_MOCK(LL_DMA_EnableStream, mock);
expectedDma = DMA2;
expectedStream = LL_DMA_STREAM_4;
expectedSrcAddress = (uint32_t)testData;
expectedLength = (sizeof(testData) + 3) / 4;
Crc_StartNextTask(&crcStatus);
EXPECT_EQ(crcStatus.activeSlot, &slot2);
EXPECT_EQ(crcStatus.activeTask, 0);
EXPECT_EQ(LL_DMA_SetM2MSrcAddress_mock_callcount, 1);
EXPECT_EQ(LL_DMA_SetDataLength_mock_callcount, 1);
EXPECT_EQ(LL_DMA_EnableStream_mock_callcount, 1);
crcStatus.activeSlot->tasks[crcStatus.activeTask].callback = nullptr;
crcStatus.activeSlot->tasks[crcStatus.activeTask].callbackParam = nullptr;
Crc_StartNextTask(&crcStatus);
EXPECT_EQ(crcStatus.activeSlot, &slot1);
EXPECT_EQ(crcStatus.activeTask, 1);
EXPECT_EQ(LL_DMA_SetM2MSrcAddress_mock_callcount, 2);
EXPECT_EQ(LL_DMA_SetDataLength_mock_callcount, 2);
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";
uint32_t FakeCustomData1, FakeCustomData2;
memset(tasks1, 0, sizeof(tasks1));
memset(tasks2, 0, sizeof(tasks2));
memset(&fakeCrc, 0, sizeof(fakeCrc));
fakeCrc.DR = 0xa5a55a5a;
Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
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);
ACTIVATE_MOCK(LL_DMA_DisableStream, mock);
ACTIVATE_MOCK(LL_DMA_SetM2MSrcAddress, mock);
ACTIVATE_MOCK(LL_DMA_SetDataLength, mock);
ACTIVATE_MOCK(LL_DMA_EnableStream, mock);
ACTIVATE_MOCK(Crc_StartNextTask, mock);
expectedDma = DMA2;
expectedStream = LL_DMA_STREAM_4;
expectedCustomPtr = &FakeCustomData1;
expectedCrc = fakeCrc.DR;
expectedSuccess = 1;
DMA2->HISR |= DMA_HISR_TCIF4;
DMA2->HIFCR = 0;
Crc_HandleDmaIrq(&crcStatus);
EXPECT_EQ(LL_DMA_DisableStream_mock_callcount, 1);
EXPECT_EQ(DMA2->HIFCR & DMA_HIFCR_CTCIF4, DMA_HIFCR_CTCIF4);
expectedCustomPtr = &FakeCustomData2;
DMA2->HISR |= DMA_HISR_TCIF4 | DMA_HISR_TEIF4;
DMA2->HIFCR = 0;
crcStatus.activeSlot->tasks[crcStatus.activeTask].callback = nullptr;
crcStatus.activeSlot->tasks[crcStatus.activeTask].callbackParam = nullptr;
Crc_HandleDmaIrq(&crcStatus);
EXPECT_EQ(DMA2->HIFCR & (DMA_HIFCR_CTCIF4 | DMA_HIFCR_CTEIF4), DMA_HIFCR_CTCIF4 | DMA_HIFCR_CTEIF4);
EXPECT_EQ(LL_DMA_DisableStream_mock_callcount, 2);
}
// 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_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_IsTaskQueued(&slot1, 0), 0);
EXPECT_NE(Crc_IsTaskQueued(&slot1, 1), 0);
Crc_StartNextTask(&crcStatus);
EXPECT_EQ(Crc_IsTaskQueued(&slot1, 1), 0);
}
// 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_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_IsTaskBusy(&slot1, 0), 0);
EXPECT_NE(Crc_IsTaskBusy(&slot1, 1), 0);
DMA2->HISR |= DMA_HISR_TCIF4;
Crc_HandleDmaIrq(&crcStatus);
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_IsTaskBusy(&slot1, 0), 0);
EXPECT_EQ(Crc_IsTaskBusy(&slot1, 1), 0);
}
//
//DMA_TypeDef * DMA1 __attribute__((weak));
//DMA_TypeDef * DMA2 __attribute__((weak));
//
//static DMA_TypeDef dma1, dma2;
//static crcstatus_t crcStatus;
//static crcslot_t slot1, slot2;
//static crctask_t tasks1[2], tasks2[2];
//static CRC_TypeDef fakeCrc;
//
//static DMA_TypeDef *expectedDma;
//static uint32_t expectedStream;
//static uint32_t expectedSrcAddress;
//static uint32_t expectedDstAddress;
//static uint32_t expectedLength;
//static void *expectedCustomPtr;
//static uint8_t expectedSuccess;
//static uint32_t expectedCrc;
//
////////////////////////////////////////////////////////////////////////////////
//uint32_t effective_primask = 0;
//
//DEFINE_MOCK(__set_PRIMASK, mock, uint32_t primask) {
// effective_primask = primask;
// LEAVE_MOCK;
//}
//
//DEFINE_MOCK_RET(uint32_t, __get_PRIMASK, mock) {
// RETURN_MOCK(__get_PRIMASK, mock, effective_primask);
//}
//
//DEFINE_MOCK_VAR(crcslot_t *, __disable_irq, mock, firstslot_required);
//DEFINE_MOCK(__disable_irq, mock) {
// if(MOCK_CALLCOUNT(__disable_irq, mock) < 2) {
// EXPECT_EQ(crcStatus.firstSlot, MOCK_VAR(__disable_irq, mock, firstslot_required));
// }
// effective_primask = 1;
// LEAVE_MOCK;
//}
//
//DEFINE_MOCK(LL_DMA_EnableIT_TC, mock, DMA_TypeDef *dma, uint32_t stream) {
// EXPECT_EQ(expectedDma, dma);
// EXPECT_EQ(expectedStream, stream);
// LEAVE_MOCK;
//}
//
//DEFINE_MOCK(LL_DMA_EnableIT_TE, mock, DMA_TypeDef *dma, uint32_t stream) {
// EXPECT_EQ(expectedDma, dma);
// EXPECT_EQ(expectedStream, stream);
// LEAVE_MOCK;
//}
//
//DEFINE_MOCK(LL_DMA_SetM2MDstAddress, mock, DMA_TypeDef *dma, uint32_t stream, uint32_t address) {
// EXPECT_EQ(expectedDma, dma);
// EXPECT_EQ(expectedStream, stream);
// EXPECT_EQ(expectedDstAddress, address);
// LEAVE_MOCK;
//}
//
//DEFINE_MOCK(LL_DMA_SetM2MSrcAddress, mock, DMA_TypeDef *dma, uint32_t stream, uint32_t address) {
// EXPECT_EQ(expectedDma, dma);
// EXPECT_EQ(expectedStream, stream);
// EXPECT_EQ(expectedSrcAddress, address);
// LEAVE_MOCK;
//}
//
//DEFINE_MOCK(LL_DMA_SetDataLength, mock, DMA_TypeDef *dma, uint32_t stream, uint32_t length) {
// EXPECT_EQ(expectedDma, dma);
// EXPECT_EQ(expectedStream, stream);
// EXPECT_EQ(expectedLength, length);
// LEAVE_MOCK;
//}
//
//DEFINE_MOCK(LL_DMA_EnableStream, mock, DMA_TypeDef *dma, uint32_t stream) {
// EXPECT_EQ(expectedDma, dma);
// EXPECT_EQ(expectedStream, stream);
// LEAVE_MOCK;
//}
//
//DEFINE_MOCK(LL_DMA_DisableStream, mock, DMA_TypeDef *dma, uint32_t stream) {
// EXPECT_EQ(expectedDma, dma);
// EXPECT_EQ(expectedStream, stream);
// LEAVE_MOCK;
//}
//
//DEFINE_MOCK(Crc_StartNextTask, mock, struct crcstatus_t *status) {
// EXPECT_EQ(status, &crcStatus);
// LEAVE_MOCK
//}
//
//void FakeCallback_1(void*, uint32_t, uint8_t) {}
//void FakeCallback_2(void*, uint32_t, uint8_t) {}
//void FakeCallback_3(void*, uint32_t, uint8_t) {}
//
//void FakeCallbackCheck(void* ptr, uint32_t crc, uint8_t success)
//{
// EXPECT_EQ(ptr, expectedCustomPtr);
// EXPECT_EQ(crc, expectedCrc);
// EXPECT_EQ(success, expectedSuccess);
//}
//
//DEFINE_MOCK(Dma_Init, mock, struct dmainfo_t * info, DMA_TypeDef *dma, uint32_t stream)
//{
// LEAVE_MOCK;
//}
//
////////////////////////////////////////////////////////////////////////////////
//TEST(CrcScheduler, InitStatus)
//{
// expectedDma = DMA2;
// expectedStream = LL_DMA_STREAM_4;
// expectedDstAddress = (uint32_t)&fakeCrc;
// memset(&crcStatus, 0xff, sizeof(crcStatus));
//
// ACTIVATE_MOCK(LL_DMA_EnableIT_TC, mock);
// ACTIVATE_MOCK(LL_DMA_EnableIT_TE, mock);
// ACTIVATE_MOCK(LL_DMA_SetM2MDstAddress, mock);
// ACTIVATE_MOCK(Dma_Init, mock);
//
// Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
// EXPECT_EQ(crcStatus.crcUnit, &fakeCrc);
// EXPECT_EQ(crcStatus.activeSlot, nullptr);
// EXPECT_EQ(crcStatus.firstSlot, nullptr);
// EXPECT_EQ(MOCK_VAR(Dma_Init, mock, callcount), 1);
//}
//
//
//TEST(CrcScheduler, AttachTask_single)
//{
// DMA1 = &dma1;
// DMA2 = &dma2;
// effective_primask = 0;
// Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
// ACTIVATE_MOCK_RV(__get_PRIMASK, mock, 0);
// ACTIVATE_MOCK(__set_PRIMASK, mock);
// ACTIVATE_MOCK(__disable_irq, mock);
// MOCK_STORE(__disable_irq, mock, firstslot_required, nullptr);
//
// Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
//
// EXPECT_EQ(MOCK_CALLCOUNT(__get_PRIMASK, mock), 1);
// EXPECT_EQ(MOCK_CALLCOUNT(__set_PRIMASK, mock), 1);
// EXPECT_EQ(MOCK_CALLCOUNT(__disable_irq, mock), 1);
// EXPECT_EQ(crcStatus.firstSlot, &slot1);
// EXPECT_EQ(slot1.next, nullptr);
// EXPECT_EQ(slot1.count, 2);
// EXPECT_EQ(crcStatus.activeSlot, nullptr);
//}
//
//// Are tasks attached in the expected order internally
//TEST(CrcScheduler, AttachTask_multiple)
//{
// ACTIVATE_MOCK_RV(__get_PRIMASK, mock, 1);
// ACTIVATE_MOCK(__set_PRIMASK, mock);
// ACTIVATE_MOCK(__disable_irq, mock);
// MOCK_STORE(__disable_irq, mock, firstslot_required, nullptr);
// DMA1 = &dma1;
// DMA2 = &dma2;
// Crc_InitStatus(&crcStatus, NULL, DMA2, LL_DMA_STREAM_4);
//
// Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
// MOCK_STORE(__disable_irq, mock, firstslot_required, &slot1);
// Crc_AttachTasks(&crcStatus, &slot2, tasks2, 2);
//
// EXPECT_EQ(MOCK_CALLCOUNT(__get_PRIMASK, mock), 2);
// EXPECT_EQ(MOCK_CALLCOUNT(__set_PRIMASK, mock), 2);
// EXPECT_EQ(MOCK_CALLCOUNT(__disable_irq, mock), 2);
// EXPECT_EQ(crcStatus.firstSlot, &slot2);
// EXPECT_EQ(slot2.next, &slot1);
// EXPECT_EQ(slot1.next, nullptr);
// EXPECT_EQ(slot2.count, 2);
// EXPECT_EQ(crcStatus.activeSlot, nullptr);
//}
//
//// No blocking should occur if the the task is not busy
//TEST(CrcScheduler, Enqueue_nowait)
//{
// uint32_t fakeCrcResult;
// uint8_t testData[] = "qwerty";
// expectedDma = DMA2;
// expectedStream = LL_DMA_STREAM_4;
// expectedSrcAddress = (uint32_t)testData;
//
// memset(tasks1, 0, sizeof(tasks1));
// memset(&fakeCrc, 0, sizeof(fakeCrc));
//
// Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
// Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
// expectedLength = 2;
//
// ACTIVATE_MOCK(LL_DMA_SetM2MSrcAddress, mock);
// ACTIVATE_MOCK(LL_DMA_SetDataLength, mock);
// ACTIVATE_MOCK(LL_DMA_EnableStream, mock);
//
// EXPECT_TRUE(Crc_Enqueue(&crcStatus, &slot1, 0, testData, sizeof(testData), FakeCallback_1, &fakeCrcResult));
//
// //first task should be picked up before return;
// EXPECT_EQ(slot1.tasks[0].address, nullptr);
// EXPECT_EQ((uintptr_t)slot1.tasks[0].callback, (uintptr_t)FakeCallback_1);
// EXPECT_EQ(MOCK_VAR(LL_DMA_SetM2MSrcAddress, mock, callcount), 1);
// EXPECT_EQ(MOCK_VAR(LL_DMA_SetDataLength, mock, callcount), 1);
// EXPECT_EQ(MOCK_VAR(LL_DMA_EnableStream, mock, callcount), 1);
//
// EXPECT_FALSE(Crc_Enqueue(&crcStatus, &slot1, 1, testData, 4, FakeCallback_1, &fakeCrcResult));
//
// // second task should be queued
// EXPECT_EQ(slot1.tasks[1].address, testData);
// EXPECT_EQ((uintptr_t)slot1.tasks[1].callback, (uintptr_t)FakeCallback_1);
// EXPECT_EQ(slot1.tasks[1].wordCount, 1);
//
// // should be no new calls to hardware handling functions
// EXPECT_EQ(MOCK_VAR(LL_DMA_SetM2MSrcAddress, mock, callcount), 1);
// EXPECT_EQ(MOCK_VAR(LL_DMA_SetDataLength, mock, callcount), 1);
// 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";
// uint32_t fakeCrcResult;
//
// memset(tasks1, 0, sizeof(tasks1));
// memset(&fakeCrc, 0, sizeof(fakeCrc));
//
// Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
// 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)
// std::promise<bool> promisedFinished;
// auto futureResult = promisedFinished.get_future();
// pthread_t th;
// std::thread t([&testData](std::promise<bool>& finished) {
// pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
// Crc_Enqueue(&crcStatus, &slot1, 0, testData, sizeof(testData), FakeCallback_1, nullptr);
// finished.set_value(true);
// }, std::ref(promisedFinished));
// th = t.native_handle();
// t.detach();
// EXPECT_EQ(futureResult.wait_for(std::chrono::milliseconds(100)), std::future_status::timeout);
// tasks1[0].callback = nullptr;
// tasks1[0].callbackParam = nullptr;
// 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);
//}
//
//// StartNextTask should start the scheduled tasks in predefined order
//TEST(CrcScheduler, Crc_StartNextTask)
//{
// uint8_t testData[] = "qwerty";
// uint32_t fakeCrcResult1, fakeCrcResult2, fakeCrcResult3;
//
// memset(tasks1, 0, sizeof(tasks1));
// memset(tasks2, 0, sizeof(tasks2));
// memset(&fakeCrc, 0, sizeof(fakeCrc));
//
// Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
// 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);
//
// EXPECT_EQ(crcStatus.activeSlot, &slot1);
// EXPECT_EQ(crcStatus.activeTask, 0);
// crcStatus.activeSlot->tasks[crcStatus.activeTask].callback = nullptr;
// crcStatus.activeSlot->tasks[crcStatus.activeTask].callbackParam = nullptr;
//
// ACTIVATE_MOCK(LL_DMA_SetM2MSrcAddress, mock);
// ACTIVATE_MOCK(LL_DMA_SetDataLength, mock);
// ACTIVATE_MOCK(LL_DMA_EnableStream, mock);
//
// expectedDma = DMA2;
// expectedStream = LL_DMA_STREAM_4;
// expectedSrcAddress = (uint32_t)testData;
// expectedLength = (sizeof(testData) + 3) / 4;
//
// Crc_StartNextTask(&crcStatus);
//
// EXPECT_EQ(crcStatus.activeSlot, &slot2);
// EXPECT_EQ(crcStatus.activeTask, 0);
// EXPECT_EQ(LL_DMA_SetM2MSrcAddress_mock_callcount, 1);
// EXPECT_EQ(LL_DMA_SetDataLength_mock_callcount, 1);
// EXPECT_EQ(LL_DMA_EnableStream_mock_callcount, 1);
// crcStatus.activeSlot->tasks[crcStatus.activeTask].callback = nullptr;
// crcStatus.activeSlot->tasks[crcStatus.activeTask].callbackParam = nullptr;
//
// Crc_StartNextTask(&crcStatus);
//
// EXPECT_EQ(crcStatus.activeSlot, &slot1);
// EXPECT_EQ(crcStatus.activeTask, 1);
// EXPECT_EQ(LL_DMA_SetM2MSrcAddress_mock_callcount, 2);
// EXPECT_EQ(LL_DMA_SetDataLength_mock_callcount, 2);
// 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";
// uint32_t FakeCustomData1, FakeCustomData2;
//
//
// memset(tasks1, 0, sizeof(tasks1));
// memset(tasks2, 0, sizeof(tasks2));
// memset(&fakeCrc, 0, sizeof(fakeCrc));
//
// fakeCrc.DR = 0xa5a55a5a;
//
// Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
// 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);
//
// ACTIVATE_MOCK(LL_DMA_DisableStream, mock);
// ACTIVATE_MOCK(LL_DMA_SetM2MSrcAddress, mock);
// ACTIVATE_MOCK(LL_DMA_SetDataLength, mock);
// ACTIVATE_MOCK(LL_DMA_EnableStream, mock);
// ACTIVATE_MOCK(Crc_StartNextTask, mock);
//
// expectedDma = DMA2;
// expectedStream = LL_DMA_STREAM_4;
//
// expectedCustomPtr = &FakeCustomData1;
// expectedCrc = fakeCrc.DR;
// expectedSuccess = 1;
//
// DMA2->HISR |= DMA_HISR_TCIF4;
// DMA2->HIFCR = 0;
//
// Crc_HandleDmaIrq(&crcStatus);
//
// EXPECT_EQ(LL_DMA_DisableStream_mock_callcount, 1);
//
// EXPECT_EQ(DMA2->HIFCR & DMA_HIFCR_CTCIF4, DMA_HIFCR_CTCIF4);
//
// expectedCustomPtr = &FakeCustomData2;
// DMA2->HISR |= DMA_HISR_TCIF4 | DMA_HISR_TEIF4;
// DMA2->HIFCR = 0;
// crcStatus.activeSlot->tasks[crcStatus.activeTask].callback = nullptr;
// crcStatus.activeSlot->tasks[crcStatus.activeTask].callbackParam = nullptr;
//
// Crc_HandleDmaIrq(&crcStatus);
//
// EXPECT_EQ(DMA2->HIFCR & (DMA_HIFCR_CTCIF4 | DMA_HIFCR_CTEIF4), DMA_HIFCR_CTCIF4 | DMA_HIFCR_CTEIF4);
// EXPECT_EQ(LL_DMA_DisableStream_mock_callcount, 2);
//}
//
//// 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_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_IsTaskQueued(&slot1, 0), 0);
// EXPECT_NE(Crc_IsTaskQueued(&slot1, 1), 0);
//
// Crc_StartNextTask(&crcStatus);
//
// EXPECT_EQ(Crc_IsTaskQueued(&slot1, 1), 0);
//}
//
//// 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_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_IsTaskBusy(&slot1, 0), 0);
// EXPECT_NE(Crc_IsTaskBusy(&slot1, 1), 0);
//
// DMA2->HISR |= DMA_HISR_TCIF4;
// Crc_HandleDmaIrq(&crcStatus);
//
// 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_IsTaskBusy(&slot1, 0), 0);
// EXPECT_EQ(Crc_IsTaskBusy(&slot1, 1), 0);
//}
//

File diff suppressed because it is too large Load diff