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

@ -124,7 +124,7 @@
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Startup"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Startup"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="application"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="application"/>
<entry excluding="f4ll_c/test" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="components"/> <entry excluding="f4ll_c/test" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="components"/>
<entry excluding="test|x86_gtest/googletest" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="platforms"/> <entry excluding="platform-test-f4-ll|test|x86_gtest/googletest" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="platforms"/>
</sourceEntries> </sourceEntries>
</configuration> </configuration>
</storageModule> </storageModule>
@ -252,7 +252,7 @@
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Startup"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Startup"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="application"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="application"/>
<entry excluding="f4ll_c/test" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="components"/> <entry excluding="f4ll_c/test" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="components"/>
<entry excluding="test|x86_gtest/googletest" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="platforms"/> <entry excluding="platform-test-f4-ll|test|x86_gtest/googletest" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="platforms"/>
</sourceEntries> </sourceEntries>
</configuration> </configuration>
</storageModule> </storageModule>
@ -271,7 +271,7 @@
</extensions> </extensions>
</storageModule> </storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0"> <storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" errorParsers="org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GCCErrorParser" id="cdt.managedbuild.config.gnu.exe.debug.1840394059.960309647" name="Unittest" parent="cdt.managedbuild.config.gnu.exe.debug" prebuildStep="cd ../platforms/test &amp;&amp; ./build-googletest.sh gtest_i386"> <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" errorParsers="org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GCCErrorParser" id="cdt.managedbuild.config.gnu.exe.debug.1840394059.960309647" name="Unittest" parent="cdt.managedbuild.config.gnu.exe.debug" prebuildStep="cd ../platforms/platform-test-f4-ll &amp;&amp; ./build_cpputest.sh &amp;&amp; ./build_subhook.sh">
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1840394059.960309647." name="/" resourcePath=""> <folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1840394059.960309647." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1057380913" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug"> <toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1057380913" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
<targetPlatform binaryParser="org.eclipse.cdt.core.GNU_ELF" id="cdt.managedbuild.target.gnu.platform.exe.debug.1321090068" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/> <targetPlatform binaryParser="org.eclipse.cdt.core.GNU_ELF" id="cdt.managedbuild.target.gnu.platform.exe.debug.1321090068" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
@ -284,8 +284,9 @@
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.1623248717" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.compiler.option.include.paths.1623248717" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="../inc"/> <listOptionValue builtIn="false" value="../inc"/>
<listOptionValue builtIn="false" value="../components/f4ll_c/inc"/> <listOptionValue builtIn="false" value="../components/f4ll_c/inc"/>
<listOptionValue builtIn="false" value="../platforms/test"/> <listOptionValue builtIn="false" value="../platforms/platform-test-f4-ll"/>
<listOptionValue builtIn="false" value="../platforms/test/gtest_i386/include"/> <listOptionValue builtIn="false" value="../platforms/platform-test-f4-ll/cpputest_x86/include"/>
<listOptionValue builtIn="false" value="../platforms/platform-test-f4-ll/subhook_x86/include"/>
</option> </option>
<option id="gnu.cpp.compiler.option.dialect.std.103125774" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/> <option id="gnu.cpp.compiler.option.dialect.std.103125774" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
<option id="gnu.cpp.compiler.option.preprocessor.preprocess.42158302" name="Preprocess only (-E)" superClass="gnu.cpp.compiler.option.preprocessor.preprocess" useByScannerDiscovery="false" value="false" valueType="boolean"/> <option id="gnu.cpp.compiler.option.preprocessor.preprocess.42158302" name="Preprocess only (-E)" superClass="gnu.cpp.compiler.option.preprocessor.preprocess" useByScannerDiscovery="false" value="false" valueType="boolean"/>
@ -302,14 +303,15 @@
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.1725421165" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.1725421165" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="../inc"/> <listOptionValue builtIn="false" value="../inc"/>
<listOptionValue builtIn="false" value="../components/f4ll_c/inc"/> <listOptionValue builtIn="false" value="../components/f4ll_c/inc"/>
<listOptionValue builtIn="false" value="../platforms/test"/> <listOptionValue builtIn="false" value="../platforms/platform-test-f4-ll"/>
<listOptionValue builtIn="false" value="../platforms/test/gtest_i386/include"/> <listOptionValue builtIn="false" value="../platforms/platform-test-f4-ll/cpputest_x86/include"/>
<listOptionValue builtIn="false" value="../platforms/platform-test-f4-ll/subhook_x86/include"/>
</option> </option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.preprocessor.def.symbols.1910702134" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.preprocessor.def.symbols.1910702134" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
<listOptionValue builtIn="false" value="UNITTEST"/> <listOptionValue builtIn="false" value="UNITTEST"/>
</option> </option>
<option id="gnu.c.compiler.option.preprocessor.preprocess.654871536" name="Preprocess only (-E)" superClass="gnu.c.compiler.option.preprocessor.preprocess" useByScannerDiscovery="false" value="false" valueType="boolean"/> <option id="gnu.c.compiler.option.preprocessor.preprocess.654871536" name="Preprocess only (-E)" superClass="gnu.c.compiler.option.preprocessor.preprocess" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="gnu.c.compiler.option.dialect.std.1002651825" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.c.compiler.dialect.default" valueType="enumerated"/> <option id="gnu.c.compiler.option.dialect.std.1002651825" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.c.compiler.dialect.c11" valueType="enumerated"/>
<option id="gnu.c.compiler.option.pthread.2055057964" name="Support for pthread (-pthread)" superClass="gnu.c.compiler.option.pthread" useByScannerDiscovery="false" value="true" valueType="boolean"/> <option id="gnu.c.compiler.option.pthread.2055057964" name="Support for pthread (-pthread)" superClass="gnu.c.compiler.option.pthread" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="gnu.c.compiler.option.optimization.flags.1990763554" name="Other optimization flags" superClass="gnu.c.compiler.option.optimization.flags" useByScannerDiscovery="false" value="-fno-inline" valueType="string"/> <option id="gnu.c.compiler.option.optimization.flags.1990763554" name="Other optimization flags" superClass="gnu.c.compiler.option.optimization.flags" useByScannerDiscovery="false" value="-fno-inline" valueType="string"/>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.537079503" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.537079503" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
@ -333,11 +335,13 @@
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1547977213" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"> <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1547977213" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
<option id="gnu.cpp.link.option.flags.892010408" name="Linker flags" superClass="gnu.cpp.link.option.flags" useByScannerDiscovery="false" value="-m32" valueType="string"/> <option id="gnu.cpp.link.option.flags.892010408" name="Linker flags" superClass="gnu.cpp.link.option.flags" useByScannerDiscovery="false" value="-m32" valueType="string"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.2050679230" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.paths.2050679230" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" useByScannerDiscovery="false" valueType="libPaths">
<listOptionValue builtIn="false" value="../platforms/test/gtest_i386/lib"/> <listOptionValue builtIn="false" value="../platforms/platform-test-f4-ll/cpputest_x86/lib"/>
<listOptionValue builtIn="false" value="../platforms/platform-test-f4-ll/subhook_x86/lib"/>
</option> </option>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.1965858469" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.cpp.link.option.libs.1965858469" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" useByScannerDiscovery="false" valueType="libs">
<listOptionValue builtIn="false" value="gtest"/> <listOptionValue builtIn="false" value="CppUTestExt"/>
<listOptionValue builtIn="false" value="gtest_main"/> <listOptionValue builtIn="false" value="CppUTest"/>
<listOptionValue builtIn="false" value="subhook"/>
</option> </option>
<option id="gnu.cpp.link.option.pthread.1592295432" name="Support for pthread (-pthread)" superClass="gnu.cpp.link.option.pthread" useByScannerDiscovery="false" value="true" valueType="boolean"/> <option id="gnu.cpp.link.option.pthread.1592295432" name="Support for pthread (-pthread)" superClass="gnu.cpp.link.option.pthread" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1591821302" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1591821302" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
@ -353,6 +357,7 @@
<sourceEntries> <sourceEntries>
<entry excluding="platform/googletest|f4ll_c/test/googletest|f4ll_c/mocks" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="components"/> <entry excluding="platform/googletest|f4ll_c/test/googletest|f4ll_c/mocks" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="components"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="inc"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="inc"/>
<entry excluding="cpputest|cpputest_x86|subhook_x86|subhook" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="platforms/platform-test-f4-ll"/>
<entry excluding="googletest" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="platforms/test"/> <entry excluding="googletest" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="platforms/test"/>
</sourceEntries> </sourceEntries>
</configuration> </configuration>
@ -375,6 +380,7 @@
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/> <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="refreshScope" versionNumber="2"> <storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Unittest"/>
<configuration configurationName="Debug"> <configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/f407ve_packetusart_c"/> <resource resourceType="PROJECT" workspacePath="/f407ve_packetusart_c"/>
</configuration> </configuration>

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_Copy(void *dst, void const *src, size_t length);
void Mcd_HandleDmaIrq(void); void Mcd_HandleDmaIrq(void);
#ifdef UNITTEST
DECLARE_MOCK(Mcd_Init);
DECLARE_MOCK(Mcd_Copy);
DECLARE_MOCK(Mcd_HandleDmaIrq);
#endif // UNITTEST
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -27,14 +27,10 @@
# define DIAG_INTERRUPT_OUT() # define DIAG_INTERRUPT_OUT()
#endif #endif
#ifndef MOCKABLE
#define MOCKABLE(x) x
#endif
void Crc_StartNextTask(struct crcstatus_t *status); 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; st->crcUnit = crcUnit;
Dma_Init(&st->dmaInfo, dma, stream); 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->count = taskCount;
slot->tasks = tasks; 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; 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; 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]; struct crctask_t volatile *taskPtr = &slot->tasks[task];
return taskPtr->callback != NULL || taskPtr->callbackParam != NULL; 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)); 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) void *address, uint16_t len, void (*callback)(void*, uint32_t, uint8_t), void* callbackParam)
{ {
uint32_t prim = __get_PRIMASK(); 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; uint32_t result;
Crc_Enqueue(status, slot, task, address, len, NULL, &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 // only called from ISR context
void MOCKABLE(Crc_StartNextTask)(struct crcstatus_t *status) void Crc_StartNextTask(struct crcstatus_t *status)
{ {
char moreTasks; char moreTasks;
uint8_t index = 0; 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 // !!!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; uint8_t success = 1;

View file

@ -5,11 +5,8 @@
* Author: abody * Author: abody
*/ */
#include <f4ll_c/dmahelper.h> #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) if(dma == DMA1)
return (stream < LL_DMA_STREAM_4) ? &DMA1->LISR : &DMA1->HISR; 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) if(dma == DMA1)
return (stream < LL_DMA_STREAM_4) ? &DMA1->LIFCR : &DMA1->HIFCR; 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; 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] = { 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 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]; return feMasks[stream];
} }
uint32_t MOCKABLE(Dma_GetDmeMask)(uint32_t stream) uint32_t Dma_GetDmeMask(uint32_t stream)
{ {
static const uint32_t dmeMasks[8] = { 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 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]; return dmeMasks[stream];
} }
uint32_t MOCKABLE(Dma_GetTeMask)(uint32_t stream) uint32_t Dma_GetTeMask(uint32_t stream)
{ {
static const uint32_t teMasks[8] = { 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 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]; return teMasks[stream];
} }
uint32_t MOCKABLE(Dma_GetHtMask)(uint32_t stream) uint32_t Dma_GetHtMask(uint32_t stream)
{ {
static const uint32_t htMasks[8] = { 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 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]; return htMasks[stream];
} }
uint32_t MOCKABLE(Dma_GetTcMask)(uint32_t stream) uint32_t Dma_GetTcMask(uint32_t stream)
{ {
static const uint32_t tcMasks[8] = { 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 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]; 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->dma = dma;
info->stream = stream; info->stream = stream;

View file

@ -15,21 +15,17 @@
# define DIAG_INTERRUPT_OUT() # define DIAG_INTERRUPT_OUT()
#endif #endif
#ifndef MOCKABLE
#define MOCKABLE(x) x
#endif // MOCKABLE
volatile uint8_t g_memcpyDmaBusy = 0; volatile uint8_t g_memcpyDmaBusy = 0;
static struct dmainfo_t g_memcpyDmaInfo; 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); Dma_Init(&g_memcpyDmaInfo, dma, stream);
LL_DMA_EnableIT_TC(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_SetM2MSrcAddress(g_memcpyDmaInfo.dma, g_memcpyDmaInfo.stream, (uint32_t)src);
LL_DMA_SetM2MDstAddress(g_memcpyDmaInfo.dma, g_memcpyDmaInfo.stream, (uint32_t)dst); 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; return dst;
} }
void MOCKABLE(Mcd_HandleDmaIrq)(void) void Mcd_HandleDmaIrq(void)
{ {
DIAG_INTERRUPT_IN(); DIAG_INTERRUPT_IN();
if(*g_memcpyDmaInfo.isReg & g_memcpyDmaInfo.tcMask) { // DMA transfer complete if(*g_memcpyDmaInfo.isReg & g_memcpyDmaInfo.tcMask) { // DMA transfer complete

View file

@ -15,10 +15,6 @@
#include "f4ll_c/dmahelper.h" #include "f4ll_c/dmahelper.h"
#include "f4ll_c/crcscheduler.h" #include "f4ll_c/crcscheduler.h"
#ifndef MOCKABLE
#define MOCKABLE(x) x
#endif
#ifndef DIAG_RX_BUFFER_SWITCH #ifndef DIAG_RX_BUFFER_SWITCH
# define DIAG_RX_BUFFER_SWITCH(x) # define DIAG_RX_BUFFER_SWITCH(x)
#endif #endif
@ -80,7 +76,7 @@ static inline void StatsAddSkiped(struct usart_stats *s, uint8_t cnt) {
#define StatsAddSkiped(x) #define StatsAddSkiped(x)
#endif // USART_STATS_DISABLED #endif // USART_STATS_DISABLED
void MOCKABLE(Pu_Init)( void Pu_Init(
struct usartstatus_t *st, USART_TypeDef *usart, DMA_TypeDef *dma, struct usartstatus_t *st, USART_TypeDef *usart, DMA_TypeDef *dma,
uint32_t stream_rx, uint32_t stream_tx, uint32_t stream_rx, uint32_t stream_tx,
struct crcstatus_t *crcStatus, 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; 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; 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; struct usart_buffer_t *buffer = &status->txBuffer;
uint8_t hash = STARTMARKER; 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; 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_ConfigAddresses(dma, stream, (uint32_t)buffer, LL_USART_DMA_GetRegAddr(usart), LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
LL_DMA_SetDataLength(dma, stream, length); 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]; struct usart_buffer_t *buffer = &status->rxBuffers[packetIndex];
if(buffer->busy) { 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(); DIAG_INTERRUPT_IN();
StatsIncRcvd(&status->stats); 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; struct usart_buffer_t *ub = (struct usart_buffer_t*) callbackParm;
if(!success) 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(); DIAG_INTERRUPT_IN();
if(*status->txDmaInfo.isReg & status->txDmaInfo.tcMask) { // DMA transfer complete 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(); DIAG_INTERRUPT_IN();
if(LL_USART_IsActiveFlag_IDLE(status->usart) && LL_USART_IsEnabledIT_IDLE(status->usart)) { // receiver idle 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 <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <inttypes.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 <thread>
#include <future> #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); 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

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="converted.config.1470469097">
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="makefileGenerator">
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
<parser enabled="false"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="false"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="false"/>
</scannerInfoProvider>
</profile>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.pathentry">
<pathentry kind="src" path=""/>
<pathentry kind="out" path=""/>
<pathentry kind="con" path="org.eclipse.cdt.make.core.DISCOVERED_SCANNER_INFO"/>
</storageModule>
<storageModule buildSystemId="org.eclipse.cdt.core.defaultConfigDataProvider" id="converted.config.1470469097" moduleId="org.eclipse.cdt.core.settings" name="convertedConfig">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
</cconfiguration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
</cproject>

View file

@ -6,7 +6,29 @@
*/ */
#include "cmsis.h" #include "cmsis.h"
#include <stdlib.h> #include <stdlib.h>
#include <CppUTestExt/MockSupport_c.h>
#include <platform/helpers.h>
void __disable_irq)() {} uint32_t g_effective_primask = 0;
uint32_t __get_PRIMASK() { return 0; }
void __set_PRIMASK(uint32_t primask) {} void __disable_irq() {
g_effective_primask = 1;
mock_c()->actualCall(__FUNCTION__);
}
void __enable_irq() {
g_effective_primask = 0;
mock_c()->actualCall(__FUNCTION__);
}
uint32_t __get_PRIMASK() {
return mock_c()->actualCall(__FUNCTION__)->
returnUnsignedIntValueOrDefault(g_effective_primask);
}
void __set_PRIMASK(uint32_t primask) {
g_effective_primask = primask;
mock_c()->actualCall(__FUNCTION__)->
withUnsignedIntParameters(TOSTR(primask), primask);
}

View file

@ -23,7 +23,9 @@ extern "C" {
#define READ_REG(REG) ((REG)) #define READ_REG(REG) ((REG))
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))) #define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
extern uint32_t g_effective_primask;
void __disable_irq(); void __disable_irq();
void __enable_irq();
uint32_t __get_PRIMASK(); uint32_t __get_PRIMASK();
void __set_PRIMASK(uint32_t priMask); void __set_PRIMASK(uint32_t priMask);

View file

@ -5,13 +5,90 @@
* Author: abody * Author: abody
*/ */
#include "dma_ll.h" #include "dma_ll.h"
#include <CppUTestExt/MockSupport_c.h>
#include <platform/helpers.h>
__attribute__((weak)) DMA_TypeDef _DMA1;
__attribute__((weak)) DMA_TypeDef _DMA2;
void LL_DMA_EnableIT_TC(DMA_TypeDef *DMAx, uint32_t Stream)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(DMAx), DMAx)->
withUnsignedIntParameters(TOSTR(Stream), Stream);
}
void LL_DMA_EnableIT_TE(DMA_TypeDef *DMAx, uint32_t Stream)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(DMAx), DMAx)->
withUnsignedIntParameters(TOSTR(Stream), Stream);
}
void LL_DMA_SetM2MDstAddress(DMA_TypeDef* DMAx, uint32_t Stream, uint32_t MemoryAddress)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(DMAx), DMAx)->
withUnsignedIntParameters(TOSTR(Stream), Stream)->
withUnsignedIntParameters(TOSTR(MemoryAddress), MemoryAddress);
}
void LL_DMA_SetM2MSrcAddress(DMA_TypeDef* DMAx, uint32_t Stream, uint32_t MemoryAddress)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(DMAx), DMAx)->
withUnsignedIntParameters(TOSTR(Stream), Stream)->
withUnsignedIntParameters(TOSTR(MemoryAddress), MemoryAddress);
}
uint32_t LL_DMA_GetDataLength(DMA_TypeDef* DMAx, uint32_t Stream)
{
return mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(DMAx), DMAx)->
withUnsignedIntParameters(TOSTR(Stream), Stream)->
returnUnsignedIntValueOrDefault(0);
}
void LL_DMA_SetDataLength(DMA_TypeDef* DMAx, uint32_t Stream, uint32_t NbData)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(DMAx), DMAx)->
withUnsignedIntParameters(TOSTR(Stream), Stream)->
withUnsignedIntParameters(TOSTR(NbData), NbData);
}
void LL_DMA_EnableStream(DMA_TypeDef *DMAx, uint32_t Stream)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(DMAx), DMAx)->
withUnsignedIntParameters(TOSTR(Stream), Stream);
}
void LL_DMA_DisableStream(DMA_TypeDef *DMAx, uint32_t Stream)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(DMAx), DMAx)->
withUnsignedIntParameters(TOSTR(Stream), Stream);
}
void LL_DMA_ConfigAddresses(DMA_TypeDef* DMAx, uint32_t Stream, uint32_t SrcAddress, uint32_t DstAddress, uint32_t Direction)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(DMAx), DMAx)->
withUnsignedIntParameters(TOSTR(Stream), Stream)->
withUnsignedIntParameters(TOSTR(SrcAddress), SrcAddress)->
withUnsignedIntParameters(TOSTR(DstAddress), DstAddress)->
withUnsignedIntParameters(TOSTR(Direction), Direction);
}
void LL_DMA_EnableIT_TC(DMA_TypeDef *DMAx, uint32_t Stream) {}
void LL_DMA_EnableIT_TE(DMA_TypeDef *DMAx, uint32_t Stream) {}
void LL_DMA_SetM2MDstAddress(DMA_TypeDef* DMAx, uint32_t Stream, uint32_t MemoryAddress) {}
void LL_DMA_SetM2MSrcAddress(DMA_TypeDef* DMAx, uint32_t Stream, uint32_t MemoryAddress) {}
uint32_t LL_DMA_GetDataLength(DMA_TypeDef* DMAx, uint32_t Stream) { return 0; }
void LL_DMA_SetDataLength(DMA_TypeDef* DMAx, uint32_t Stream, uint32_t NbData) {}
void LL_DMA_EnableStream(DMA_TypeDef *DMAx, uint32_t Stream) {}
void LL_DMA_DisableStream(DMA_TypeDef *DMAx, uint32_t Stream) {}
void LL_DMA_ConfigAddresses(DMA_TypeDef* DMAx, uint32_t Stream, uint32_t SrcAddress, uint32_t DstAddress, uint32_t Direction) {}

View file

@ -608,8 +608,11 @@ typedef struct
extern DMA_TypeDef *DMA1; extern DMA_TypeDef _DMA1;
extern DMA_TypeDef *DMA2; extern DMA_TypeDef _DMA2;
#define DMA1 (&_DMA1)
#define DMA2 (&_DMA2)
void LL_DMA_EnableIT_TC(DMA_TypeDef *DMAx, uint32_t Stream); void LL_DMA_EnableIT_TC(DMA_TypeDef *DMAx, uint32_t Stream);
void LL_DMA_EnableIT_TE(DMA_TypeDef *DMAx, uint32_t Stream); void LL_DMA_EnableIT_TE(DMA_TypeDef *DMAx, uint32_t Stream);

View file

@ -0,0 +1,13 @@
/*
* helpers.h
*
* Created on: Feb 25, 2021
* Author: compi
*/
#ifndef PLATFORM_HELPERS_H_
#define PLATFORM_HELPERS_H_
#define TOSTR(x) #x
#endif /* PLATFORM_HELPERS_H_ */

View file

@ -0,0 +1,7 @@
#include <stdint.h>
#include <CppUTest/CommandLineTestRunner.h>
int main(int ac, char** av)
{
return CommandLineTestRunner::RunAllTests(ac, av);
}

View file

@ -6,22 +6,115 @@
*/ */
#include "usart_ll.h" #include "usart_ll.h"
#include <CppUTestExt/MockSupport_c.h>
#include <platform/helpers.h>
void LL_USART_EnableIT_IDLE(USART_TypeDef *USARTx) {} __attribute__((weak)) USART_TypeDef _USART1;
void LL_USART_EnableIT_TC(USART_TypeDef *USARTx) {} __attribute__((weak)) USART_TypeDef _USART2;
void LL_USART_DisableIT_TC(USART_TypeDef *USARTx) {} __attribute__((weak)) USART_TypeDef _USART3;
uint32_t LL_USART_IsEnabledIT_IDLE(USART_TypeDef *USARTx) { return 1; } __attribute__((weak)) USART_TypeDef _USART6;
uint32_t LL_USART_IsEnabledIT_TC(USART_TypeDef *USARTx) { return 1; }
void LL_USART_EnableDMAReq_RX(USART_TypeDef *USARTx) {} void LL_USART_EnableIT_IDLE(USART_TypeDef *USARTx)
void LL_USART_EnableDMAReq_TX(USART_TypeDef *USARTx) {} {
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(USARTx), USARTx);
}
uint32_t LL_USART_DMA_GetRegAddr(USART_TypeDef *USARTx) { return 0; }
uint32_t LL_USART_IsActiveFlag_IDLE(USART_TypeDef *USARTx) { return 1; } void LL_USART_EnableIT_TC(USART_TypeDef *USARTx)
uint32_t LL_USART_IsActiveFlag_TC(USART_TypeDef *USARTx) { return 1; } {
void LL_USART_ClearFlag_ORE(USART_TypeDef *USARTx) {} mock_c()->actualCall(__FUNCTION__)->
void LL_USART_ClearFlag_IDLE(USART_TypeDef *USARTx) {} withPointerParameters(TOSTR(USARTx), USARTx);
}
void LL_USART_DisableIT_TC(USART_TypeDef *USARTx)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(USARTx), USARTx);
}
uint32_t LL_USART_IsEnabledIT_IDLE(USART_TypeDef *USARTx)
{
return mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(USARTx), USARTx)->
returnUnsignedIntValueOrDefault(1);
}
uint32_t LL_USART_IsEnabledIT_TC(USART_TypeDef *USARTx)
{
return mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(USARTx), USARTx)->
returnUnsignedIntValueOrDefault(1);
}
void LL_USART_EnableDMAReq_RX(USART_TypeDef *USARTx)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(USARTx), USARTx);
}
void LL_USART_EnableDMAReq_TX(USART_TypeDef *USARTx)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(USARTx), USARTx);
}
uint32_t LL_USART_DMA_GetRegAddr(USART_TypeDef *USARTx)
{
return mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(USARTx), USARTx)->
returnUnsignedIntValueOrDefault(0);
}
uint32_t LL_USART_IsActiveFlag_IDLE(USART_TypeDef *USARTx)
{
return mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(USARTx), USARTx)->
returnUnsignedIntValueOrDefault(1);
}
uint32_t LL_USART_IsActiveFlag_TC(USART_TypeDef *USARTx)
{
return mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(USARTx), USARTx)->
returnUnsignedIntValueOrDefault(1);
}
void LL_USART_ClearFlag_ORE(USART_TypeDef *USARTx)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(USARTx), USARTx);
}
void LL_USART_ClearFlag_IDLE(USART_TypeDef *USARTx)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(USARTx), USARTx);
}
void LL_USART_EnableDirectionTx(USART_TypeDef *USARTx)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(USARTx), USARTx);
}
void LL_USART_DisableDirectionTx(USART_TypeDef *USARTx)
{
mock_c()->actualCall(__FUNCTION__)->
withPointerParameters(TOSTR(USARTx), USARTx);
}
void LL_USART_EnableDirectionTx(USART_TypeDef *USARTx) {}
void LL_USART_DisableDirectionTx(USART_TypeDef *USARTx) {}

View file

@ -198,10 +198,15 @@ typedef struct
/*----------- cut here -----------*/ /*----------- cut here -----------*/
extern USART_TypeDef *USART1; extern USART_TypeDef _USART1;
extern USART_TypeDef *USART2; extern USART_TypeDef _USART2;
extern USART_TypeDef *USART3; extern USART_TypeDef _USART3;
extern USART_TypeDef *USART6; extern USART_TypeDef _USART6;
#define USART1 (&_USART1)
#define USART2 (&_USART2)
#define USART3 (&_USART3)
#define USART6 (&_USART6)
void LL_USART_EnableIT_IDLE(USART_TypeDef *USARTx); void LL_USART_EnableIT_IDLE(USART_TypeDef *USARTx);
void LL_USART_EnableIT_TC(USART_TypeDef *USARTx); void LL_USART_EnableIT_TC(USART_TypeDef *USARTx);