From 084e23850fb5014048f336dda52eb63edb0ea018 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 30 Dec 2023 16:45:35 -0600 Subject: [PATCH 01/57] So make unittest TEST_LEADER=HelloWorld works... --- Tests/UnitTests/HelloWorld.c | 5 + Tests/UnitTests/Makefile | 110 + Tests/UnitTests/fff.h | 6588 +++++++++++++++++++++++++++++ Tests/UnitTests/theMakefilecopyof | 216 + 4 files changed, 6919 insertions(+) create mode 100644 Tests/UnitTests/HelloWorld.c create mode 100644 Tests/UnitTests/Makefile create mode 100644 Tests/UnitTests/fff.h create mode 100644 Tests/UnitTests/theMakefilecopyof diff --git a/Tests/UnitTests/HelloWorld.c b/Tests/UnitTests/HelloWorld.c new file mode 100644 index 000000000..4668ec1fa --- /dev/null +++ b/Tests/UnitTests/HelloWorld.c @@ -0,0 +1,5 @@ +#include + +int main(void) { + printf("\n\rHello world\n\r"); +} \ No newline at end of file diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile new file mode 100644 index 000000000..dee07f003 --- /dev/null +++ b/Tests/UnitTests/Makefile @@ -0,0 +1,110 @@ + +# Build path +BUILD_DIR = Objects#../../Objects + +###################################### +# source + +# changed to +C_SOURCES = \ +../$(TEST) + +####################################### +# binaries +####################################### +PREFIX = #arm-none-eabi- not this time! ## +# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) +# or it can be added to the PATH environment variable. +CC = $(PREFIX)gcc +AS = $(PREFIX)gcc -x assembler-with-cpp +CP = $(PREFIX)objcopy +SZ = $(PREFIX)size + +HEX = $(CP) -O ihex +BIN = $(CP) -O binary -S + +SF = st-flash + +####################################### +# CFLAGS +####################################### +# cpu +#CPU = -mcpu=cortex-m4 commented out## + +# float-abi +#FLOAT-ABI = -mfloat-abi=soft co## + +# mcu +#MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) co## + +# macros for gcc +# AS defines +#AS_DEFS = co## + +# C defines +# C_DEFS = \ co## +# -DSTM32F413_423xx \ +# -DUSE_STDPERIPH_DRIVER \ +# -D__FPU_PRESENT + + +# AS includes +#AS_INCLUDES = #co + +ifeq ($(DEBUG), 1) +CFLAGS += -g3 -gdwarf-2 -DDEBUG +endif + +ifeq ($(MOTOR_LOOPBACK), 1) +CFLAGS += -DMOTOR_LOOPBACK +endif + +ifeq ($(CAR_LOOPBACK), 1) +CFLAGS += -DCAR_LOOPBACK +endif + + +####################################### +# build the application +####################################### +# list of objects +OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) +vpath %.c $(sort $(dir $(C_SOURCES))) +# list of ASM program objects +OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) +vpath %.s $(sort $(dir $(ASM_SOURCES))) + +##Added +TOCOMPILE := $(TEST_LEADER) +## # @$(CC) $(OBJECTS) -o $@ + +#added +$(BUILD_DIR)/$(TARGET).o: $(BUILD_DIR) + @echo "LD $(<:../../%=%)" + @$(CC) $(TOCOMPILE).c -o $(BUILD_DIR)/$(TOCOMPILE).o + @echo "SZ $(<:../../%=%)" + +#end add ^^ use to be @$(SZ) $@ + + +$(BUILD_DIR): + mkdir $@ + +####################################### +# clean up +####################################### +clean: + -rm -fR $(BUILD_DIR) + +####################################### +# flash +####################################### +flash: + $(SF) write $(BUILD_DIR)/$(TARGET).bin 0x8000000 + +####################################### +# dependencies +####################################### +-include $(wildcard $(BUILD_DIR)/*.d) + +# *** EOF *** diff --git a/Tests/UnitTests/fff.h b/Tests/UnitTests/fff.h new file mode 100644 index 000000000..6601f846f --- /dev/null +++ b/Tests/UnitTests/fff.h @@ -0,0 +1,6588 @@ +/* +LICENSE + +The MIT License (MIT) + +Copyright (c) 2010 Michael Long + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +#ifndef FAKE_FUNCTIONS +#define FAKE_FUNCTIONS + +#include +#include /* For memset and memcpy */ + +#define FFF_MAX_ARGS (20u) +#ifndef FFF_ARG_HISTORY_LEN + #define FFF_ARG_HISTORY_LEN (50u) +#endif +#ifndef FFF_CALL_HISTORY_LEN + #define FFF_CALL_HISTORY_LEN (50u) +#endif +#ifndef FFF_GCC_FUNCTION_ATTRIBUTES + #define FFF_GCC_FUNCTION_ATTRIBUTES +#endif +#ifndef CUSTOM_FFF_FUNCTION_TEMPLATE +#define CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN, FUNCNAME, ...) \ + RETURN(*FUNCNAME)(__VA_ARGS__) +#endif /* CUSTOM_FFF_FUNCTION_TEMPLATE */ +/* -- INTERNAL HELPER MACROS -- */ +#define SET_RETURN_SEQ(FUNCNAME, ARRAY_POINTER, ARRAY_LEN) \ + FUNCNAME##_fake.return_val_seq = ARRAY_POINTER; \ + FUNCNAME##_fake.return_val_seq_len = ARRAY_LEN; +#define SET_CUSTOM_FAKE_SEQ(FUNCNAME, ARRAY_POINTER, ARRAY_LEN) \ + FUNCNAME##_fake.custom_fake_seq = ARRAY_POINTER; \ + FUNCNAME##_fake.custom_fake_seq_len = ARRAY_LEN; + +/* Defining a function to reset a fake function */ +#define RESET_FAKE(FUNCNAME) { \ + FUNCNAME##_reset(); \ +} \ + + +#define DECLARE_ARG(type, n, FUNCNAME) \ + type arg##n##_val; \ + type arg##n##_history[FFF_ARG_HISTORY_LEN]; + +#define DECLARE_ALL_FUNC_COMMON \ + unsigned int call_count; \ + unsigned int arg_history_len; \ + unsigned int arg_histories_dropped; \ + +#define DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + RETURN_TYPE return_val_history[FFF_ARG_HISTORY_LEN]; + +#define SAVE_ARG(FUNCNAME, n) \ + memcpy((void*)&FUNCNAME##_fake.arg##n##_val, (void*)&arg##n, sizeof(arg##n)); + +#define ROOM_FOR_MORE_HISTORY(FUNCNAME) \ + FUNCNAME##_fake.call_count < FFF_ARG_HISTORY_LEN + +#define SAVE_RET_HISTORY(FUNCNAME, RETVAL) \ + if ((FUNCNAME##_fake.call_count - 1) < FFF_ARG_HISTORY_LEN) \ + memcpy((void *)&FUNCNAME##_fake.return_val_history[FUNCNAME##_fake.call_count - 1], (const void *) &RETVAL, sizeof(RETVAL)); \ + +#define SAVE_ARG_HISTORY(FUNCNAME, ARGN) \ + memcpy((void*)&FUNCNAME##_fake.arg##ARGN##_history[FUNCNAME##_fake.call_count], (void*)&arg##ARGN, sizeof(arg##ARGN)); + +#define HISTORY_DROPPED(FUNCNAME) \ + FUNCNAME##_fake.arg_histories_dropped++ + +#define DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + RETURN_TYPE return_val; \ + int return_val_seq_len; \ + int return_val_seq_idx; \ + RETURN_TYPE * return_val_seq; \ + +#define DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + int custom_fake_seq_len; \ + int custom_fake_seq_idx; \ + +#define INCREMENT_CALL_COUNT(FUNCNAME) \ + FUNCNAME##_fake.call_count++ + +#define RETURN_FAKE_RESULT(FUNCNAME) \ + if (FUNCNAME##_fake.return_val_seq_len){ /* then its a sequence */ \ + if(FUNCNAME##_fake.return_val_seq_idx < FUNCNAME##_fake.return_val_seq_len) { \ + SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_idx]) \ + return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_idx++]; \ + } \ + SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len-1]) \ + return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len-1]; /* return last element */ \ + } \ + SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val) \ + return FUNCNAME##_fake.return_val; \ + +#ifdef __cplusplus + #define FFF_EXTERN_C extern "C"{ + #define FFF_END_EXTERN_C } +#else /* ansi c */ + #define FFF_EXTERN_C + #define FFF_END_EXTERN_C +#endif /* cpp/ansi c */ + +#define DEFINE_RESET_FUNCTION(FUNCNAME) \ + void FUNCNAME##_reset(void){ \ + memset((void*)&FUNCNAME##_fake, 0, sizeof(FUNCNAME##_fake) - sizeof(FUNCNAME##_fake.custom_fake) - sizeof(FUNCNAME##_fake.custom_fake_seq)); \ + FUNCNAME##_fake.custom_fake = NULL; \ + FUNCNAME##_fake.custom_fake_seq = NULL; \ + FUNCNAME##_fake.arg_history_len = FFF_ARG_HISTORY_LEN; \ + } +/* -- END INTERNAL HELPER MACROS -- */ + +typedef void (*fff_function_t)(void); +typedef struct { + fff_function_t call_history[FFF_CALL_HISTORY_LEN]; + unsigned int call_history_idx; +} fff_globals_t; + +FFF_EXTERN_C +extern fff_globals_t fff; +FFF_END_EXTERN_C + +#define DEFINE_FFF_GLOBALS \ + FFF_EXTERN_C \ + fff_globals_t fff; \ + FFF_END_EXTERN_C + +#define FFF_RESET_HISTORY() \ + fff.call_history_idx = 0; \ + memset(fff.call_history, 0, sizeof(fff.call_history)); + +#define REGISTER_CALL(function) \ + if(fff.call_history_idx < FFF_CALL_HISTORY_LEN) \ + fff.call_history[fff.call_history_idx++] = (fff_function_t)function; + +#define DECLARE_FAKE_VOID_FUNC0(FUNCNAME) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, void); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, void); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(void); \ + +#define DEFINE_FAKE_VOID_FUNC0(FUNCNAME) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(void){ \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC0(FUNCNAME) \ + DECLARE_FAKE_VOID_FUNC0(FUNCNAME) \ + DEFINE_FAKE_VOID_FUNC0(FUNCNAME) \ + + +#define DECLARE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0); \ + +#define DEFINE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + DECLARE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + DEFINE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + +#define DEFINE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DECLARE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DEFINE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + +#define DEFINE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DECLARE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DEFINE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + +#define DEFINE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DECLARE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DEFINE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + +#define DEFINE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DECLARE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DEFINE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + +#define DEFINE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DECLARE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DEFINE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + +#define DEFINE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DECLARE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DEFINE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + +#define DEFINE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DECLARE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DEFINE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + +#define DEFINE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DECLARE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DEFINE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + +#define DEFINE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DECLARE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DEFINE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + +#define DEFINE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DECLARE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DEFINE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + +#define DEFINE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DECLARE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DEFINE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + +#define DEFINE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DECLARE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DEFINE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + +#define DEFINE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DECLARE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DEFINE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + +#define DEFINE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DECLARE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DEFINE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + +#define DEFINE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DECLARE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DEFINE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + +#define DEFINE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DECLARE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DEFINE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + +#define DEFINE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DECLARE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DEFINE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + +#define DEFINE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DECLARE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DEFINE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ARG(ARG19_TYPE, 19, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + +#define DEFINE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + SAVE_ARG(FUNCNAME, 19); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + SAVE_ARG_HISTORY(FUNCNAME, 19); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DECLARE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DEFINE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, void); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, void); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(void); \ + +#define DEFINE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(void){ \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + DECLARE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + DEFINE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + + +#define DECLARE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0); \ + +#define DEFINE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + DECLARE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + DEFINE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + +#define DEFINE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DECLARE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DEFINE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + +#define DEFINE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DECLARE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DEFINE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + +#define DEFINE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DECLARE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DEFINE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + +#define DEFINE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DECLARE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DEFINE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + +#define DEFINE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DECLARE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DEFINE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + +#define DEFINE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DECLARE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DEFINE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + +#define DEFINE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DECLARE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DEFINE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + +#define DEFINE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DECLARE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DEFINE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + +#define DEFINE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DECLARE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DEFINE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + +#define DEFINE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DECLARE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DEFINE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + +#define DEFINE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DECLARE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DEFINE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + +#define DEFINE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DECLARE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DEFINE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + +#define DEFINE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DECLARE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DEFINE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + +#define DEFINE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DECLARE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DEFINE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + +#define DEFINE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DECLARE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DEFINE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + +#define DEFINE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DECLARE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DEFINE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + +#define DEFINE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DECLARE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DEFINE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + +#define DEFINE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DECLARE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DEFINE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ARG(ARG19_TYPE, 19, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + +#define DEFINE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + SAVE_ARG(FUNCNAME, 19); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + SAVE_ARG_HISTORY(FUNCNAME, 19); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake != NULL){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DECLARE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DEFINE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ...); \ + +#define DEFINE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg0); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg0); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg0); \ + FUNCNAME##_fake.custom_fake(arg0, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...); \ + +#define DEFINE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg1); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg1); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg1); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...); \ + +#define DEFINE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg2); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg2); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg2); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...); \ + +#define DEFINE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg3); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg3); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg3); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...); \ + +#define DEFINE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg4); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg4); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg4); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...); \ + +#define DEFINE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg5); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg5); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg5); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...); \ + +#define DEFINE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg6); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg6); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg6); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...); \ + +#define DEFINE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg7); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg7); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg7); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...); \ + +#define DEFINE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg8); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg8); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg8); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...); \ + +#define DEFINE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg9); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg9); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg9); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...); \ + +#define DEFINE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg10); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg10); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg10); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...); \ + +#define DEFINE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg11); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg11); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg11); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...); \ + +#define DEFINE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg12); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg12); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg12); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...); \ + +#define DEFINE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg13); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg13); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg13); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...); \ + +#define DEFINE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg14); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg14); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg14); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...); \ + +#define DEFINE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg15); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg15); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg15); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...); \ + +#define DEFINE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg16); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg16); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg16); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...); \ + +#define DEFINE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg17); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg17); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg17); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...); \ + +#define DEFINE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg18); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg18); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg18); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg0); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg0); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg0); \ + ret = FUNCNAME##_fake.custom_fake(arg0, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg1); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg1); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg1); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg2); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg2); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg2); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg3); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg3); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg3); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg4); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg4); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg4); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg5); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg5); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg5); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg6); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg6); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg6); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg7); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg7); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg7); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg8); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg8); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg8); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg9); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg9); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg9); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg10); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg10); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg10); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg11); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg11); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg11); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg12); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg12); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg12); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg13); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg13); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg13); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg14); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg14); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg14); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg15); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg15); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg15); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg16); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg16); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg16); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg17); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg17); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg17); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, va_list ap); \ + CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg18); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg18); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg18); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + +/* MSVC expand macro fix */ +#define EXPAND(x) x + +#define PP_NARG_MINUS2(...) EXPAND(PP_NARG_MINUS2_(__VA_ARGS__, PP_RSEQ_N_MINUS2())) + +#define PP_NARG_MINUS2_(...) EXPAND(PP_ARG_MINUS2_N(__VA_ARGS__)) + +#define PP_ARG_MINUS2_N(returnVal, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N + +#define PP_RSEQ_N_MINUS2() 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + +#define PP_NARG_MINUS1(...) EXPAND(PP_NARG_MINUS1_(__VA_ARGS__, PP_RSEQ_N_MINUS1())) + +#define PP_NARG_MINUS1_(...) EXPAND(PP_ARG_MINUS1_N(__VA_ARGS__)) + +#define PP_ARG_MINUS1_N( _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N + +#define PP_RSEQ_N_MINUS1() 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + + + +/* DECLARE AND DEFINE FAKE FUNCTIONS - PLACE IN TEST FILES */ + +#define FAKE_VALUE_FUNC(...) EXPAND(FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VALUE_(N,...) EXPAND(FUNC_VALUE_N(N,__VA_ARGS__)) + +#define FUNC_VALUE_N(N,...) EXPAND(FAKE_VALUE_FUNC ## N(__VA_ARGS__)) + + +#define FAKE_VOID_FUNC(...) EXPAND(FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VOID_(N,...) EXPAND(FUNC_VOID_N(N,__VA_ARGS__)) + +#define FUNC_VOID_N(N,...) EXPAND(FAKE_VOID_FUNC ## N(__VA_ARGS__)) + + +#define FAKE_VALUE_FUNC_VARARG(...) EXPAND(FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VALUE_VARARG_(N,...) EXPAND(FUNC_VALUE_VARARG_N(N,__VA_ARGS__)) + +#define FUNC_VALUE_VARARG_N(N,...) EXPAND(FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__)) + + +#define FAKE_VOID_FUNC_VARARG(...) EXPAND(FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VOID_VARARG_(N,...) EXPAND(FUNC_VOID_VARARG_N(N,__VA_ARGS__)) + +#define FUNC_VOID_VARARG_N(N,...) EXPAND(FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__)) + + + +/* DECLARE FAKE FUNCTIONS - PLACE IN HEADER FILES */ + +#define DECLARE_FAKE_VALUE_FUNC(...) EXPAND(DECLARE_FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_(N,...) EXPAND(DECLARE_FUNC_VALUE_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_N(N,...) EXPAND(DECLARE_FAKE_VALUE_FUNC ## N(__VA_ARGS__)) + + +#define DECLARE_FAKE_VOID_FUNC(...) EXPAND(DECLARE_FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VOID_(N,...) EXPAND(DECLARE_FUNC_VOID_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VOID_N(N,...) EXPAND(DECLARE_FAKE_VOID_FUNC ## N(__VA_ARGS__)) + + +#define DECLARE_FAKE_VALUE_FUNC_VARARG(...) EXPAND(DECLARE_FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_VARARG_(N,...) EXPAND(DECLARE_FUNC_VALUE_VARARG_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_VARARG_N(N,...) EXPAND(DECLARE_FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__)) + + +#define DECLARE_FAKE_VOID_FUNC_VARARG(...) EXPAND(DECLARE_FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VOID_VARARG_(N,...) EXPAND(DECLARE_FUNC_VOID_VARARG_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VOID_VARARG_N(N,...) EXPAND(DECLARE_FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__)) + + + +/* DEFINE FAKE FUNCTIONS - PLACE IN SOURCE FILES */ + +#define DEFINE_FAKE_VALUE_FUNC(...) EXPAND(DEFINE_FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_(N,...) EXPAND(DEFINE_FUNC_VALUE_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_N(N,...) EXPAND(DEFINE_FAKE_VALUE_FUNC ## N(__VA_ARGS__)) + + +#define DEFINE_FAKE_VOID_FUNC(...) EXPAND(DEFINE_FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VOID_(N,...) EXPAND(DEFINE_FUNC_VOID_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VOID_N(N,...) EXPAND(DEFINE_FAKE_VOID_FUNC ## N(__VA_ARGS__)) + + +#define DEFINE_FAKE_VALUE_FUNC_VARARG(...) EXPAND(DEFINE_FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_VARARG_(N,...) EXPAND(DEFINE_FUNC_VALUE_VARARG_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_VARARG_N(N,...) EXPAND(DEFINE_FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__)) + + +#define DEFINE_FAKE_VOID_FUNC_VARARG(...) EXPAND(DEFINE_FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VOID_VARARG_(N,...) EXPAND(DEFINE_FUNC_VOID_VARARG_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VOID_VARARG_N(N,...) EXPAND(DEFINE_FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__)) + + + + +#endif /* FAKE_FUNCTIONS */ \ No newline at end of file diff --git a/Tests/UnitTests/theMakefilecopyof b/Tests/UnitTests/theMakefilecopyof new file mode 100644 index 000000000..65ee0bf45 --- /dev/null +++ b/Tests/UnitTests/theMakefilecopyof @@ -0,0 +1,216 @@ +###################################### +# target +###################################### +TARGET = controls-leader + + +###################################### +# building variables +###################################### +# optimization +ifeq ($(DEBUG), 0) +OPT = -O3 +else +OPT = -Og -g3 +endif + +####################################### +# paths +####################################### +# Build path +BUILD_DIR = Objects#../../Objects + +###################################### +# source +###################################### +# C sources +# since current path is in the BSP folder, go to the top level with ../../ +# C_SOURCES = \ commented out! +# $(wildcard ../../Drivers/Src/*.c) \ +# $(wildcard ../../BSP/STM32F413/Src/*.c) \ +# $(wildcard ../../BSP/STM32F413/STM32F4xx_StdPeriph_Driver/Src/*.c) \ +# $(wildcard ../../CMSIS/DSP_Lib/Source/*.c) \ +# $(wildcard ../../RTOS/uCOS-III-STM32F4/uCOS-III/Source/*.c) \ +# $(wildcard ../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/*.c) \ +# $(wildcard ../../RTOS/uCOS-III-STM32F4/uC-CPU/*.c) \ +# $(wildcard ../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/*.c) \ +# $(wildcard ../../RTOS/uCOS-III-STM32F4/uC-LIB/*.c) + +# This line adds everything in Apps/Src/*.c except for main.c, then adds the test file +#C_SOURCES += \ +$(filter-out ../../Apps/Src/main.c, $(wildcard ../../Apps/Src/*.c)) \ +../../$(TEST) + +# changed to +C_SOURCES = \ +../$(TEST) + +# ASM sources +# ASM_SOURCES = \ commented out!## +# ../../BSP/STM32F413/Src/startup_stm32f413xx.s \ +# ../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/os_cpu_a.s \ +# ../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/cpu_a.s + + +####################################### +# binaries +####################################### +PREFIX = #arm-none-eabi- not this time! ## +# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) +# or it can be added to the PATH environment variable. +ifdef GCC_PATH +CC = $(GCC_PATH)/$(PREFIX)gcc +AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp +CP = $(GCC_PATH)/$(PREFIX)objcopy +SZ = $(GCC_PATH)/$(PREFIX)size +else +CC = $(PREFIX)gcc +AS = $(PREFIX)gcc -x assembler-with-cpp +CP = $(PREFIX)objcopy +SZ = $(PREFIX)size +endif +HEX = $(CP) -O ihex +BIN = $(CP) -O binary -S + +SF = st-flash + +####################################### +# CFLAGS +####################################### +# cpu +#CPU = -mcpu=cortex-m4 commented out## + +# float-abi +#FLOAT-ABI = -mfloat-abi=soft co## + +# mcu +#MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) co## + +# macros for gcc +# AS defines +#AS_DEFS = co## + +# C defines +# C_DEFS = \ co## +# -DSTM32F413_423xx \ +# -DUSE_STDPERIPH_DRIVER \ +# -D__FPU_PRESENT + + +# AS includes +#AS_INCLUDES = #co + +# C includes +# since current path is in the BSP folder, go to the top level with ../../ +#C_INCLUDES = \ #not sure if we need this...? + #-I../../Apps/Inc \ +-I../../Drivers/Inc \ +-I../../Config/Inc \ +-I../../BSP/Inc \ +-I../../CMSIS/Device/ST/STM32F4xx/Include \ +-I../../CMSIS/Include \ +-I../../BSP/STM32F413/STM32F4xx_StdPeriph_Driver/Inc \ +-I../../RTOS/uCOS-III-STM32F4/uCOS-III/Source/ \ +-I../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/ \ +-I../../RTOS/uCOS-III-STM32F4/uC-CPU/ \ +-I../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/ \ +-I../../RTOS/uCOS-III-STM32F4/uC-LIB/ \ +-I../../Tests/Inc/ \ + +# compile gcc flags +# ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections commented out + +CFLAGS = $(C_INCLUDES) -Wall -Werror -fdata-sections -ffunction-sections#$(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -Werror -fdata-sections -ffunction-sections + +ifeq ($(DEBUG), 1) +CFLAGS += -g3 -gdwarf-2 -DDEBUG +endif + +ifeq ($(MOTOR_LOOPBACK), 1) +CFLAGS += -DMOTOR_LOOPBACK +endif + +ifeq ($(CAR_LOOPBACK), 1) +CFLAGS += -DCAR_LOOPBACK +endif + +# Generate dependency information +CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" + + +####################################### +# LDFLAGS +####################################### +# link script +#LDSCRIPT = ./GCC/STM32F413RHTx_FLASH.ld #co### + +# libraries +LIBS = -lc -lm -lnosys +LIBDIR = +#LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections co## + +# default action: build all +all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin $(BUILD_DIR)/$(TARGET).o + + +####################################### +# build the application +####################################### +# list of objects +OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) +vpath %.c $(sort $(dir $(C_SOURCES))) +# list of ASM program objects +OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) +vpath %.s $(sort $(dir $(ASM_SOURCES))) + +$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) + @echo "CC $(<:../../%=%)" + @$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ + +$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) + @echo "AS $(<:../../%=%)" + @$(AS) -c $(CFLAGS) $< -o $@ + +$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile + @echo "LD $(<:../../%=%)" + @$(CC) $(OBJECTS) $(LDFLAGS) -o $@ + @echo "SZ $(<:../../%=%)" + @$(SZ) $@ + +#added +$(BUILD_DIR)/$(TARGET).o: $(OBJECTS) Makefile + @echo "LD $(<:../../%=%)" + @$(CC) $(OBJECTS) $(LDFLAGS) -o $@ + @echo "SZ $(<:../../%=%)" + @$(SZ) $@ +#end add + +$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) + @echo "HEX $(<:../../%=%)" + @$(HEX) $< $@ + +$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) + @echo "BIN $(<:../../%=%)" + @$(BIN) $< $@ + +$(BUILD_DIR): + mkdir $@ + +####################################### +# clean up +####################################### +clean: + -rm -fR $(BUILD_DIR) + +####################################### +# flash +####################################### +flash: + $(SF) write $(BUILD_DIR)/$(TARGET).bin 0x8000000 + +####################################### +# dependencies +####################################### +-include $(wildcard $(BUILD_DIR)/*.d) + +# *** EOF *** From 94506097a18fdf0eebb8a4033e3a83a77d4b57e9 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 30 Dec 2023 19:48:03 -0600 Subject: [PATCH 02/57] Messing with makefiles and new unit testing structure; testing the addition of fff using Contactors; added Unity files. --- Drivers/Inc/Contactors.h | 13 +- Makefile | 5 + Tests/UnitTests/HelloWorld.c | 14 +- Tests/UnitTests/Makefile | 13 +- Tests/UnitTests/Test_Contactors.c | 0 Tests/UnitTests/Unity/unity.c | 2487 +++++++++++++++++++++++ Tests/UnitTests/Unity/unity.h | 697 +++++++ Tests/UnitTests/Unity/unity_internals.h | 1169 +++++++++++ 8 files changed, 4393 insertions(+), 5 deletions(-) create mode 100644 Tests/UnitTests/Test_Contactors.c create mode 100644 Tests/UnitTests/Unity/unity.c create mode 100644 Tests/UnitTests/Unity/unity.h create mode 100644 Tests/UnitTests/Unity/unity_internals.h diff --git a/Drivers/Inc/Contactors.h b/Drivers/Inc/Contactors.h index 77cf7ec15..f7b6efbad 100644 --- a/Drivers/Inc/Contactors.h +++ b/Drivers/Inc/Contactors.h @@ -12,9 +12,13 @@ #define __CONTACTORS_H #include "common.h" +#ifdef MOCK_CONTACTORS ///////////////////////////////// +#include "fff.h" +#else #include "config.h" #include "BSP_GPIO.h" #include "stm32f4xx_gpio.h" +#endif #define CONTACTORS_PORT PORTC @@ -31,7 +35,12 @@ typedef enum contactor_ENUM { }contactor_t; - +#ifdef MOCK_CONTACTORS +DEFINE_FFF_GLOBALS; +FAKE_VOID_FUNC(Contactors_Init); +FAKE_VALUE_FUNC(bool, Contactors_Get, contactor_t); +FAKE_VALUE_FUNC(bool, Contactors_Set, contactor_t, bool, bool); +#else /** * @brief Initializes contactors to be used * in connection with the Motor and Array @@ -56,7 +65,7 @@ bool Contactors_Get(contactor_t contactor); * @return Whether or not the contactor was successfully set */ ErrorStatus Contactors_Set(contactor_t contactor, bool state, bool blocking); - +#endif #endif diff --git a/Makefile b/Makefile index afea3bbe3..cd75d056c 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,11 @@ leader: $(MAKE) -C BSP -C STM32F413 -j TARGET=$(LEADER) TEST=$(TEST_LEADER) @echo "${BLUE}Compiled for leader! Jolly Good!${NC}" +unittest: + @echo "${YELLOW}Compiling unit test...${NC}" + $(MAKE) -C Tests -C UnitTests -j TARGET=$(LEADER) TEST=$(TEST_LEADER) + @echo "${BLUE}Compiled unit test! Jolly Good!${NC}" + flash: $(MAKE) -C BSP -C STM32F413 flash diff --git a/Tests/UnitTests/HelloWorld.c b/Tests/UnitTests/HelloWorld.c index 4668ec1fa..db8170042 100644 --- a/Tests/UnitTests/HelloWorld.c +++ b/Tests/UnitTests/HelloWorld.c @@ -1,5 +1,17 @@ #include +#include "fff.h" +#define MOCK_CONTACTORS +#include "Contactors.h" int main(void) { - printf("\n\rHello world\n\r"); + printf("\rHello world\n\r"); + Contactors_Init(); + printf("\n\rHello world?\n\r"); + bool x = Contactors_Get(ARRAY_PRECHARGE_BYPASS_CONTACTOR); + printf("\n\rHello world!\n\r"); + Contactors_Set(ARRAY_PRECHARGE_BYPASS_CONTACTOR, false, true); + printf("\n\rHello world...\n\r"); + + printf("\n\rCall argument for set: %d\n\r", Contactors_Set_fake.arg1_history[0]); + printf("\n\rHello world~\n\r"); } \ No newline at end of file diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index dee07f003..32a5d4c5b 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -51,6 +51,15 @@ SF = st-flash # AS includes #AS_INCLUDES = #co +C_INCLUDES := \ +-I../../Apps/Inc \ +-I../../Drivers/Inc \ +-I../../Config/Inc \ +-I../../BSP/Inc \ +-I../../Tests/Inc/ \ +-I../../Tests/UnitTests \ +-IInc + ifeq ($(DEBUG), 1) CFLAGS += -g3 -gdwarf-2 -DDEBUG endif @@ -79,9 +88,9 @@ TOCOMPILE := $(TEST_LEADER) ## # @$(CC) $(OBJECTS) -o $@ #added -$(BUILD_DIR)/$(TARGET).o: $(BUILD_DIR) +$(BUILD_DIR)/$(TARGET).o: $(BUILD_DIR) $(TOCOMPILE).c @echo "LD $(<:../../%=%)" - @$(CC) $(TOCOMPILE).c -o $(BUILD_DIR)/$(TOCOMPILE).o + @$(CC) $(C_INCLUDES) $(TOCOMPILE).c -o $(BUILD_DIR)/$(TOCOMPILE).o @echo "SZ $(<:../../%=%)" #end add ^^ use to be @$(SZ) $@ diff --git a/Tests/UnitTests/Test_Contactors.c b/Tests/UnitTests/Test_Contactors.c new file mode 100644 index 000000000..e69de29bb diff --git a/Tests/UnitTests/Unity/unity.c b/Tests/UnitTests/Unity/unity.c new file mode 100644 index 000000000..14b558ebc --- /dev/null +++ b/Tests/UnitTests/Unity/unity.c @@ -0,0 +1,2487 @@ +/* ========================================================================= + Unity Project - A Test Framework for C + Copyright (c) 2007-21 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +============================================================================ */ + +#include "unity.h" + +#ifndef UNITY_PROGMEM +#define UNITY_PROGMEM +#endif + +/* If omitted from header, declare overrideable prototypes here so they're ready for use */ +#ifdef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION +void UNITY_OUTPUT_CHAR(int); +#endif + +/* Helpful macros for us to use here in Assert functions */ +#define UNITY_FAIL_AND_BAIL do { Unity.CurrentTestFailed = 1; UNITY_OUTPUT_FLUSH(); TEST_ABORT(); } while (0) +#define UNITY_IGNORE_AND_BAIL do { Unity.CurrentTestIgnored = 1; UNITY_OUTPUT_FLUSH(); TEST_ABORT(); } while (0) +#define RETURN_IF_FAIL_OR_IGNORE do { if (Unity.CurrentTestFailed || Unity.CurrentTestIgnored) { TEST_ABORT(); } } while (0) + +struct UNITY_STORAGE_T Unity; + +#ifdef UNITY_OUTPUT_COLOR +const char UNITY_PROGMEM UnityStrOk[] = "\033[42mOK\033[0m"; +const char UNITY_PROGMEM UnityStrPass[] = "\033[42mPASS\033[0m"; +const char UNITY_PROGMEM UnityStrFail[] = "\033[41mFAIL\033[0m"; +const char UNITY_PROGMEM UnityStrIgnore[] = "\033[43mIGNORE\033[0m"; +#else +const char UNITY_PROGMEM UnityStrOk[] = "OK"; +const char UNITY_PROGMEM UnityStrPass[] = "PASS"; +const char UNITY_PROGMEM UnityStrFail[] = "FAIL"; +const char UNITY_PROGMEM UnityStrIgnore[] = "IGNORE"; +#endif +static const char UNITY_PROGMEM UnityStrNull[] = "NULL"; +static const char UNITY_PROGMEM UnityStrSpacer[] = ". "; +static const char UNITY_PROGMEM UnityStrExpected[] = " Expected "; +static const char UNITY_PROGMEM UnityStrWas[] = " Was "; +static const char UNITY_PROGMEM UnityStrGt[] = " to be greater than "; +static const char UNITY_PROGMEM UnityStrLt[] = " to be less than "; +static const char UNITY_PROGMEM UnityStrOrEqual[] = "or equal to "; +static const char UNITY_PROGMEM UnityStrNotEqual[] = " to be not equal to "; +static const char UNITY_PROGMEM UnityStrElement[] = " Element "; +static const char UNITY_PROGMEM UnityStrByte[] = " Byte "; +static const char UNITY_PROGMEM UnityStrMemory[] = " Memory Mismatch."; +static const char UNITY_PROGMEM UnityStrDelta[] = " Values Not Within Delta "; +static const char UNITY_PROGMEM UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless."; +static const char UNITY_PROGMEM UnityStrNullPointerForExpected[] = " Expected pointer to be NULL"; +static const char UNITY_PROGMEM UnityStrNullPointerForActual[] = " Actual pointer was NULL"; +#ifndef UNITY_EXCLUDE_FLOAT +static const char UNITY_PROGMEM UnityStrNot[] = "Not "; +static const char UNITY_PROGMEM UnityStrInf[] = "Infinity"; +static const char UNITY_PROGMEM UnityStrNegInf[] = "Negative Infinity"; +static const char UNITY_PROGMEM UnityStrNaN[] = "NaN"; +static const char UNITY_PROGMEM UnityStrDet[] = "Determinate"; +static const char UNITY_PROGMEM UnityStrInvalidFloatTrait[] = "Invalid Float Trait"; +#endif +const char UNITY_PROGMEM UnityStrErrShorthand[] = "Unity Shorthand Support Disabled"; +const char UNITY_PROGMEM UnityStrErrFloat[] = "Unity Floating Point Disabled"; +const char UNITY_PROGMEM UnityStrErrDouble[] = "Unity Double Precision Disabled"; +const char UNITY_PROGMEM UnityStrErr64[] = "Unity 64-bit Support Disabled"; +static const char UNITY_PROGMEM UnityStrBreaker[] = "-----------------------"; +static const char UNITY_PROGMEM UnityStrResultsTests[] = " Tests "; +static const char UNITY_PROGMEM UnityStrResultsFailures[] = " Failures "; +static const char UNITY_PROGMEM UnityStrResultsIgnored[] = " Ignored "; +#ifndef UNITY_EXCLUDE_DETAILS +static const char UNITY_PROGMEM UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " "; +static const char UNITY_PROGMEM UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " "; +#endif +/*----------------------------------------------- + * Pretty Printers & Test Result Output Handlers + *-----------------------------------------------*/ + +/*-----------------------------------------------*/ +/* Local helper function to print characters. */ +static void UnityPrintChar(const char* pch) +{ + /* printable characters plus CR & LF are printed */ + if ((*pch <= 126) && (*pch >= 32)) + { + UNITY_OUTPUT_CHAR(*pch); + } + /* write escaped carriage returns */ + else if (*pch == 13) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('r'); + } + /* write escaped line feeds */ + else if (*pch == 10) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('n'); + } + /* unprintable characters are shown as codes */ + else + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)*pch, 2); + } +} + +/*-----------------------------------------------*/ +/* Local helper function to print ANSI escape strings e.g. "\033[42m". */ +#ifdef UNITY_OUTPUT_COLOR +static UNITY_UINT UnityPrintAnsiEscapeString(const char* string) +{ + const char* pch = string; + UNITY_UINT count = 0; + + while (*pch && (*pch != 'm')) + { + UNITY_OUTPUT_CHAR(*pch); + pch++; + count++; + } + UNITY_OUTPUT_CHAR('m'); + count++; + + return count; +} +#endif + +/*-----------------------------------------------*/ +void UnityPrint(const char* string) +{ + const char* pch = string; + + if (pch != NULL) + { + while (*pch) + { +#ifdef UNITY_OUTPUT_COLOR + /* print ANSI escape code */ + if ((*pch == 27) && (*(pch + 1) == '[')) + { + pch += UnityPrintAnsiEscapeString(pch); + continue; + } +#endif + UnityPrintChar(pch); + pch++; + } + } +} +/*-----------------------------------------------*/ +void UnityPrintLen(const char* string, const UNITY_UINT32 length) +{ + const char* pch = string; + + if (pch != NULL) + { + while (*pch && ((UNITY_UINT32)(pch - string) < length)) + { + /* printable characters plus CR & LF are printed */ + if ((*pch <= 126) && (*pch >= 32)) + { + UNITY_OUTPUT_CHAR(*pch); + } + /* write escaped carriage returns */ + else if (*pch == 13) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('r'); + } + /* write escaped line feeds */ + else if (*pch == 10) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('n'); + } + /* unprintable characters are shown as codes */ + else + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)*pch, 2); + } + pch++; + } + } +} + +/*-----------------------------------------------*/ +void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style) +{ + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + if (style == UNITY_DISPLAY_STYLE_CHAR) + { + /* printable characters plus CR & LF are printed */ + UNITY_OUTPUT_CHAR('\''); + if ((number <= 126) && (number >= 32)) + { + UNITY_OUTPUT_CHAR((int)number); + } + /* write escaped carriage returns */ + else if (number == 13) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('r'); + } + /* write escaped line feeds */ + else if (number == 10) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('n'); + } + /* unprintable characters are shown as codes */ + else + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)number, 2); + } + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrintNumber(number); + } + } + else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT) + { + UnityPrintNumberUnsigned((UNITY_UINT)number); + } + else + { + UNITY_OUTPUT_CHAR('0'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)number, (char)((style & 0xF) * 2)); + } +} + +/*-----------------------------------------------*/ +void UnityPrintNumber(const UNITY_INT number_to_print) +{ + UNITY_UINT number = (UNITY_UINT)number_to_print; + + if (number_to_print < 0) + { + /* A negative number, including MIN negative */ + UNITY_OUTPUT_CHAR('-'); + number = (~number) + 1; + } + UnityPrintNumberUnsigned(number); +} + +/*----------------------------------------------- + * basically do an itoa using as little ram as possible */ +void UnityPrintNumberUnsigned(const UNITY_UINT number) +{ + UNITY_UINT divisor = 1; + + /* figure out initial divisor */ + while (number / divisor > 9) + { + divisor *= 10; + } + + /* now mod and print, then divide divisor */ + do + { + UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); + divisor /= 10; + } while (divisor > 0); +} + +/*-----------------------------------------------*/ +void UnityPrintNumberHex(const UNITY_UINT number, const char nibbles_to_print) +{ + int nibble; + char nibbles = nibbles_to_print; + + if ((unsigned)nibbles > UNITY_MAX_NIBBLES) + { + nibbles = UNITY_MAX_NIBBLES; + } + + while (nibbles > 0) + { + nibbles--; + nibble = (int)(number >> (nibbles * 4)) & 0x0F; + if (nibble <= 9) + { + UNITY_OUTPUT_CHAR((char)('0' + nibble)); + } + else + { + UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble)); + } + } +} + +/*-----------------------------------------------*/ +void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number) +{ + UNITY_UINT current_bit = (UNITY_UINT)1 << (UNITY_INT_WIDTH - 1); + UNITY_INT32 i; + + for (i = 0; i < UNITY_INT_WIDTH; i++) + { + if (current_bit & mask) + { + if (current_bit & number) + { + UNITY_OUTPUT_CHAR('1'); + } + else + { + UNITY_OUTPUT_CHAR('0'); + } + } + else + { + UNITY_OUTPUT_CHAR('X'); + } + current_bit = current_bit >> 1; + } +} + +/*-----------------------------------------------*/ +#ifndef UNITY_EXCLUDE_FLOAT_PRINT +/* + * This function prints a floating-point value in a format similar to + * printf("%.7g") on a single-precision machine or printf("%.9g") on a + * double-precision machine. The 7th digit won't always be totally correct + * in single-precision operation (for that level of accuracy, a more + * complicated algorithm would be needed). + */ +void UnityPrintFloat(const UNITY_DOUBLE input_number) +{ +#ifdef UNITY_INCLUDE_DOUBLE + static const int sig_digits = 9; + static const UNITY_INT32 min_scaled = 100000000; + static const UNITY_INT32 max_scaled = 1000000000; +#else + static const int sig_digits = 7; + static const UNITY_INT32 min_scaled = 1000000; + static const UNITY_INT32 max_scaled = 10000000; +#endif + + UNITY_DOUBLE number = input_number; + + /* print minus sign (does not handle negative zero) */ + if (number < 0.0f) + { + UNITY_OUTPUT_CHAR('-'); + number = -number; + } + + /* handle zero, NaN, and +/- infinity */ + if (number == 0.0f) + { + UnityPrint("0"); + } + else if (UNITY_IS_NAN(number)) + { + UnityPrint("nan"); + } + else if (UNITY_IS_INF(number)) + { + UnityPrint("inf"); + } + else + { + UNITY_INT32 n_int = 0; + UNITY_INT32 n; + int exponent = 0; + int decimals; + int digits; + char buf[16] = {0}; + + /* + * Scale up or down by powers of 10. To minimize rounding error, + * start with a factor/divisor of 10^10, which is the largest + * power of 10 that can be represented exactly. Finally, compute + * (exactly) the remaining power of 10 and perform one more + * multiplication or division. + */ + if (number < 1.0f) + { + UNITY_DOUBLE factor = 1.0f; + + while (number < (UNITY_DOUBLE)max_scaled / 1e10f) { number *= 1e10f; exponent -= 10; } + while (number * factor < (UNITY_DOUBLE)min_scaled) { factor *= 10.0f; exponent--; } + + number *= factor; + } + else if (number > (UNITY_DOUBLE)max_scaled) + { + UNITY_DOUBLE divisor = 1.0f; + + while (number > (UNITY_DOUBLE)min_scaled * 1e10f) { number /= 1e10f; exponent += 10; } + while (number / divisor > (UNITY_DOUBLE)max_scaled) { divisor *= 10.0f; exponent++; } + + number /= divisor; + } + else + { + /* + * In this range, we can split off the integer part before + * doing any multiplications. This reduces rounding error by + * freeing up significant bits in the fractional part. + */ + UNITY_DOUBLE factor = 1.0f; + n_int = (UNITY_INT32)number; + number -= (UNITY_DOUBLE)n_int; + + while (n_int < min_scaled) { n_int *= 10; factor *= 10.0f; exponent--; } + + number *= factor; + } + + /* round to nearest integer */ + n = ((UNITY_INT32)(number + number) + 1) / 2; + +#ifndef UNITY_ROUND_TIES_AWAY_FROM_ZERO + /* round to even if exactly between two integers */ + if ((n & 1) && (((UNITY_DOUBLE)n - number) == 0.5f)) + n--; +#endif + + n += n_int; + + if (n >= max_scaled) + { + n = min_scaled; + exponent++; + } + + /* determine where to place decimal point */ + decimals = ((exponent <= 0) && (exponent >= -(sig_digits + 3))) ? (-exponent) : (sig_digits - 1); + exponent += decimals; + + /* truncate trailing zeroes after decimal point */ + while ((decimals > 0) && ((n % 10) == 0)) + { + n /= 10; + decimals--; + } + + /* build up buffer in reverse order */ + digits = 0; + while ((n != 0) || (digits <= decimals)) + { + buf[digits++] = (char)('0' + n % 10); + n /= 10; + } + + /* print out buffer (backwards) */ + while (digits > 0) + { + if (digits == decimals) + { + UNITY_OUTPUT_CHAR('.'); + } + UNITY_OUTPUT_CHAR(buf[--digits]); + } + + /* print exponent if needed */ + if (exponent != 0) + { + UNITY_OUTPUT_CHAR('e'); + + if (exponent < 0) + { + UNITY_OUTPUT_CHAR('-'); + exponent = -exponent; + } + else + { + UNITY_OUTPUT_CHAR('+'); + } + + digits = 0; + while ((exponent != 0) || (digits < 2)) + { + buf[digits++] = (char)('0' + exponent % 10); + exponent /= 10; + } + while (digits > 0) + { + UNITY_OUTPUT_CHAR(buf[--digits]); + } + } + } +} +#endif /* ! UNITY_EXCLUDE_FLOAT_PRINT */ + +/*-----------------------------------------------*/ +static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line) +{ +#ifdef UNITY_OUTPUT_FOR_ECLIPSE + UNITY_OUTPUT_CHAR('('); + UnityPrint(file); + UNITY_OUTPUT_CHAR(':'); + UnityPrintNumber((UNITY_INT)line); + UNITY_OUTPUT_CHAR(')'); + UNITY_OUTPUT_CHAR(' '); + UnityPrint(Unity.CurrentTestName); + UNITY_OUTPUT_CHAR(':'); +#else +#ifdef UNITY_OUTPUT_FOR_IAR_WORKBENCH + UnityPrint("'); + UnityPrint(Unity.CurrentTestName); + UnityPrint(" "); +#else +#ifdef UNITY_OUTPUT_FOR_QT_CREATOR + UnityPrint("file://"); + UnityPrint(file); + UNITY_OUTPUT_CHAR(':'); + UnityPrintNumber((UNITY_INT)line); + UNITY_OUTPUT_CHAR(' '); + UnityPrint(Unity.CurrentTestName); + UNITY_OUTPUT_CHAR(':'); +#else + UnityPrint(file); + UNITY_OUTPUT_CHAR(':'); + UnityPrintNumber((UNITY_INT)line); + UNITY_OUTPUT_CHAR(':'); + UnityPrint(Unity.CurrentTestName); + UNITY_OUTPUT_CHAR(':'); +#endif +#endif +#endif +} + +/*-----------------------------------------------*/ +static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line) +{ + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrint(UnityStrFail); + UNITY_OUTPUT_CHAR(':'); +} + +/*-----------------------------------------------*/ +void UnityConcludeTest(void) +{ + if (Unity.CurrentTestIgnored) + { + Unity.TestIgnores++; + } + else if (!Unity.CurrentTestFailed) + { + UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber); + UnityPrint(UnityStrPass); + } + else + { + Unity.TestFailures++; + } + + Unity.CurrentTestFailed = 0; + Unity.CurrentTestIgnored = 0; + UNITY_PRINT_EXEC_TIME(); + UNITY_PRINT_EOL(); + UNITY_FLUSH_CALL(); +} + +/*-----------------------------------------------*/ +static void UnityAddMsgIfSpecified(const char* msg) +{ +#ifdef UNITY_PRINT_TEST_CONTEXT + UnityPrint(UnityStrSpacer); + UNITY_PRINT_TEST_CONTEXT(); +#endif +#ifndef UNITY_EXCLUDE_DETAILS + if (Unity.CurrentDetail1) + { + UnityPrint(UnityStrSpacer); + UnityPrint(UnityStrDetail1Name); + UnityPrint(Unity.CurrentDetail1); + if (Unity.CurrentDetail2) + { + UnityPrint(UnityStrDetail2Name); + UnityPrint(Unity.CurrentDetail2); + } + } +#endif + if (msg) + { + UnityPrint(UnityStrSpacer); + UnityPrint(msg); + } +} + +/*-----------------------------------------------*/ +static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual) +{ + UnityPrint(UnityStrExpected); + if (expected != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrint(expected); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } + UnityPrint(UnityStrWas); + if (actual != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrint(actual); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } +} + +/*-----------------------------------------------*/ +static void UnityPrintExpectedAndActualStringsLen(const char* expected, + const char* actual, + const UNITY_UINT32 length) +{ + UnityPrint(UnityStrExpected); + if (expected != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrintLen(expected, length); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } + UnityPrint(UnityStrWas); + if (actual != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrintLen(actual, length); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } +} + +/*----------------------------------------------- + * Assertion & Control Helpers + *-----------------------------------------------*/ + +/*-----------------------------------------------*/ +static int UnityIsOneArrayNull(UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_LINE_TYPE lineNumber, + const char* msg) +{ + /* Both are NULL or same pointer */ + if (expected == actual) { return 0; } + + /* print and return true if just expected is NULL */ + if (expected == NULL) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrNullPointerForExpected); + UnityAddMsgIfSpecified(msg); + return 1; + } + + /* print and return true if just actual is NULL */ + if (actual == NULL) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrNullPointerForActual); + UnityAddMsgIfSpecified(msg); + return 1; + } + + return 0; /* return false if neither is NULL */ +} + +/*----------------------------------------------- + * Assertion Functions + *-----------------------------------------------*/ + +/*-----------------------------------------------*/ +void UnityAssertBits(const UNITY_INT mask, + const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + RETURN_IF_FAIL_OR_IGNORE; + + if ((mask & expected) != (mask & actual)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)expected); + UnityPrint(UnityStrWas); + UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertEqualNumber(const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + RETURN_IF_FAIL_OR_IGNORE; + + if (expected != actual) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expected, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold, + const UNITY_INT actual, + const UNITY_COMPARISON_T compare, + const char *msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + int failed = 0; + RETURN_IF_FAIL_OR_IGNORE; + + if ((threshold == actual) && (compare & UNITY_EQUAL_TO)) { return; } + if ((threshold == actual)) { failed = 1; } + + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + if ((actual > threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; } + if ((actual < threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; } + } + else /* UINT or HEX */ + { + if (((UNITY_UINT)actual > (UNITY_UINT)threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; } + if (((UNITY_UINT)actual < (UNITY_UINT)threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; } + } + + if (failed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(actual, style); + if (compare & UNITY_GREATER_THAN) { UnityPrint(UnityStrGt); } + if (compare & UNITY_SMALLER_THAN) { UnityPrint(UnityStrLt); } + if (compare & UNITY_EQUAL_TO) { UnityPrint(UnityStrOrEqual); } + if (compare == UNITY_NOT_EQUAL) { UnityPrint(UnityStrNotEqual); } + UnityPrintNumberByStyle(threshold, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +#define UnityPrintPointlessAndBail() \ +do { \ + UnityTestResultsFailBegin(lineNumber); \ + UnityPrint(UnityStrPointless); \ + UnityAddMsgIfSpecified(msg); \ + UNITY_FAIL_AND_BAIL; \ +} while (0) + +/*-----------------------------------------------*/ +void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style, + const UNITY_FLAGS_T flags) +{ + UNITY_UINT32 elements = num_elements; + unsigned int length = style & 0xF; + unsigned int increment = 0; + + RETURN_IF_FAIL_OR_IGNORE; + + if (num_elements == 0) + { +#ifdef UNITY_COMPARE_PTRS_ON_ZERO_ARRAY + UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, lineNumber, msg); +#else + UnityPrintPointlessAndBail(); +#endif + } + + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } + + if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) + { + UNITY_FAIL_AND_BAIL; + } + + while ((elements > 0) && (elements--)) + { + UNITY_INT expect_val; + UNITY_INT actual_val; + + switch (length) + { + case 1: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual; + if (style & (UNITY_DISPLAY_RANGE_UINT | UNITY_DISPLAY_RANGE_HEX)) + { + expect_val &= 0x000000FF; + actual_val &= 0x000000FF; + } + increment = sizeof(UNITY_INT8); + break; + + case 2: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual; + if (style & (UNITY_DISPLAY_RANGE_UINT | UNITY_DISPLAY_RANGE_HEX)) + { + expect_val &= 0x0000FFFF; + actual_val &= 0x0000FFFF; + } + increment = sizeof(UNITY_INT16); + break; + +#ifdef UNITY_SUPPORT_64 + case 8: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual; + increment = sizeof(UNITY_INT64); + break; +#endif + + default: /* default is length 4 bytes */ + case 4: + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual; +#ifdef UNITY_SUPPORT_64 + if (style & (UNITY_DISPLAY_RANGE_UINT | UNITY_DISPLAY_RANGE_HEX)) + { + expect_val &= 0x00000000FFFFFFFF; + actual_val &= 0x00000000FFFFFFFF; + } +#endif + increment = sizeof(UNITY_INT32); + length = 4; + break; + } + + if (expect_val != actual_val) + { + if ((style & UNITY_DISPLAY_RANGE_UINT) && (length < (UNITY_INT_WIDTH / 8))) + { /* For UINT, remove sign extension (padding 1's) from signed type casts above */ + UNITY_INT mask = 1; + mask = (mask << 8 * length) - 1; + expect_val &= mask; + actual_val &= mask; + } + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expect_val, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual_val, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + /* Walk through array by incrementing the pointers */ + if (flags == UNITY_ARRAY_TO_ARRAY) + { + expected = (UNITY_INTERNAL_PTR)((const char*)expected + increment); + } + actual = (UNITY_INTERNAL_PTR)((const char*)actual + increment); + } +} + +/*-----------------------------------------------*/ +#ifndef UNITY_EXCLUDE_FLOAT +/* Wrap this define in a function with variable types as float or double */ +#define UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff) \ + if (UNITY_IS_INF(expected) && UNITY_IS_INF(actual) && (((expected) < 0) == ((actual) < 0))) return 1; \ + if (UNITY_NAN_CHECK) return 1; \ + (diff) = (actual) - (expected); \ + if ((diff) < 0) (diff) = -(diff); \ + if ((delta) < 0) (delta) = -(delta); \ + return !(UNITY_IS_NAN(diff) || UNITY_IS_INF(diff) || ((diff) > (delta))) + /* This first part of this condition will catch any NaN or Infinite values */ +#ifndef UNITY_NAN_NOT_EQUAL_NAN + #define UNITY_NAN_CHECK UNITY_IS_NAN(expected) && UNITY_IS_NAN(actual) +#else + #define UNITY_NAN_CHECK 0 +#endif + +#ifndef UNITY_EXCLUDE_FLOAT_PRINT + #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \ + do { \ + UnityPrint(UnityStrExpected); \ + UnityPrintFloat(expected); \ + UnityPrint(UnityStrWas); \ + UnityPrintFloat(actual); \ + } while (0) +#else + #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \ + UnityPrint(UnityStrDelta) +#endif /* UNITY_EXCLUDE_FLOAT_PRINT */ + +/*-----------------------------------------------*/ +static int UnityFloatsWithin(UNITY_FLOAT delta, UNITY_FLOAT expected, UNITY_FLOAT actual) +{ + UNITY_FLOAT diff; + UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); +} + +/*-----------------------------------------------*/ +void UnityAssertWithinFloatArray(const UNITY_FLOAT delta, + UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected, + UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags) +{ + UNITY_UINT32 elements = num_elements; + UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_expected = expected; + UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_actual = actual; + UNITY_FLOAT in_delta = delta; + UNITY_FLOAT current_element_delta = delta; + + RETURN_IF_FAIL_OR_IGNORE; + + if (elements == 0) + { +#ifdef UNITY_COMPARE_PTRS_ON_ZERO_ARRAY + UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, lineNumber, msg); +#else + UnityPrintPointlessAndBail(); +#endif + } + + if (UNITY_IS_INF(in_delta)) + { + return; /* Arrays will be force equal with infinite delta */ + } + + if (UNITY_IS_NAN(in_delta)) + { + /* Delta must be correct number */ + UnityPrintPointlessAndBail(); + } + + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } + + if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) + { + UNITY_FAIL_AND_BAIL; + } + + /* fix delta sign if need */ + if (in_delta < 0) + { + in_delta = -in_delta; + } + + while (elements--) + { + current_element_delta = *ptr_expected * UNITY_FLOAT_PRECISION; + + if (current_element_delta < 0) + { + /* fix delta sign for correct calculations */ + current_element_delta = -current_element_delta; + } + + if (!UnityFloatsWithin(in_delta + current_element_delta, *ptr_expected, *ptr_actual)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)*ptr_expected, (UNITY_DOUBLE)*ptr_actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + if (flags == UNITY_ARRAY_TO_ARRAY) + { + ptr_expected++; + } + ptr_actual++; + } +} + +/*-----------------------------------------------*/ +void UnityAssertFloatsWithin(const UNITY_FLOAT delta, + const UNITY_FLOAT expected, + const UNITY_FLOAT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + RETURN_IF_FAIL_OR_IGNORE; + + + if (!UnityFloatsWithin(delta, expected, actual)) + { + UnityTestResultsFailBegin(lineNumber); + UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)expected, (UNITY_DOUBLE)actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertFloatsNotWithin(const UNITY_FLOAT delta, + const UNITY_FLOAT expected, + const UNITY_FLOAT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + RETURN_IF_FAIL_OR_IGNORE; + + if (UnityFloatsWithin(delta, expected, actual)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintFloat((UNITY_DOUBLE)expected); + UnityPrint(UnityStrNotEqual); + UnityPrintFloat((UNITY_DOUBLE)actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertGreaterOrLessFloat(const UNITY_FLOAT threshold, + const UNITY_FLOAT actual, + const UNITY_COMPARISON_T compare, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + int failed; + + RETURN_IF_FAIL_OR_IGNORE; + + failed = 0; + + /* Checking for "not success" rather than failure to get the right result for NaN */ + if (!(actual < threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; } + if (!(actual > threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; } + + if ((compare & UNITY_EQUAL_TO) && UnityFloatsWithin(threshold * UNITY_FLOAT_PRECISION, threshold, actual)) { failed = 0; } + + if (failed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintFloat(actual); + if (compare & UNITY_GREATER_THAN) { UnityPrint(UnityStrGt); } + if (compare & UNITY_SMALLER_THAN) { UnityPrint(UnityStrLt); } + if (compare & UNITY_EQUAL_TO) { UnityPrint(UnityStrOrEqual); } + UnityPrintFloat(threshold); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertFloatSpecial(const UNITY_FLOAT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style) +{ + const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet}; + UNITY_INT should_be_trait = ((UNITY_INT)style & 1); + UNITY_INT is_trait = !should_be_trait; + UNITY_INT trait_index = (UNITY_INT)(style >> 1); + + RETURN_IF_FAIL_OR_IGNORE; + + switch (style) + { + case UNITY_FLOAT_IS_INF: + case UNITY_FLOAT_IS_NOT_INF: + is_trait = UNITY_IS_INF(actual) && (actual > 0); + break; + case UNITY_FLOAT_IS_NEG_INF: + case UNITY_FLOAT_IS_NOT_NEG_INF: + is_trait = UNITY_IS_INF(actual) && (actual < 0); + break; + + case UNITY_FLOAT_IS_NAN: + case UNITY_FLOAT_IS_NOT_NAN: + is_trait = UNITY_IS_NAN(actual) ? 1 : 0; + break; + + case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */ + case UNITY_FLOAT_IS_NOT_DET: + is_trait = !UNITY_IS_INF(actual) && !UNITY_IS_NAN(actual); + break; + + case UNITY_FLOAT_INVALID_TRAIT: /* Supress warning */ + default: /* including UNITY_FLOAT_INVALID_TRAIT */ + trait_index = 0; + trait_names[0] = UnityStrInvalidFloatTrait; + break; + } + + if (is_trait != should_be_trait) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + if (!should_be_trait) + { + UnityPrint(UnityStrNot); + } + UnityPrint(trait_names[trait_index]); + UnityPrint(UnityStrWas); +#ifndef UNITY_EXCLUDE_FLOAT_PRINT + UnityPrintFloat((UNITY_DOUBLE)actual); +#else + if (should_be_trait) + { + UnityPrint(UnityStrNot); + } + UnityPrint(trait_names[trait_index]); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +#endif /* not UNITY_EXCLUDE_FLOAT */ + +/*-----------------------------------------------*/ +#ifndef UNITY_EXCLUDE_DOUBLE +static int UnityDoublesWithin(UNITY_DOUBLE delta, UNITY_DOUBLE expected, UNITY_DOUBLE actual) +{ + UNITY_DOUBLE diff; + UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); +} + +/*-----------------------------------------------*/ +void UnityAssertWithinDoubleArray(const UNITY_DOUBLE delta, + UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expected, + UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags) +{ + UNITY_UINT32 elements = num_elements; + UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_expected = expected; + UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_actual = actual; + UNITY_DOUBLE in_delta = delta; + UNITY_DOUBLE current_element_delta = delta; + + RETURN_IF_FAIL_OR_IGNORE; + + if (elements == 0) + { +#ifdef UNITY_COMPARE_PTRS_ON_ZERO_ARRAY + UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, lineNumber, msg); +#else + UnityPrintPointlessAndBail(); +#endif + } + + if (UNITY_IS_INF(in_delta)) + { + return; /* Arrays will be force equal with infinite delta */ + } + + if (UNITY_IS_NAN(in_delta)) + { + /* Delta must be correct number */ + UnityPrintPointlessAndBail(); + } + + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } + + if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) + { + UNITY_FAIL_AND_BAIL; + } + + /* fix delta sign if need */ + if (in_delta < 0) + { + in_delta = -in_delta; + } + + while (elements--) + { + current_element_delta = *ptr_expected * UNITY_DOUBLE_PRECISION; + + if (current_element_delta < 0) + { + /* fix delta sign for correct calculations */ + current_element_delta = -current_element_delta; + } + + if (!UnityDoublesWithin(in_delta + current_element_delta, *ptr_expected, *ptr_actual)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(*ptr_expected, *ptr_actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + if (flags == UNITY_ARRAY_TO_ARRAY) + { + ptr_expected++; + } + ptr_actual++; + } +} + +/*-----------------------------------------------*/ +void UnityAssertDoublesWithin(const UNITY_DOUBLE delta, + const UNITY_DOUBLE expected, + const UNITY_DOUBLE actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + RETURN_IF_FAIL_OR_IGNORE; + + if (!UnityDoublesWithin(delta, expected, actual)) + { + UnityTestResultsFailBegin(lineNumber); + UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertDoublesNotWithin(const UNITY_DOUBLE delta, + const UNITY_DOUBLE expected, + const UNITY_DOUBLE actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + RETURN_IF_FAIL_OR_IGNORE; + + if (UnityDoublesWithin(delta, expected, actual)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintFloat((UNITY_DOUBLE)expected); + UnityPrint(UnityStrNotEqual); + UnityPrintFloat((UNITY_DOUBLE)actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertGreaterOrLessDouble(const UNITY_DOUBLE threshold, + const UNITY_DOUBLE actual, + const UNITY_COMPARISON_T compare, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + int failed; + + RETURN_IF_FAIL_OR_IGNORE; + + failed = 0; + + /* Checking for "not success" rather than failure to get the right result for NaN */ + if (!(actual < threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; } + if (!(actual > threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; } + + if ((compare & UNITY_EQUAL_TO) && UnityDoublesWithin(threshold * UNITY_DOUBLE_PRECISION, threshold, actual)) { failed = 0; } + + if (failed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintFloat(actual); + if (compare & UNITY_GREATER_THAN) { UnityPrint(UnityStrGt); } + if (compare & UNITY_SMALLER_THAN) { UnityPrint(UnityStrLt); } + if (compare & UNITY_EQUAL_TO) { UnityPrint(UnityStrOrEqual); } + UnityPrintFloat(threshold); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style) +{ + const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet}; + UNITY_INT should_be_trait = ((UNITY_INT)style & 1); + UNITY_INT is_trait = !should_be_trait; + UNITY_INT trait_index = (UNITY_INT)(style >> 1); + + RETURN_IF_FAIL_OR_IGNORE; + + switch (style) + { + case UNITY_FLOAT_IS_INF: + case UNITY_FLOAT_IS_NOT_INF: + is_trait = UNITY_IS_INF(actual) && (actual > 0); + break; + case UNITY_FLOAT_IS_NEG_INF: + case UNITY_FLOAT_IS_NOT_NEG_INF: + is_trait = UNITY_IS_INF(actual) && (actual < 0); + break; + + case UNITY_FLOAT_IS_NAN: + case UNITY_FLOAT_IS_NOT_NAN: + is_trait = UNITY_IS_NAN(actual) ? 1 : 0; + break; + + case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */ + case UNITY_FLOAT_IS_NOT_DET: + is_trait = !UNITY_IS_INF(actual) && !UNITY_IS_NAN(actual); + break; + + case UNITY_FLOAT_INVALID_TRAIT: /* Supress warning */ + default: /* including UNITY_FLOAT_INVALID_TRAIT */ + trait_index = 0; + trait_names[0] = UnityStrInvalidFloatTrait; + break; + } + + if (is_trait != should_be_trait) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + if (!should_be_trait) + { + UnityPrint(UnityStrNot); + } + UnityPrint(trait_names[trait_index]); + UnityPrint(UnityStrWas); +#ifndef UNITY_EXCLUDE_FLOAT_PRINT + UnityPrintFloat(actual); +#else + if (should_be_trait) + { + UnityPrint(UnityStrNot); + } + UnityPrint(trait_names[trait_index]); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +#endif /* not UNITY_EXCLUDE_DOUBLE */ + +/*-----------------------------------------------*/ +void UnityAssertNumbersWithin(const UNITY_UINT delta, + const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + RETURN_IF_FAIL_OR_IGNORE; + + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + if (actual > expected) + { + Unity.CurrentTestFailed = (((UNITY_UINT)actual - (UNITY_UINT)expected) > delta); + } + else + { + Unity.CurrentTestFailed = (((UNITY_UINT)expected - (UNITY_UINT)actual) > delta); + } + } + else + { + if ((UNITY_UINT)actual > (UNITY_UINT)expected) + { + Unity.CurrentTestFailed = (((UNITY_UINT)actual - (UNITY_UINT)expected) > delta); + } + else + { + Unity.CurrentTestFailed = (((UNITY_UINT)expected - (UNITY_UINT)actual) > delta); + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrDelta); + UnityPrintNumberByStyle((UNITY_INT)delta, style); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expected, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertNumbersArrayWithin(const UNITY_UINT delta, + UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style, + const UNITY_FLAGS_T flags) +{ + UNITY_UINT32 elements = num_elements; + unsigned int length = style & 0xF; + unsigned int increment = 0; + + RETURN_IF_FAIL_OR_IGNORE; + + if (num_elements == 0) + { +#ifdef UNITY_COMPARE_PTRS_ON_ZERO_ARRAY + UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, lineNumber, msg); +#else + UnityPrintPointlessAndBail(); +#endif + } + + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } + + if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) + { + UNITY_FAIL_AND_BAIL; + } + + while ((elements > 0) && (elements--)) + { + UNITY_INT expect_val; + UNITY_INT actual_val; + + switch (length) + { + case 1: + /* fixing problems with signed overflow on unsigned numbers */ + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual; + increment = sizeof(UNITY_INT8); + } + else + { + expect_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT8*)expected; + actual_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT8*)actual; + increment = sizeof(UNITY_UINT8); + } + break; + + case 2: + /* fixing problems with signed overflow on unsigned numbers */ + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual; + increment = sizeof(UNITY_INT16); + } + else + { + expect_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT16*)expected; + actual_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT16*)actual; + increment = sizeof(UNITY_UINT16); + } + break; + +#ifdef UNITY_SUPPORT_64 + case 8: + /* fixing problems with signed overflow on unsigned numbers */ + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual; + increment = sizeof(UNITY_INT64); + } + else + { + expect_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT64*)expected; + actual_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT64*)actual; + increment = sizeof(UNITY_UINT64); + } + break; +#endif + + default: /* default is length 4 bytes */ + case 4: + /* fixing problems with signed overflow on unsigned numbers */ + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected; + actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual; + increment = sizeof(UNITY_INT32); + } + else + { + expect_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT32*)expected; + actual_val = (UNITY_INT)*(UNITY_PTR_ATTRIBUTE const UNITY_UINT32*)actual; + increment = sizeof(UNITY_UINT32); + } + length = 4; + break; + } + + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + if (actual_val > expect_val) + { + Unity.CurrentTestFailed = (((UNITY_UINT)actual_val - (UNITY_UINT)expect_val) > delta); + } + else + { + Unity.CurrentTestFailed = (((UNITY_UINT)expect_val - (UNITY_UINT)actual_val) > delta); + } + } + else + { + if ((UNITY_UINT)actual_val > (UNITY_UINT)expect_val) + { + Unity.CurrentTestFailed = (((UNITY_UINT)actual_val - (UNITY_UINT)expect_val) > delta); + } + else + { + Unity.CurrentTestFailed = (((UNITY_UINT)expect_val - (UNITY_UINT)actual_val) > delta); + } + } + + if (Unity.CurrentTestFailed) + { + if ((style & UNITY_DISPLAY_RANGE_UINT) && (length < (UNITY_INT_WIDTH / 8))) + { /* For UINT, remove sign extension (padding 1's) from signed type casts above */ + UNITY_INT mask = 1; + mask = (mask << 8 * length) - 1; + expect_val &= mask; + actual_val &= mask; + } + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrDelta); + UnityPrintNumberByStyle((UNITY_INT)delta, style); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expect_val, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual_val, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + /* Walk through array by incrementing the pointers */ + if (flags == UNITY_ARRAY_TO_ARRAY) + { + expected = (UNITY_INTERNAL_PTR)((const char*)expected + increment); + } + actual = (UNITY_INTERNAL_PTR)((const char*)actual + increment); + } +} + +/*-----------------------------------------------*/ +void UnityAssertEqualString(const char* expected, + const char* actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + UNITY_UINT32 i; + + RETURN_IF_FAIL_OR_IGNORE; + + /* if both pointers not null compare the strings */ + if (expected && actual) + { + for (i = 0; expected[i] || actual[i]; i++) + { + if (expected[i] != actual[i]) + { + Unity.CurrentTestFailed = 1; + break; + } + } + } + else + { /* fail if either null but not if both */ + if (expected || actual) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrintExpectedAndActualStrings(expected, actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertEqualStringLen(const char* expected, + const char* actual, + const UNITY_UINT32 length, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + UNITY_UINT32 i; + + RETURN_IF_FAIL_OR_IGNORE; + + /* if both pointers not null compare the strings */ + if (expected && actual) + { + for (i = 0; (i < length) && (expected[i] || actual[i]); i++) + { + if (expected[i] != actual[i]) + { + Unity.CurrentTestFailed = 1; + break; + } + } + } + else + { /* fail if either null but not if both */ + if (expected || actual) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrintExpectedAndActualStringsLen(expected, actual, length); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected, + const char** actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags) +{ + UNITY_UINT32 i = 0; + UNITY_UINT32 j = 0; + const char* expd = NULL; + const char* act = NULL; + + RETURN_IF_FAIL_OR_IGNORE; + + /* if no elements, it's an error */ + if (num_elements == 0) + { +#ifdef UNITY_COMPARE_PTRS_ON_ZERO_ARRAY + UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, lineNumber, msg); +#else + UnityPrintPointlessAndBail(); +#endif + } + + if ((const void*)expected == (const void*)actual) + { + return; /* Both are NULL or same pointer */ + } + + if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) + { + UNITY_FAIL_AND_BAIL; + } + + if (flags != UNITY_ARRAY_TO_ARRAY) + { + expd = (const char*)expected; + } + + do + { + act = actual[j]; + if (flags == UNITY_ARRAY_TO_ARRAY) + { + expd = ((const char* const*)expected)[j]; + } + + /* if both pointers not null compare the strings */ + if (expd && act) + { + for (i = 0; expd[i] || act[i]; i++) + { + if (expd[i] != act[i]) + { + Unity.CurrentTestFailed = 1; + break; + } + } + } + else + { /* handle case of one pointers being null (if both null, test should pass) */ + if (expd != act) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + if (num_elements > 1) + { + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(j); + } + UnityPrintExpectedAndActualStrings(expd, act); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + } while (++j < num_elements); +} + +/*-----------------------------------------------*/ +void UnityAssertEqualMemory(UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 length, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags) +{ + UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; + UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual; + UNITY_UINT32 elements = num_elements; + UNITY_UINT32 bytes; + + RETURN_IF_FAIL_OR_IGNORE; + + if (elements == 0) + { +#ifdef UNITY_COMPARE_PTRS_ON_ZERO_ARRAY + UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, lineNumber, msg); +#else + UnityPrintPointlessAndBail(); +#endif + } + if (length == 0) + { + UnityPrintPointlessAndBail(); + } + + if (expected == actual) + { + return; /* Both are NULL or same pointer */ + } + + if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) + { + UNITY_FAIL_AND_BAIL; + } + + while (elements--) + { + bytes = length; + while (bytes--) + { + if (*ptr_exp != *ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrMemory); + if (num_elements > 1) + { + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + } + UnityPrint(UnityStrByte); + UnityPrintNumberUnsigned(length - bytes - 1); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp++; + ptr_act++; + } + if (flags == UNITY_ARRAY_TO_VAL) + { + ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; + } + } +} + +/*-----------------------------------------------*/ + +static union +{ + UNITY_INT8 i8; + UNITY_INT16 i16; + UNITY_INT32 i32; +#ifdef UNITY_SUPPORT_64 + UNITY_INT64 i64; +#endif +#ifndef UNITY_EXCLUDE_FLOAT + float f; +#endif +#ifndef UNITY_EXCLUDE_DOUBLE + double d; +#endif +} UnityQuickCompare; + +UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size) +{ + switch(size) + { + case 1: + UnityQuickCompare.i8 = (UNITY_INT8)num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i8); + + case 2: + UnityQuickCompare.i16 = (UNITY_INT16)num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i16); + +#ifdef UNITY_SUPPORT_64 + case 8: + UnityQuickCompare.i64 = (UNITY_INT64)num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i64); +#endif + + default: /* 4 bytes */ + UnityQuickCompare.i32 = (UNITY_INT32)num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i32); + } +} + +#ifndef UNITY_EXCLUDE_FLOAT +/*-----------------------------------------------*/ +UNITY_INTERNAL_PTR UnityFloatToPtr(const float num) +{ + UnityQuickCompare.f = num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.f); +} +#endif + +#ifndef UNITY_EXCLUDE_DOUBLE +/*-----------------------------------------------*/ +UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num) +{ + UnityQuickCompare.d = num; + return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.d); +} +#endif + +#ifdef UNITY_INCLUDE_PRINT_FORMATTED + +/*----------------------------------------------- + * printf length modifier helpers + *-----------------------------------------------*/ + +enum UnityLengthModifier { + UNITY_LENGTH_MODIFIER_NONE, + UNITY_LENGTH_MODIFIER_LONG_LONG, + UNITY_LENGTH_MODIFIER_LONG, +}; + +#define UNITY_EXTRACT_ARG(NUMBER_T, NUMBER, LENGTH_MOD, VA, ARG_T) \ +do { \ + switch (LENGTH_MOD) \ + { \ + case UNITY_LENGTH_MODIFIER_LONG_LONG: \ + { \ + NUMBER = (NUMBER_T)va_arg(VA, long long ARG_T); \ + break; \ + } \ + case UNITY_LENGTH_MODIFIER_LONG: \ + { \ + NUMBER = (NUMBER_T)va_arg(VA, long ARG_T); \ + break; \ + } \ + case UNITY_LENGTH_MODIFIER_NONE: \ + default: \ + { \ + NUMBER = (NUMBER_T)va_arg(VA, ARG_T); \ + break; \ + } \ + } \ +} while (0) + +static enum UnityLengthModifier UnityLengthModifierGet(const char *pch, int *length) +{ + enum UnityLengthModifier length_mod; + switch (pch[0]) + { + case 'l': + { + if (pch[1] == 'l') + { + *length = 2; + length_mod = UNITY_LENGTH_MODIFIER_LONG_LONG; + } + else + { + *length = 1; + length_mod = UNITY_LENGTH_MODIFIER_LONG; + } + break; + } + case 'h': + { + // short and char are converted to int + length_mod = UNITY_LENGTH_MODIFIER_NONE; + if (pch[1] == 'h') + { + *length = 2; + } + else + { + *length = 1; + } + break; + } + case 'j': + case 'z': + case 't': + case 'L': + { + // Not supported, but should gobble up the length specifier anyway + length_mod = UNITY_LENGTH_MODIFIER_NONE; + *length = 1; + break; + } + default: + { + length_mod = UNITY_LENGTH_MODIFIER_NONE; + *length = 0; + } + } + return length_mod; +} + +/*----------------------------------------------- + * printf helper function + *-----------------------------------------------*/ +static void UnityPrintFVA(const char* format, va_list va) +{ + const char* pch = format; + if (pch != NULL) + { + while (*pch) + { + /* format identification character */ + if (*pch == '%') + { + pch++; + + if (pch != NULL) + { + int length_mod_size; + enum UnityLengthModifier length_mod = UnityLengthModifierGet(pch, &length_mod_size); + pch += length_mod_size; + + switch (*pch) + { + case 'd': + case 'i': + { + UNITY_INT number; + UNITY_EXTRACT_ARG(UNITY_INT, number, length_mod, va, int); + UnityPrintNumber((UNITY_INT)number); + break; + } +#ifndef UNITY_EXCLUDE_FLOAT_PRINT + case 'f': + case 'g': + { + const double number = va_arg(va, double); + UnityPrintFloat((UNITY_DOUBLE)number); + break; + } +#endif + case 'u': + { + UNITY_UINT number; + UNITY_EXTRACT_ARG(UNITY_UINT, number, length_mod, va, unsigned int); + UnityPrintNumberUnsigned(number); + break; + } + case 'b': + { + UNITY_UINT number; + UNITY_EXTRACT_ARG(UNITY_UINT, number, length_mod, va, unsigned int); + const UNITY_UINT mask = (UNITY_UINT)0 - (UNITY_UINT)1; + UNITY_OUTPUT_CHAR('0'); + UNITY_OUTPUT_CHAR('b'); + UnityPrintMask(mask, number); + break; + } + case 'x': + case 'X': + { + UNITY_UINT number; + UNITY_EXTRACT_ARG(UNITY_UINT, number, length_mod, va, unsigned int); + UNITY_OUTPUT_CHAR('0'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex(number, UNITY_MAX_NIBBLES); + break; + } + case 'p': + { + UNITY_UINT number; + char nibbles_to_print = 8; + if (UNITY_POINTER_WIDTH == 64) + { + length_mod = UNITY_LENGTH_MODIFIER_LONG_LONG; + nibbles_to_print = 16; + } + UNITY_EXTRACT_ARG(UNITY_UINT, number, length_mod, va, unsigned int); + UNITY_OUTPUT_CHAR('0'); + UNITY_OUTPUT_CHAR('x'); + UnityPrintNumberHex((UNITY_UINT)number, nibbles_to_print); + break; + } + case 'c': + { + const int ch = va_arg(va, int); + UnityPrintChar((const char *)&ch); + break; + } + case 's': + { + const char * string = va_arg(va, const char *); + UnityPrint(string); + break; + } + case '%': + { + UnityPrintChar(pch); + break; + } + default: + { + /* print the unknown format character */ + UNITY_OUTPUT_CHAR('%'); + UnityPrintChar(pch); + break; + } + } + } + } +#ifdef UNITY_OUTPUT_COLOR + /* print ANSI escape code */ + else if ((*pch == 27) && (*(pch + 1) == '[')) + { + pch += UnityPrintAnsiEscapeString(pch); + continue; + } +#endif + else if (*pch == '\n') + { + UNITY_PRINT_EOL(); + } + else + { + UnityPrintChar(pch); + } + + pch++; + } + } +} + +void UnityPrintF(const UNITY_LINE_TYPE line, const char* format, ...) +{ + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrint("INFO"); + if(format != NULL) + { + UnityPrint(": "); + va_list va; + va_start(va, format); + UnityPrintFVA(format, va); + va_end(va); + } + UNITY_PRINT_EOL(); +} +#endif /* ! UNITY_INCLUDE_PRINT_FORMATTED */ + + +/*----------------------------------------------- + * Control Functions + *-----------------------------------------------*/ + +/*-----------------------------------------------*/ +void UnityFail(const char* msg, const UNITY_LINE_TYPE line) +{ + RETURN_IF_FAIL_OR_IGNORE; + + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrint(UnityStrFail); + if (msg != NULL) + { + UNITY_OUTPUT_CHAR(':'); + +#ifdef UNITY_PRINT_TEST_CONTEXT + UNITY_PRINT_TEST_CONTEXT(); +#endif +#ifndef UNITY_EXCLUDE_DETAILS + if (Unity.CurrentDetail1) + { + UnityPrint(UnityStrDetail1Name); + UnityPrint(Unity.CurrentDetail1); + if (Unity.CurrentDetail2) + { + UnityPrint(UnityStrDetail2Name); + UnityPrint(Unity.CurrentDetail2); + } + UnityPrint(UnityStrSpacer); + } +#endif + if (msg[0] != ' ') + { + UNITY_OUTPUT_CHAR(' '); + } + UnityPrint(msg); + } + + UNITY_FAIL_AND_BAIL; +} + +/*-----------------------------------------------*/ +void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line) +{ + RETURN_IF_FAIL_OR_IGNORE; + + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrint(UnityStrIgnore); + if (msg != NULL) + { + UNITY_OUTPUT_CHAR(':'); + UNITY_OUTPUT_CHAR(' '); + UnityPrint(msg); + } + UNITY_IGNORE_AND_BAIL; +} + +/*-----------------------------------------------*/ +void UnityMessage(const char* msg, const UNITY_LINE_TYPE line) +{ + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrint("INFO"); + if (msg != NULL) + { + UNITY_OUTPUT_CHAR(':'); + UNITY_OUTPUT_CHAR(' '); + UnityPrint(msg); + } + UNITY_PRINT_EOL(); +} + +/*-----------------------------------------------*/ +/* If we have not defined our own test runner, then include our default test runner to make life easier */ +#ifndef UNITY_SKIP_DEFAULT_RUNNER +void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum) +{ + Unity.CurrentTestName = FuncName; + Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum; + Unity.NumberOfTests++; + UNITY_CLR_DETAILS(); + UNITY_EXEC_TIME_START(); + if (TEST_PROTECT()) + { + setUp(); + Func(); + } + if (TEST_PROTECT()) + { + tearDown(); + } + UNITY_EXEC_TIME_STOP(); + UnityConcludeTest(); +} +#endif + +/*-----------------------------------------------*/ +void UnitySetTestFile(const char* filename) +{ + Unity.TestFile = filename; +} + +/*-----------------------------------------------*/ +void UnityBegin(const char* filename) +{ + Unity.TestFile = filename; + Unity.CurrentTestName = NULL; + Unity.CurrentTestLineNumber = 0; + Unity.NumberOfTests = 0; + Unity.TestFailures = 0; + Unity.TestIgnores = 0; + Unity.CurrentTestFailed = 0; + Unity.CurrentTestIgnored = 0; + + UNITY_CLR_DETAILS(); + UNITY_OUTPUT_START(); +} + +/*-----------------------------------------------*/ +int UnityEnd(void) +{ + UNITY_PRINT_EOL(); + UnityPrint(UnityStrBreaker); + UNITY_PRINT_EOL(); + UnityPrintNumber((UNITY_INT)(Unity.NumberOfTests)); + UnityPrint(UnityStrResultsTests); + UnityPrintNumber((UNITY_INT)(Unity.TestFailures)); + UnityPrint(UnityStrResultsFailures); + UnityPrintNumber((UNITY_INT)(Unity.TestIgnores)); + UnityPrint(UnityStrResultsIgnored); + UNITY_PRINT_EOL(); + if (Unity.TestFailures == 0U) + { + UnityPrint(UnityStrOk); + } + else + { + UnityPrint(UnityStrFail); +#ifdef UNITY_DIFFERENTIATE_FINAL_FAIL + UNITY_OUTPUT_CHAR('E'); UNITY_OUTPUT_CHAR('D'); +#endif + } + UNITY_PRINT_EOL(); + UNITY_FLUSH_CALL(); + UNITY_OUTPUT_COMPLETE(); + return (int)(Unity.TestFailures); +} + +/*----------------------------------------------- + * Command Line Argument Support + *-----------------------------------------------*/ +#ifdef UNITY_USE_COMMAND_LINE_ARGS + +char* UnityOptionIncludeNamed = NULL; +char* UnityOptionExcludeNamed = NULL; +int UnityVerbosity = 1; + +/*-----------------------------------------------*/ +int UnityParseOptions(int argc, char** argv) +{ + int i; + UnityOptionIncludeNamed = NULL; + UnityOptionExcludeNamed = NULL; + + for (i = 1; i < argc; i++) + { + if (argv[i][0] == '-') + { + switch (argv[i][1]) + { + case 'l': /* list tests */ + return -1; + case 'n': /* include tests with name including this string */ + case 'f': /* an alias for -n */ + if (argv[i][2] == '=') + { + UnityOptionIncludeNamed = &argv[i][3]; + } + else if (++i < argc) + { + UnityOptionIncludeNamed = argv[i]; + } + else + { + UnityPrint("ERROR: No Test String to Include Matches For"); + UNITY_PRINT_EOL(); + return 1; + } + break; + case 'q': /* quiet */ + UnityVerbosity = 0; + break; + case 'v': /* verbose */ + UnityVerbosity = 2; + break; + case 'x': /* exclude tests with name including this string */ + if (argv[i][2] == '=') + { + UnityOptionExcludeNamed = &argv[i][3]; + } + else if (++i < argc) + { + UnityOptionExcludeNamed = argv[i]; + } + else + { + UnityPrint("ERROR: No Test String to Exclude Matches For"); + UNITY_PRINT_EOL(); + return 1; + } + break; + default: + UnityPrint("ERROR: Unknown Option "); + UNITY_OUTPUT_CHAR(argv[i][1]); + UNITY_PRINT_EOL(); + /* Now display help */ + /* FALLTHRU */ + case 'h': + UnityPrint("Options: "); UNITY_PRINT_EOL(); + UnityPrint("-l List all tests and exit"); UNITY_PRINT_EOL(); + UnityPrint("-f NAME Filter to run only tests whose name includes NAME"); UNITY_PRINT_EOL(); + UnityPrint("-n NAME (deprecated) alias of -f"); UNITY_PRINT_EOL(); + UnityPrint("-h show this Help menu"); UNITY_PRINT_EOL(); + UnityPrint("-q Quiet/decrease verbosity"); UNITY_PRINT_EOL(); + UnityPrint("-v increase Verbosity"); UNITY_PRINT_EOL(); + UnityPrint("-x NAME eXclude tests whose name includes NAME"); UNITY_PRINT_EOL(); + UNITY_OUTPUT_FLUSH(); + return 1; + } + } + } + + return 0; +} + +/*-----------------------------------------------*/ +int IsStringInBiggerString(const char* longstring, const char* shortstring) +{ + const char* lptr = longstring; + const char* sptr = shortstring; + const char* lnext = lptr; + + if (*sptr == '*') + { + return 1; + } + + while (*lptr) + { + lnext = lptr + 1; + + /* If they current bytes match, go on to the next bytes */ + while (*lptr && *sptr && (*lptr == *sptr)) + { + lptr++; + sptr++; + + /* We're done if we match the entire string or up to a wildcard */ + if (*sptr == '*') + return 1; + if (*sptr == ',') + return 1; + if (*sptr == '"') + return 1; + if (*sptr == '\'') + return 1; + if (*sptr == ':') + return 2; + if (*sptr == 0) + return 1; + } + + /* Otherwise we start in the long pointer 1 character further and try again */ + lptr = lnext; + sptr = shortstring; + } + + return 0; +} + +/*-----------------------------------------------*/ +int UnityStringArgumentMatches(const char* str) +{ + int retval; + const char* ptr1; + const char* ptr2; + const char* ptrf; + + /* Go through the options and get the substrings for matching one at a time */ + ptr1 = str; + while (ptr1[0] != 0) + { + if ((ptr1[0] == '"') || (ptr1[0] == '\'')) + { + ptr1++; + } + + /* look for the start of the next partial */ + ptr2 = ptr1; + ptrf = 0; + do + { + ptr2++; + if ((ptr2[0] == ':') && (ptr2[1] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')) + { + ptrf = &ptr2[1]; + } + } while ((ptr2[0] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')); + + while ((ptr2[0] != 0) && ((ptr2[0] == ':') || (ptr2[0] == '\'') || (ptr2[0] == '"') || (ptr2[0] == ','))) + { + ptr2++; + } + + /* done if complete filename match */ + retval = IsStringInBiggerString(Unity.TestFile, ptr1); + if (retval == 1) + { + return retval; + } + + /* done if testname match after filename partial match */ + if ((retval == 2) && (ptrf != 0)) + { + if (IsStringInBiggerString(Unity.CurrentTestName, ptrf)) + { + return 1; + } + } + + /* done if complete testname match */ + if (IsStringInBiggerString(Unity.CurrentTestName, ptr1) == 1) + { + return 1; + } + + ptr1 = ptr2; + } + + /* we couldn't find a match for any substrings */ + return 0; +} + +/*-----------------------------------------------*/ +int UnityTestMatches(void) +{ + /* Check if this test name matches the included test pattern */ + int retval; + if (UnityOptionIncludeNamed) + { + retval = UnityStringArgumentMatches(UnityOptionIncludeNamed); + } + else + { + retval = 1; + } + + /* Check if this test name matches the excluded test pattern */ + if (UnityOptionExcludeNamed) + { + if (UnityStringArgumentMatches(UnityOptionExcludeNamed)) + { + retval = 0; + } + } + + return retval; +} + +#endif /* UNITY_USE_COMMAND_LINE_ARGS */ +/*-----------------------------------------------*/ \ No newline at end of file diff --git a/Tests/UnitTests/Unity/unity.h b/Tests/UnitTests/Unity/unity.h new file mode 100644 index 000000000..4079f259e --- /dev/null +++ b/Tests/UnitTests/Unity/unity.h @@ -0,0 +1,697 @@ +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007-21 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_FRAMEWORK_H +#define UNITY_FRAMEWORK_H +#define UNITY + +#define UNITY_VERSION_MAJOR 2 +#define UNITY_VERSION_MINOR 6 +#define UNITY_VERSION_BUILD 0 +#define UNITY_VERSION ((UNITY_VERSION_MAJOR << 16) | (UNITY_VERSION_MINOR << 8) | UNITY_VERSION_BUILD) + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "unity_internals.h" + +/*------------------------------------------------------- + * Test Setup / Teardown + *-------------------------------------------------------*/ + +/* These functions are intended to be called before and after each test. + * If using unity directly, these will need to be provided for each test + * executable built. If you are using the test runner generator and/or + * Ceedling, these are optional. */ +void setUp(void); +void tearDown(void); + +/* These functions are intended to be called at the beginning and end of an + * entire test suite. suiteTearDown() is passed the number of tests that + * failed, and its return value becomes the exit code of main(). If using + * Unity directly, you're in charge of calling these if they are desired. + * If using Ceedling or the test runner generator, these will be called + * automatically if they exist. */ +void suiteSetUp(void); +int suiteTearDown(int num_failures); + +/*------------------------------------------------------- + * Test Reset and Verify + *-------------------------------------------------------*/ + +/* These functions are intended to be called before during tests in order + * to support complex test loops, etc. Both are NOT built into Unity. Instead + * the test runner generator will create them. resetTest will run teardown and + * setup again, verifying any end-of-test needs between. verifyTest will only + * run the verification. */ +void resetTest(void); +void verifyTest(void); + +/*------------------------------------------------------- + * Configuration Options + *------------------------------------------------------- + * All options described below should be passed as a compiler flag to all files using Unity. If you must add #defines, place them BEFORE the #include above. + + * Integers/longs/pointers + * - Unity attempts to automatically discover your integer sizes + * - define UNITY_EXCLUDE_STDINT_H to stop attempting to look in + * - define UNITY_EXCLUDE_LIMITS_H to stop attempting to look in + * - If you cannot use the automatic methods above, you can force Unity by using these options: + * - define UNITY_SUPPORT_64 + * - set UNITY_INT_WIDTH + * - set UNITY_LONG_WIDTH + * - set UNITY_POINTER_WIDTH + + * Floats + * - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons + * - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT + * - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats + * - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons + * - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default) + * - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE + * - define UNITY_DOUBLE_TYPE to specify something other than double + * - define UNITY_EXCLUDE_FLOAT_PRINT to trim binary size, won't print floating point values in errors + + * Output + * - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired + * - define UNITY_DIFFERENTIATE_FINAL_FAIL to print FAILED (vs. FAIL) at test end summary - for automated search for failure + + * Optimization + * - by default, line numbers are stored in unsigned shorts. Define UNITY_LINE_TYPE with a different type if your files are huge + * - by default, test and failure counters are unsigned shorts. Define UNITY_COUNTER_TYPE with a different type if you want to save space or have more than 65535 Tests. + + * Test Cases + * - define UNITY_SUPPORT_TEST_CASES to include the TEST_CASE macro, though really it's mostly about the runner generator script + + * Parameterized Tests + * - you'll want to create a define of TEST_CASE(...), TEST_RANGE(...) and/or TEST_MATRIX(...) which basically evaluates to nothing + + * Tests with Arguments + * - you'll want to define UNITY_USE_COMMAND_LINE_ARGS if you have the test runner passing arguments to Unity + + *------------------------------------------------------- + * Basic Fail and Ignore + *-------------------------------------------------------*/ + +#define TEST_FAIL_MESSAGE(message) UNITY_TEST_FAIL(__LINE__, (message)) +#define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL) +#define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, (message)) +#define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL) +#define TEST_MESSAGE(message) UnityMessage((message), __LINE__) +#define TEST_ONLY() +#ifdef UNITY_INCLUDE_PRINT_FORMATTED +#define TEST_PRINTF(message, ...) UnityPrintF(__LINE__, (message), ##__VA_ARGS__) +#endif + +/* It is not necessary for you to call PASS. A PASS condition is assumed if nothing fails. + * This method allows you to abort a test immediately with a PASS state, ignoring the remainder of the test. */ +#define TEST_PASS() TEST_ABORT() +#define TEST_PASS_MESSAGE(message) do { UnityMessage((message), __LINE__); TEST_ABORT(); } while (0) + +/*------------------------------------------------------- + * Build Directives + *------------------------------------------------------- + + * These macros do nothing, but they are useful for additional build context. + * Tools (like Ceedling) can scan for these directives and make use of them for + * per-test-executable #include search paths and linking. */ + +/* Add source files to a test executable's compilation and linking. Ex: TEST_SOURCE_FILE("sandwiches.c") */ +#define TEST_SOURCE_FILE(a) + +/* Customize #include search paths for a test executable's compilation. Ex: TEST_INCLUDE_PATH("src/module_a/inc") */ +#define TEST_INCLUDE_PATH(a) + +/*------------------------------------------------------- + * Test Asserts (simple) + *-------------------------------------------------------*/ + +/* Boolean */ +#define TEST_ASSERT(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expression Evaluated To FALSE") +#define TEST_ASSERT_TRUE(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expected TRUE Was FALSE") +#define TEST_ASSERT_UNLESS(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expression Evaluated To TRUE") +#define TEST_ASSERT_FALSE(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expected FALSE Was TRUE") +#define TEST_ASSERT_NULL(pointer) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, " Expected NULL") +#define TEST_ASSERT_NOT_NULL(pointer) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, " Expected Non-NULL") +#define TEST_ASSERT_EMPTY(pointer) UNITY_TEST_ASSERT_EMPTY( (pointer), __LINE__, " Expected Empty") +#define TEST_ASSERT_NOT_EMPTY(pointer) UNITY_TEST_ASSERT_NOT_EMPTY((pointer), __LINE__, " Expected Non-Empty") + +/* Integers (of all sizes) */ +#define TEST_ASSERT_EQUAL_INT(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_size_t(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_CHAR(expected, actual) UNITY_TEST_ASSERT_EQUAL_CHAR((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT)(-1), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT)(0), (actual), __LINE__, NULL) +#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT)1 << (bit)), (UNITY_UINT)(-1), (actual), __LINE__, NULL) +#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT)1 << (bit)), (UNITY_UINT)(0), (actual), __LINE__, NULL) + +/* Integer Not Equal To (of all sizes) */ +#define TEST_ASSERT_NOT_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_CHAR((threshold), (actual), __LINE__, NULL) + +/* Integer Greater Than/ Less Than (of all sizes) */ +#define TEST_ASSERT_GREATER_THAN(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_size_t(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_CHAR(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_CHAR((threshold), (actual), __LINE__, NULL) + +#define TEST_ASSERT_LESS_THAN(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_size_t(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_CHAR(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_CHAR((threshold), (actual), __LINE__, NULL) + +#define TEST_ASSERT_GREATER_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, NULL) + +#define TEST_ASSERT_LESS_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, NULL) + +/* Integer Ranges (of all sizes) */ +#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_size_t_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_CHAR_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_CHAR_WITHIN((delta), (expected), (actual), __LINE__, NULL) + +/* Integer Array Ranges (of all sizes) */ +#define TEST_ASSERT_INT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_INT8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_INT16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_INT32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_INT64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_UINT64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_size_t_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_HEX64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) +#define TEST_ASSERT_CHAR_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL) + + +/* Structs and Strings */ +#define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING(expected, actual) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, NULL) + +/* Arrays */ +#define TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_size_t_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_CHAR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) + +/* Arrays Compared To Single Value */ +#define TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_size_t(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_CHAR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_CHAR((expected), (actual), (num_elements), __LINE__, NULL) + +/* Floating Point (If Enabled) */ +#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_NOT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_NOT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_NOT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_FLOAT_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_FLOAT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_FLOAT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_FLOAT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_FLOAT(threshold, actual) UNITY_TEST_ASSERT_LESS_THAN_FLOAT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_FLOAT(threshold, actual) UNITY_TEST_ASSERT_LESS_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, NULL) + +/* Double (If Enabled) */ +#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_NOT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_NOT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_NOT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_DOUBLE_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_GREATER_THAN_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_DOUBLE((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_THAN_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_LESS_THAN_DOUBLE((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_LESS_OR_EQUAL_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_LESS_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, NULL) + +/* Shorthand */ +#ifdef UNITY_SHORTHAND_AS_OLD +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal") +#endif +#ifdef UNITY_SHORTHAND_AS_INT +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif +#ifdef UNITY_SHORTHAND_AS_MEM +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_MEMORY((&expected), (&actual), sizeof(expected), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif +#ifdef UNITY_SHORTHAND_AS_RAW +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) == (actual)), __LINE__, " Expected Equal") +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal") +#endif +#ifdef UNITY_SHORTHAND_AS_NONE +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif + +/*------------------------------------------------------- + * Test Asserts (with additional messages) + *-------------------------------------------------------*/ + +/* Boolean */ +#define TEST_ASSERT_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message)) +#define TEST_ASSERT_TRUE_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message)) +#define TEST_ASSERT_UNLESS_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message)) +#define TEST_ASSERT_FALSE_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message)) +#define TEST_ASSERT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, (message)) +#define TEST_ASSERT_NOT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, (message)) +#define TEST_ASSERT_EMPTY_MESSAGE(pointer, message) UNITY_TEST_ASSERT_EMPTY( (pointer), __LINE__, (message)) +#define TEST_ASSERT_NOT_EMPTY_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_EMPTY((pointer), __LINE__, (message)) + +/* Integers (of all sizes) */ +#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_size_t_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(-1), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(0), (actual), __LINE__, (message)) +#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, (message)) +#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_CHAR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_CHAR((expected), (actual), __LINE__, (message)) + +/* Integer Not Equal To (of all sizes) */ +#define TEST_ASSERT_NOT_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_CHAR((threshold), (actual), __LINE__, (message)) + + +/* Integer Greater Than/ Less Than (of all sizes) */ +#define TEST_ASSERT_GREATER_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_CHAR((threshold), (actual), __LINE__, (message)) + +#define TEST_ASSERT_LESS_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_CHAR((threshold), (actual), __LINE__, (message)) + +#define TEST_ASSERT_GREATER_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, (message)) + +#define TEST_ASSERT_LESS_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, (message)) + +/* Integer Ranges (of all sizes) */ +#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_size_t_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_CHAR_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_CHAR_WITHIN((delta), (expected), (actual), __LINE__, (message)) + +/* Integer Array Ranges (of all sizes) */ +#define TEST_ASSERT_INT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_INT8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_INT16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_INT32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_INT64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_UINT64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_size_t_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_HEX64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) +#define TEST_ASSERT_CHAR_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message)) + + +/* Structs and Strings */ +#define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_LEN_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, (message)) + +/* Arrays */ +#define TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_size_t_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_CHAR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) + +/* Arrays Compared To Single Value*/ +#define TEST_ASSERT_EACH_EQUAL_INT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_INT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_UINT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_size_t_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_HEX64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_PTR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_STRING_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_MEMORY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_CHAR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_CHAR((expected), (actual), (num_elements), __LINE__, (message)) + +/* Floating Point (If Enabled) */ +#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_FLOAT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_FLOAT_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_FLOAT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_FLOAT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_THAN_FLOAT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, (message)) + +/* Double (If Enabled) */ +#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_DOUBLE_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EACH_EQUAL_DOUBLE_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_GREATER_THAN_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_DOUBLE((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_THAN_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_THAN_DOUBLE((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_LESS_OR_EQUAL_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, (message)) + +/* Shorthand */ +#ifdef UNITY_SHORTHAND_AS_OLD +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, (message)) +#endif +#ifdef UNITY_SHORTHAND_AS_INT +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, message) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif +#ifdef UNITY_SHORTHAND_AS_MEM +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((&expected), (&actual), sizeof(expected), __LINE__, message) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif +#ifdef UNITY_SHORTHAND_AS_RAW +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) == (actual)), __LINE__, message) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, message) +#endif +#ifdef UNITY_SHORTHAND_AS_NONE +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand) +#endif + +/* end of UNITY_FRAMEWORK_H */ +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/Tests/UnitTests/Unity/unity_internals.h b/Tests/UnitTests/Unity/unity_internals.h new file mode 100644 index 000000000..65938ff76 --- /dev/null +++ b/Tests/UnitTests/Unity/unity_internals.h @@ -0,0 +1,1169 @@ +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007-21 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_INTERNALS_H +#define UNITY_INTERNALS_H + +#ifdef UNITY_INCLUDE_CONFIG_H +#include "unity_config.h" +#endif + +#ifndef UNITY_EXCLUDE_SETJMP_H +#include +#endif + +#ifndef UNITY_EXCLUDE_MATH_H +#include +#endif + +#ifndef UNITY_EXCLUDE_STDDEF_H +#include +#endif + +#ifdef UNITY_INCLUDE_PRINT_FORMATTED +#include +#endif + +/* Unity Attempts to Auto-Detect Integer Types + * Attempt 1: UINT_MAX, ULONG_MAX in , or default to 32 bits + * Attempt 2: UINTPTR_MAX in , or default to same size as long + * The user may override any of these derived constants: + * UNITY_INT_WIDTH, UNITY_LONG_WIDTH, UNITY_POINTER_WIDTH */ +#ifndef UNITY_EXCLUDE_STDINT_H +#include +#endif + +#ifndef UNITY_EXCLUDE_LIMITS_H +#include +#endif + +#if defined(__GNUC__) || defined(__clang__) + #define UNITY_FUNCTION_ATTR(a) __attribute__((a)) +#else + #define UNITY_FUNCTION_ATTR(a) /* ignore */ +#endif + +#ifndef UNITY_NORETURN + #if defined(__cplusplus) + #if __cplusplus >= 201103L + #define UNITY_NORETURN [[ noreturn ]] + #endif + #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L + #if defined(_WIN32) && defined(_MSC_VER) + /* We are using MSVC compiler on Windows platform. */ + /* Not all Windows SDKs supports , but compiler can support C11: */ + /* https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-arriving-in-msvc/ */ + /* Not sure, that Mingw compilers has Windows SDK headers at all. */ + #include + #endif + + /* Using Windows SDK predefined macro for detecting supported SDK with MSVC compiler. */ + /* Mingw GCC should work without that fixes. */ + /* Based on: */ + /* https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt?view=msvc-170 */ + /* NTDDI_WIN10_FE is equal to Windows 10 SDK 2104 */ + #if defined(_MSC_VER) && ((!defined(NTDDI_WIN10_FE)) || WDK_NTDDI_VERSION < NTDDI_WIN10_FE) + /* Based on tests and: */ + /* https://docs.microsoft.com/en-us/cpp/c-language/noreturn?view=msvc-170 */ + /* https://en.cppreference.com/w/c/language/_Noreturn */ + #define UNITY_NORETURN _Noreturn + #else /* Using newer Windows SDK or not MSVC compiler */ + #include + #define UNITY_NORETURN noreturn + #endif + #endif +#endif +#ifndef UNITY_NORETURN + #define UNITY_NORETURN UNITY_FUNCTION_ATTR(__noreturn__) +#endif + +/*------------------------------------------------------- + * Guess Widths If Not Specified + *-------------------------------------------------------*/ + +/* Determine the size of an int, if not already specified. + * We cannot use sizeof(int), because it is not yet defined + * at this stage in the translation of the C program. + * Also sizeof(int) does return the size in addressable units on all platforms, + * which may not necessarily be the size in bytes. + * Therefore, infer it from UINT_MAX if possible. */ +#ifndef UNITY_INT_WIDTH + #ifdef UINT_MAX + #if (UINT_MAX == 0xFFFF) + #define UNITY_INT_WIDTH (16) + #elif (UINT_MAX == 0xFFFFFFFF) + #define UNITY_INT_WIDTH (32) + #elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF) + #define UNITY_INT_WIDTH (64) + #endif + #else /* Set to default */ + #define UNITY_INT_WIDTH (32) + #endif /* UINT_MAX */ +#endif + +/* Determine the size of a long, if not already specified. */ +#ifndef UNITY_LONG_WIDTH + #ifdef ULONG_MAX + #if (ULONG_MAX == 0xFFFF) + #define UNITY_LONG_WIDTH (16) + #elif (ULONG_MAX == 0xFFFFFFFF) + #define UNITY_LONG_WIDTH (32) + #elif (ULONG_MAX == 0xFFFFFFFFFFFFFFFF) + #define UNITY_LONG_WIDTH (64) + #endif + #else /* Set to default */ + #define UNITY_LONG_WIDTH (32) + #endif /* ULONG_MAX */ +#endif + +/* Determine the size of a pointer, if not already specified. */ +#ifndef UNITY_POINTER_WIDTH + #ifdef UINTPTR_MAX + #if (UINTPTR_MAX <= 0xFFFF) + #define UNITY_POINTER_WIDTH (16) + #elif (UINTPTR_MAX <= 0xFFFFFFFF) + #define UNITY_POINTER_WIDTH (32) + #elif (UINTPTR_MAX <= 0xFFFFFFFFFFFFFFFF) + #define UNITY_POINTER_WIDTH (64) + #endif + #else /* Set to default */ + #define UNITY_POINTER_WIDTH UNITY_LONG_WIDTH + #endif /* UINTPTR_MAX */ +#endif + +/*------------------------------------------------------- + * Int Support (Define types based on detected sizes) + *-------------------------------------------------------*/ + +#if (UNITY_INT_WIDTH == 32) + typedef unsigned char UNITY_UINT8; + typedef unsigned short UNITY_UINT16; + typedef unsigned int UNITY_UINT32; + typedef signed char UNITY_INT8; + typedef signed short UNITY_INT16; + typedef signed int UNITY_INT32; +#elif (UNITY_INT_WIDTH == 16) + typedef unsigned char UNITY_UINT8; + typedef unsigned int UNITY_UINT16; + typedef unsigned long UNITY_UINT32; + typedef signed char UNITY_INT8; + typedef signed int UNITY_INT16; + typedef signed long UNITY_INT32; +#else + #error Invalid UNITY_INT_WIDTH specified! (16 or 32 are supported) +#endif + +/*------------------------------------------------------- + * 64-bit Support + *-------------------------------------------------------*/ + +/* Auto-detect 64 Bit Support */ +#ifndef UNITY_SUPPORT_64 + #if UNITY_LONG_WIDTH == 64 || UNITY_POINTER_WIDTH == 64 + #define UNITY_SUPPORT_64 + #endif +#endif + +/* 64-Bit Support Dependent Configuration */ +#ifndef UNITY_SUPPORT_64 + /* No 64-bit Support */ + typedef UNITY_UINT32 UNITY_UINT; + typedef UNITY_INT32 UNITY_INT; + #define UNITY_MAX_NIBBLES (8) /* Maximum number of nibbles in a UNITY_(U)INT */ +#else + /* 64-bit Support */ + #if (UNITY_LONG_WIDTH == 32) + typedef unsigned long long UNITY_UINT64; + typedef signed long long UNITY_INT64; + #elif (UNITY_LONG_WIDTH == 64) + typedef unsigned long UNITY_UINT64; + typedef signed long UNITY_INT64; + #else + #error Invalid UNITY_LONG_WIDTH specified! (32 or 64 are supported) + #endif + typedef UNITY_UINT64 UNITY_UINT; + typedef UNITY_INT64 UNITY_INT; + #define UNITY_MAX_NIBBLES (16) /* Maximum number of nibbles in a UNITY_(U)INT */ +#endif + +/*------------------------------------------------------- + * Pointer Support + *-------------------------------------------------------*/ + +#if (UNITY_POINTER_WIDTH == 32) + #define UNITY_PTR_TO_INT UNITY_INT32 + #define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX32 +#elif (UNITY_POINTER_WIDTH == 64) + #define UNITY_PTR_TO_INT UNITY_INT64 + #define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX64 +#elif (UNITY_POINTER_WIDTH == 16) + #define UNITY_PTR_TO_INT UNITY_INT16 + #define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX16 +#else + #error Invalid UNITY_POINTER_WIDTH specified! (16, 32 or 64 are supported) +#endif + +#ifndef UNITY_PTR_ATTRIBUTE + #define UNITY_PTR_ATTRIBUTE +#endif + +#ifndef UNITY_INTERNAL_PTR + #define UNITY_INTERNAL_PTR UNITY_PTR_ATTRIBUTE const void* +#endif + +/* optionally define UNITY_COMPARE_PTRS_ON_ZERO_ARRAY */ + +/*------------------------------------------------------- + * Float Support + *-------------------------------------------------------*/ + +#ifdef UNITY_EXCLUDE_FLOAT + +/* No Floating Point Support */ +#ifndef UNITY_EXCLUDE_DOUBLE +#define UNITY_EXCLUDE_DOUBLE /* Remove double when excluding float support */ +#endif +#ifndef UNITY_EXCLUDE_FLOAT_PRINT +#define UNITY_EXCLUDE_FLOAT_PRINT +#endif + +#else + +/* Floating Point Support */ +#ifndef UNITY_FLOAT_PRECISION +#define UNITY_FLOAT_PRECISION (0.00001f) +#endif +#ifndef UNITY_FLOAT_TYPE +#define UNITY_FLOAT_TYPE float +#endif +typedef UNITY_FLOAT_TYPE UNITY_FLOAT; + +/* isnan macro should be provided by math.h. Override if not macro */ +#ifndef UNITY_IS_NAN +#ifndef isnan +/* NaN is the only floating point value that does NOT equal itself. + * Therefore if n != n, then it is NaN. */ +#define UNITY_IS_NAN(n) ((n != n) ? 1 : 0) +#else +#define UNITY_IS_NAN(n) isnan(n) +#endif +#endif + +/* isinf macro should be provided by math.h. Override if not macro */ +#ifndef UNITY_IS_INF +#ifndef isinf +/* The value of Inf - Inf is NaN */ +#define UNITY_IS_INF(n) (UNITY_IS_NAN((n) - (n)) && !UNITY_IS_NAN(n)) +#else +#define UNITY_IS_INF(n) isinf(n) +#endif +#endif + +#endif + +/*------------------------------------------------------- + * Double Float Support + *-------------------------------------------------------*/ + +/* unlike float, we DON'T include by default */ +#if defined(UNITY_EXCLUDE_DOUBLE) || !defined(UNITY_INCLUDE_DOUBLE) + + /* No Floating Point Support */ + #ifndef UNITY_EXCLUDE_DOUBLE + #define UNITY_EXCLUDE_DOUBLE + #else + #undef UNITY_INCLUDE_DOUBLE + #endif + + #ifndef UNITY_EXCLUDE_FLOAT + #ifndef UNITY_DOUBLE_TYPE + #define UNITY_DOUBLE_TYPE double + #endif + typedef UNITY_FLOAT UNITY_DOUBLE; + /* For parameter in UnityPrintFloat(UNITY_DOUBLE), which aliases to double or float */ + #endif + +#else + + /* Double Floating Point Support */ + #ifndef UNITY_DOUBLE_PRECISION + #define UNITY_DOUBLE_PRECISION (1e-12) + #endif + + #ifndef UNITY_DOUBLE_TYPE + #define UNITY_DOUBLE_TYPE double + #endif + typedef UNITY_DOUBLE_TYPE UNITY_DOUBLE; + +#endif + +/*------------------------------------------------------- + * Output Method: stdout (DEFAULT) + *-------------------------------------------------------*/ +#ifndef UNITY_OUTPUT_CHAR + /* Default to using putchar, which is defined in stdio.h */ + #include + #define UNITY_OUTPUT_CHAR(a) (void)putchar(a) +#else + /* If defined as something else, make sure we declare it here so it's ready for use */ + #ifdef UNITY_OUTPUT_CHAR_HEADER_DECLARATION + extern void UNITY_OUTPUT_CHAR_HEADER_DECLARATION; + #endif +#endif + +#ifndef UNITY_OUTPUT_FLUSH + #ifdef UNITY_USE_FLUSH_STDOUT + /* We want to use the stdout flush utility */ + #include + #define UNITY_OUTPUT_FLUSH() (void)fflush(stdout) + #else + /* We've specified nothing, therefore flush should just be ignored */ + #define UNITY_OUTPUT_FLUSH() (void)0 + #endif +#else + /* If defined as something else, make sure we declare it here so it's ready for use */ + #ifdef UNITY_OUTPUT_FLUSH_HEADER_DECLARATION + extern void UNITY_OUTPUT_FLUSH_HEADER_DECLARATION; + #endif +#endif + +#ifndef UNITY_OUTPUT_FLUSH +#define UNITY_FLUSH_CALL() +#else +#define UNITY_FLUSH_CALL() UNITY_OUTPUT_FLUSH() +#endif + +#ifndef UNITY_PRINT_EOL +#define UNITY_PRINT_EOL() UNITY_OUTPUT_CHAR('\n') +#endif + +#ifndef UNITY_OUTPUT_START +#define UNITY_OUTPUT_START() +#endif + +#ifndef UNITY_OUTPUT_COMPLETE +#define UNITY_OUTPUT_COMPLETE() +#endif + +#ifdef UNITY_INCLUDE_EXEC_TIME + #if !defined(UNITY_EXEC_TIME_START) && \ + !defined(UNITY_EXEC_TIME_STOP) && \ + !defined(UNITY_PRINT_EXEC_TIME) && \ + !defined(UNITY_TIME_TYPE) + /* If none any of these macros are defined then try to provide a default implementation */ + + #if defined(UNITY_CLOCK_MS) + /* This is a simple way to get a default implementation on platforms that support getting a millisecond counter */ + #define UNITY_TIME_TYPE UNITY_UINT + #define UNITY_EXEC_TIME_START() Unity.CurrentTestStartTime = UNITY_CLOCK_MS() + #define UNITY_EXEC_TIME_STOP() Unity.CurrentTestStopTime = UNITY_CLOCK_MS() + #define UNITY_PRINT_EXEC_TIME() { \ + UNITY_UINT execTimeMs = (Unity.CurrentTestStopTime - Unity.CurrentTestStartTime); \ + UnityPrint(" ("); \ + UnityPrintNumberUnsigned(execTimeMs); \ + UnityPrint(" ms)"); \ + } + #elif defined(_WIN32) + #include + #define UNITY_TIME_TYPE clock_t + #define UNITY_GET_TIME(t) t = (clock_t)((clock() * 1000) / CLOCKS_PER_SEC) + #define UNITY_EXEC_TIME_START() UNITY_GET_TIME(Unity.CurrentTestStartTime) + #define UNITY_EXEC_TIME_STOP() UNITY_GET_TIME(Unity.CurrentTestStopTime) + #define UNITY_PRINT_EXEC_TIME() { \ + UNITY_UINT execTimeMs = (Unity.CurrentTestStopTime - Unity.CurrentTestStartTime); \ + UnityPrint(" ("); \ + UnityPrintNumberUnsigned(execTimeMs); \ + UnityPrint(" ms)"); \ + } + #elif defined(__unix__) || defined(__APPLE__) + #include + #define UNITY_TIME_TYPE struct timespec + #define UNITY_GET_TIME(t) clock_gettime(CLOCK_MONOTONIC, &t) + #define UNITY_EXEC_TIME_START() UNITY_GET_TIME(Unity.CurrentTestStartTime) + #define UNITY_EXEC_TIME_STOP() UNITY_GET_TIME(Unity.CurrentTestStopTime) + #define UNITY_PRINT_EXEC_TIME() { \ + UNITY_UINT execTimeMs = ((Unity.CurrentTestStopTime.tv_sec - Unity.CurrentTestStartTime.tv_sec) * 1000L); \ + execTimeMs += ((Unity.CurrentTestStopTime.tv_nsec - Unity.CurrentTestStartTime.tv_nsec) / 1000000L); \ + UnityPrint(" ("); \ + UnityPrintNumberUnsigned(execTimeMs); \ + UnityPrint(" ms)"); \ + } + #endif + #endif +#endif + +#ifndef UNITY_EXEC_TIME_START +#define UNITY_EXEC_TIME_START() do { /* nothing*/ } while (0) +#endif + +#ifndef UNITY_EXEC_TIME_STOP +#define UNITY_EXEC_TIME_STOP() do { /* nothing*/ } while (0) +#endif + +#ifndef UNITY_TIME_TYPE +#define UNITY_TIME_TYPE UNITY_UINT +#endif + +#ifndef UNITY_PRINT_EXEC_TIME +#define UNITY_PRINT_EXEC_TIME() do { /* nothing*/ } while (0) +#endif + +/*------------------------------------------------------- + * Footprint + *-------------------------------------------------------*/ + +#ifndef UNITY_LINE_TYPE +#define UNITY_LINE_TYPE UNITY_UINT +#endif + +#ifndef UNITY_COUNTER_TYPE +#define UNITY_COUNTER_TYPE UNITY_UINT +#endif + +/*------------------------------------------------------- + * Internal Structs Needed + *-------------------------------------------------------*/ + +typedef void (*UnityTestFunction)(void); + +#define UNITY_DISPLAY_RANGE_INT (0x10) +#define UNITY_DISPLAY_RANGE_UINT (0x20) +#define UNITY_DISPLAY_RANGE_HEX (0x40) +#define UNITY_DISPLAY_RANGE_CHAR (0x80) + +typedef enum +{ + UNITY_DISPLAY_STYLE_INT = (UNITY_INT_WIDTH / 8) + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT8 = 1 + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT16 = 2 + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT32 = 4 + UNITY_DISPLAY_RANGE_INT, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_INT64 = 8 + UNITY_DISPLAY_RANGE_INT, +#endif + + UNITY_DISPLAY_STYLE_UINT = (UNITY_INT_WIDTH / 8) + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT8 = 1 + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT16 = 2 + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT32 = 4 + UNITY_DISPLAY_RANGE_UINT, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_UINT64 = 8 + UNITY_DISPLAY_RANGE_UINT, +#endif + + UNITY_DISPLAY_STYLE_HEX8 = 1 + UNITY_DISPLAY_RANGE_HEX, + UNITY_DISPLAY_STYLE_HEX16 = 2 + UNITY_DISPLAY_RANGE_HEX, + UNITY_DISPLAY_STYLE_HEX32 = 4 + UNITY_DISPLAY_RANGE_HEX, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_HEX64 = 8 + UNITY_DISPLAY_RANGE_HEX, +#endif + + UNITY_DISPLAY_STYLE_CHAR = 1 + UNITY_DISPLAY_RANGE_CHAR + UNITY_DISPLAY_RANGE_INT, + + UNITY_DISPLAY_STYLE_UNKNOWN +} UNITY_DISPLAY_STYLE_T; + +typedef enum +{ + UNITY_WITHIN = 0x0, + UNITY_EQUAL_TO = 0x1, + UNITY_GREATER_THAN = 0x2, + UNITY_GREATER_OR_EQUAL = 0x2 + UNITY_EQUAL_TO, + UNITY_SMALLER_THAN = 0x4, + UNITY_SMALLER_OR_EQUAL = 0x4 + UNITY_EQUAL_TO, + UNITY_NOT_EQUAL = 0x0, + UNITY_UNKNOWN +} UNITY_COMPARISON_T; + +#ifndef UNITY_EXCLUDE_FLOAT +typedef enum UNITY_FLOAT_TRAIT +{ + UNITY_FLOAT_IS_NOT_INF = 0, + UNITY_FLOAT_IS_INF, + UNITY_FLOAT_IS_NOT_NEG_INF, + UNITY_FLOAT_IS_NEG_INF, + UNITY_FLOAT_IS_NOT_NAN, + UNITY_FLOAT_IS_NAN, + UNITY_FLOAT_IS_NOT_DET, + UNITY_FLOAT_IS_DET, + UNITY_FLOAT_INVALID_TRAIT +} UNITY_FLOAT_TRAIT_T; +#endif + +typedef enum +{ + UNITY_ARRAY_TO_VAL = 0, + UNITY_ARRAY_TO_ARRAY, + UNITY_ARRAY_UNKNOWN +} UNITY_FLAGS_T; + +struct UNITY_STORAGE_T +{ + const char* TestFile; + const char* CurrentTestName; +#ifndef UNITY_EXCLUDE_DETAILS + const char* CurrentDetail1; + const char* CurrentDetail2; +#endif + UNITY_LINE_TYPE CurrentTestLineNumber; + UNITY_COUNTER_TYPE NumberOfTests; + UNITY_COUNTER_TYPE TestFailures; + UNITY_COUNTER_TYPE TestIgnores; + UNITY_COUNTER_TYPE CurrentTestFailed; + UNITY_COUNTER_TYPE CurrentTestIgnored; +#ifdef UNITY_INCLUDE_EXEC_TIME + UNITY_TIME_TYPE CurrentTestStartTime; + UNITY_TIME_TYPE CurrentTestStopTime; +#endif +#ifndef UNITY_EXCLUDE_SETJMP_H + jmp_buf AbortFrame; +#endif +}; + +extern struct UNITY_STORAGE_T Unity; + +/*------------------------------------------------------- + * Test Suite Management + *-------------------------------------------------------*/ + +void UnityBegin(const char* filename); +int UnityEnd(void); +void UnitySetTestFile(const char* filename); +void UnityConcludeTest(void); + +#ifndef RUN_TEST +void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum); +#else +#define UNITY_SKIP_DEFAULT_RUNNER +#endif + +/*------------------------------------------------------- + * Details Support + *-------------------------------------------------------*/ + +#ifdef UNITY_EXCLUDE_DETAILS +#define UNITY_CLR_DETAILS() +#define UNITY_SET_DETAIL(d1) +#define UNITY_SET_DETAILS(d1,d2) +#else +#define UNITY_CLR_DETAILS() do { Unity.CurrentDetail1 = 0; Unity.CurrentDetail2 = 0; } while (0) +#define UNITY_SET_DETAIL(d1) do { Unity.CurrentDetail1 = (d1); Unity.CurrentDetail2 = 0; } while (0) +#define UNITY_SET_DETAILS(d1,d2) do { Unity.CurrentDetail1 = (d1); Unity.CurrentDetail2 = (d2); } while (0) + +#ifndef UNITY_DETAIL1_NAME +#define UNITY_DETAIL1_NAME "Function" +#endif + +#ifndef UNITY_DETAIL2_NAME +#define UNITY_DETAIL2_NAME "Argument" +#endif +#endif + +#ifdef UNITY_PRINT_TEST_CONTEXT +void UNITY_PRINT_TEST_CONTEXT(void); +#endif + +/*------------------------------------------------------- + * Test Output + *-------------------------------------------------------*/ + +void UnityPrint(const char* string); + +#ifdef UNITY_INCLUDE_PRINT_FORMATTED +void UnityPrintF(const UNITY_LINE_TYPE line, const char* format, ...); +#endif + +void UnityPrintLen(const char* string, const UNITY_UINT32 length); +void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number); +void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style); +void UnityPrintNumber(const UNITY_INT number_to_print); +void UnityPrintNumberUnsigned(const UNITY_UINT number); +void UnityPrintNumberHex(const UNITY_UINT number, const char nibbles_to_print); + +#ifndef UNITY_EXCLUDE_FLOAT_PRINT +void UnityPrintFloat(const UNITY_DOUBLE input_number); +#endif + +/*------------------------------------------------------- + * Test Assertion Functions + *------------------------------------------------------- + * Use the macros below this section instead of calling + * these directly. The macros have a consistent naming + * convention and will pull in file and line information + * for you. */ + +void UnityAssertEqualNumber(const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold, + const UNITY_INT actual, + const UNITY_COMPARISON_T compare, + const char *msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style, + const UNITY_FLAGS_T flags); + +void UnityAssertBits(const UNITY_INT mask, + const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualString(const char* expected, + const char* actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualStringLen(const char* expected, + const char* actual, + const UNITY_UINT32 length, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualStringArray( UNITY_INTERNAL_PTR expected, + const char** actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertEqualMemory( UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 length, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertNumbersWithin(const UNITY_UINT delta, + const UNITY_INT expected, + const UNITY_INT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityAssertNumbersArrayWithin(const UNITY_UINT delta, + UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style, + const UNITY_FLAGS_T flags); + +#ifndef UNITY_EXCLUDE_SETJMP_H +UNITY_NORETURN void UnityFail(const char* message, const UNITY_LINE_TYPE line); +UNITY_NORETURN void UnityIgnore(const char* message, const UNITY_LINE_TYPE line); +#else +void UnityFail(const char* message, const UNITY_LINE_TYPE line); +void UnityIgnore(const char* message, const UNITY_LINE_TYPE line); +#endif + +void UnityMessage(const char* message, const UNITY_LINE_TYPE line); + +#ifndef UNITY_EXCLUDE_FLOAT +void UnityAssertFloatsWithin(const UNITY_FLOAT delta, + const UNITY_FLOAT expected, + const UNITY_FLOAT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertFloatsNotWithin(const UNITY_FLOAT delta, + const UNITY_FLOAT expected, + const UNITY_FLOAT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertGreaterOrLessFloat(const UNITY_FLOAT threshold, + const UNITY_FLOAT actual, + const UNITY_COMPARISON_T compare, + const char* msg, + const UNITY_LINE_TYPE linenumber); + +void UnityAssertWithinFloatArray(const UNITY_FLOAT delta, + UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected, + UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertFloatSpecial(const UNITY_FLOAT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style); +#endif + +#ifndef UNITY_EXCLUDE_DOUBLE +void UnityAssertDoublesWithin(const UNITY_DOUBLE delta, + const UNITY_DOUBLE expected, + const UNITY_DOUBLE actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertDoublesNotWithin(const UNITY_DOUBLE delta, + const UNITY_DOUBLE expected, + const UNITY_DOUBLE actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertGreaterOrLessDouble(const UNITY_DOUBLE threshold, + const UNITY_DOUBLE actual, + const UNITY_COMPARISON_T compare, + const char* msg, + const UNITY_LINE_TYPE linenumber); + +void UnityAssertWithinDoubleArray(const UNITY_DOUBLE delta, + UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expected, + UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual, + const UNITY_UINT32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLAGS_T flags); + +void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style); +#endif + +/*------------------------------------------------------- + * Helpers + *-------------------------------------------------------*/ + +UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size); +#ifndef UNITY_EXCLUDE_FLOAT +UNITY_INTERNAL_PTR UnityFloatToPtr(const float num); +#endif +#ifndef UNITY_EXCLUDE_DOUBLE +UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num); +#endif + +/*------------------------------------------------------- + * Error Strings We Might Need + *-------------------------------------------------------*/ + +extern const char UnityStrOk[]; +extern const char UnityStrPass[]; +extern const char UnityStrFail[]; +extern const char UnityStrIgnore[]; + +extern const char UnityStrErrFloat[]; +extern const char UnityStrErrDouble[]; +extern const char UnityStrErr64[]; +extern const char UnityStrErrShorthand[]; + +/*------------------------------------------------------- + * Test Running Macros + *-------------------------------------------------------*/ + +#ifdef UNITY_TEST_PROTECT +#define TEST_PROTECT() UNITY_TEST_PROTECT() +#else +#ifndef UNITY_EXCLUDE_SETJMP_H +#define TEST_PROTECT() (setjmp(Unity.AbortFrame) == 0) +#else +#define TEST_PROTECT() 1 +#endif +#endif + +#ifdef UNITY_TEST_ABORT +#define TEST_ABORT() UNITY_TEST_ABORT() +#else +#ifndef UNITY_EXCLUDE_SETJMP_H +#define TEST_ABORT() longjmp(Unity.AbortFrame, 1) +#else +#define TEST_ABORT() return +#endif +#endif + +/* Automatically enable variadic macros support, if it not enabled before */ +#ifndef UNITY_SUPPORT_VARIADIC_MACROS + #ifdef __STDC_VERSION__ + #if __STDC_VERSION__ >= 199901L + #define UNITY_SUPPORT_VARIADIC_MACROS + #endif + #endif +#endif + +/* This tricky series of macros gives us an optional line argument to treat it as RUN_TEST(func, num=__LINE__) */ +#ifndef RUN_TEST +#ifdef UNITY_SUPPORT_VARIADIC_MACROS +#define RUN_TEST(...) RUN_TEST_AT_LINE(__VA_ARGS__, __LINE__, throwaway) +#define RUN_TEST_AT_LINE(func, line, ...) UnityDefaultTestRun(func, #func, line) +#endif +#endif + +/* Enable default macros for masking param tests test cases */ +#ifdef UNITY_SUPPORT_TEST_CASES + #ifdef UNITY_SUPPORT_VARIADIC_MACROS + #if !defined(TEST_CASE) && !defined(UNITY_EXCLUDE_TEST_CASE) + #define TEST_CASE(...) + #endif + #if !defined(TEST_RANGE) && !defined(UNITY_EXCLUDE_TEST_RANGE) + #define TEST_RANGE(...) + #endif + #if !defined(TEST_MATRIX) && !defined(UNITY_EXCLUDE_TEST_MATRIX) + #define TEST_MATRIX(...) + #endif + #endif +#endif + +/* If we can't do the tricky version, we'll just have to require them to always include the line number */ +#ifndef RUN_TEST +#ifdef CMOCK +#define RUN_TEST(func, num) UnityDefaultTestRun(func, #func, num) +#else +#define RUN_TEST(func) UnityDefaultTestRun(func, #func, __LINE__) +#endif +#endif + +#define TEST_LINE_NUM (Unity.CurrentTestLineNumber) +#define TEST_IS_IGNORED (Unity.CurrentTestIgnored) +#define UNITY_NEW_TEST(a) \ + Unity.CurrentTestName = (a); \ + Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)(__LINE__); \ + Unity.NumberOfTests++; + +#ifndef UNITY_BEGIN +#define UNITY_BEGIN() UnityBegin(__FILE__) +#endif + +#ifndef UNITY_END +#define UNITY_END() UnityEnd() +#endif + +#ifndef UNITY_SHORTHAND_AS_INT +#ifndef UNITY_SHORTHAND_AS_MEM +#ifndef UNITY_SHORTHAND_AS_NONE +#ifndef UNITY_SHORTHAND_AS_RAW +#define UNITY_SHORTHAND_AS_OLD +#endif +#endif +#endif +#endif + +/*----------------------------------------------- + * Command Line Argument Support + *-----------------------------------------------*/ + +#ifdef UNITY_USE_COMMAND_LINE_ARGS +int UnityParseOptions(int argc, char** argv); +int UnityTestMatches(void); +#endif + +/*------------------------------------------------------- + * Basic Fail and Ignore + *-------------------------------------------------------*/ + +#define UNITY_TEST_FAIL(line, message) UnityFail( (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_IGNORE(line, message) UnityIgnore( (message), (UNITY_LINE_TYPE)(line)) + +/*------------------------------------------------------- + * Test Asserts + *-------------------------------------------------------*/ + +#define UNITY_TEST_ASSERT(condition, line, message) do { if (condition) { /* nothing*/ } else { UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), (message)); } } while (0) +#define UNITY_TEST_ASSERT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) == NULL), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_NOT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) != NULL), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_EMPTY(pointer, line, message) UNITY_TEST_ASSERT(((pointer[0]) == 0), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_NOT_EMPTY(pointer, line, message) UNITY_TEST_ASSERT(((pointer[0]) != 0), (UNITY_LINE_TYPE)(line), (message)) + +#define UNITY_TEST_ASSERT_EQUAL_INT(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_EQUAL_INT8(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_EQUAL_INT16(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT16)(expected), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_EQUAL_INT32(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT32)(expected), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_EQUAL_UINT(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_EQUAL_UINT8(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_UINT8 )(expected), (UNITY_INT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_EQUAL_UINT16(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_UINT16)(expected), (UNITY_INT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_EQUAL_UINT32(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_UINT32)(expected), (UNITY_INT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_EQUAL_HEX8(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_EQUAL_HEX16(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT16)(expected), (UNITY_INT)(UNITY_INT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_EQUAL_HEX32(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT32)(expected), (UNITY_INT)(UNITY_INT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_EQUAL_CHAR(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(UNITY_INT8 )(expected), (UNITY_INT)(UNITY_INT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) +#define UNITY_TEST_ASSERT_BITS(mask, expected, actual, line, message) UnityAssertBits((UNITY_INT)(mask), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line)) + +#define UNITY_TEST_ASSERT_NOT_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_NOT_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_NOT_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_NOT_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_NOT_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_NOT_EQUAL_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_NOT_EQUAL_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_NOT_EQUAL_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_NOT_EQUAL_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_NOT_EQUAL_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_NOT_EQUAL_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_NOT_EQUAL_CHAR(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) + +#define UNITY_TEST_ASSERT_GREATER_THAN_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_GREATER_THAN_CHAR(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) + +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_SMALLER_THAN_CHAR(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 )(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) + +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT) (threshold), (UNITY_INT) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 ) (threshold), (UNITY_INT)(UNITY_INT8 ) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16) (threshold), (UNITY_INT)(UNITY_INT16) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32) (threshold), (UNITY_INT)(UNITY_INT32) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT) (threshold), (UNITY_INT) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 ) (threshold), (UNITY_INT)(UNITY_INT8 ) (actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) + +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT) (threshold), (UNITY_INT) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 ) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT16)(threshold), (UNITY_INT)(UNITY_INT16) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT32)(threshold), (UNITY_INT)(UNITY_INT32) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT) (threshold), (UNITY_INT) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT8 )(threshold), (UNITY_INT)(UNITY_UINT8 )(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT16)(threshold), (UNITY_INT)(UNITY_UINT16)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_UINT32)(threshold), (UNITY_INT)(UNITY_UINT32)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(UNITY_INT8 )(threshold), (UNITY_INT)(UNITY_INT8 ) (actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) + +#define UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin( (delta), (UNITY_INT) (expected), (UNITY_INT) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_INT8 ) (expected), (UNITY_INT)(UNITY_INT8 ) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_INT16) (expected), (UNITY_INT)(UNITY_INT16) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_INT32) (expected), (UNITY_INT)(UNITY_INT32) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin( (delta), (UNITY_INT) (expected), (UNITY_INT) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_UINT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_UINT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_UINT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT16)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT32)(delta), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(expected), (UNITY_INT)(UNITY_UINT)(UNITY_UINT32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_CHAR_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((UNITY_UINT8 )(delta), (UNITY_INT)(UNITY_INT8 ) (expected), (UNITY_INT)(UNITY_INT8 ) (actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR) + +#define UNITY_TEST_ASSERT_INT_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin( (delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT8 )(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT16)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT32)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin( (delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT8 )(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT16)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT32)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT8 )(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT16)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT32)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT8 )(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), ((UNITY_UINT32)(num_elements)), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR, UNITY_ARRAY_TO_ARRAY) + + +#define UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, line, message) UnityAssertEqualNumber((UNITY_PTR_TO_INT)(expected), (UNITY_PTR_TO_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER) +#define UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, line, message) UnityAssertEqualString((const char*)(expected), (const char*)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len, line, message) UnityAssertEqualStringLen((const char*)(expected), (const char*)(actual), (UNITY_UINT32)(len), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), 1, (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) + +#define UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((UNITY_INTERNAL_PTR)(expected), (const char**)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR, UNITY_ARRAY_TO_ARRAY) + +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT) (expected), (UNITY_INT_WIDTH / 8)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT16 )(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT32 )(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT) (expected), (UNITY_INT_WIDTH / 8)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT16)(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT32)(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT16 )(expected), 2), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT32 )(expected), 4), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_PTR_TO_INT) (expected), (UNITY_POINTER_WIDTH / 8)), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((UNITY_INTERNAL_PTR)(expected), (const char**)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(len), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_CHAR(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT8 )(expected), 1), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_CHAR, UNITY_ARRAY_TO_VAL) + +#ifdef UNITY_SUPPORT_64 +#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UnityAssertEqualNumber((UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)(expected), 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_UINT64)(expected), 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements, line, message) UnityAssertEqualIntArray(UnityNumToPtr((UNITY_INT)(UNITY_INT64)(expected), 8), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (UNITY_INT)(expected), (UNITY_INT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_NOT_EQUAL_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_NOT_EQUAL_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_NOT_EQUAL_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_NOT_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64(threshold, actual, line, message) UnityAssertGreaterOrLessOrEqualNumber((UNITY_INT)(threshold), (UNITY_INT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT64)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT64)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64, UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertNumbersArrayWithin((UNITY_UINT64)(delta), (UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64, UNITY_ARRAY_TO_ARRAY) +#else +#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_THAN_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_THAN_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#endif + +#ifdef UNITY_EXCLUDE_FLOAT +#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_NOT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_NOT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_GREATER_THAN_FLOAT(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_FLOAT(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_LESS_THAN_FLOAT(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_LESS_OR_EQUAL_FLOAT(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#else +#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UnityAssertFloatsWithin((UNITY_FLOAT)(delta), (UNITY_FLOAT)(expected), (UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_FLOAT_NOT_WITHIN(delta, expected, actual, line, message) UnityAssertFloatsNotWithin((UNITY_FLOAT)(delta), (UNITY_FLOAT)(expected), (UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((UNITY_FLOAT)(expected) * (UNITY_FLOAT)UNITY_FLOAT_PRECISION, (UNITY_FLOAT)(expected), (UNITY_FLOAT)(actual), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_NOT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_ASSERT_FLOAT_NOT_WITHIN((UNITY_FLOAT)(expected) * (UNITY_FLOAT)UNITY_FLOAT_PRECISION, (UNITY_FLOAT)(expected), (UNITY_FLOAT)(actual), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_FLOAT_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertWithinFloatArray((UNITY_FLOAT)(delta), (const UNITY_FLOAT*)(expected), (const UNITY_FLOAT*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UnityAssertWithinFloatArray((UNITY_FLOAT)0, (const UNITY_FLOAT*)(expected), (const UNITY_FLOAT*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements, line, message) UnityAssertWithinFloatArray((UNITY_FLOAT)0, UnityFloatToPtr(expected), (const UNITY_FLOAT*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_GREATER_THAN_FLOAT(threshold, actual, line, message) UnityAssertGreaterOrLessFloat((UNITY_FLOAT)(threshold), (UNITY_FLOAT)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_FLOAT(threshold, actual, line, message) UnityAssertGreaterOrLessFloat((UNITY_FLOAT)(threshold), (UNITY_FLOAT)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_LESS_THAN_FLOAT(threshold, actual, line, message) UnityAssertGreaterOrLessFloat((UNITY_FLOAT)(threshold), (UNITY_FLOAT)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_LESS_OR_EQUAL_FLOAT(threshold, actual, line, message) UnityAssertGreaterOrLessFloat((UNITY_FLOAT)(threshold), (UNITY_FLOAT)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) +#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_DET) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NEG_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NAN) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((UNITY_FLOAT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET) +#endif + +#ifdef UNITY_EXCLUDE_DOUBLE +#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_NOT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_NOT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_GREATER_THAN_DOUBLE(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_LESS_THAN_DOUBLE(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_LESS_OR_EQUAL_DOUBLE(threshold, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#else +#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((UNITY_DOUBLE)(delta), (UNITY_DOUBLE)(expected), (UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_DOUBLE_NOT_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesNotWithin((UNITY_DOUBLE)(delta), (UNITY_DOUBLE)(expected), (UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((UNITY_DOUBLE)(expected) * (UNITY_DOUBLE)UNITY_DOUBLE_PRECISION, (UNITY_DOUBLE)(expected), (UNITY_DOUBLE)(actual), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_NOT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_NOT_WITHIN((UNITY_DOUBLE)(expected) * (UNITY_DOUBLE)UNITY_DOUBLE_PRECISION, (UNITY_DOUBLE)(expected), (UNITY_DOUBLE)(actual), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_DOUBLE_ARRAY_WITHIN(delta, expected, actual, num_elements, line, message) UnityAssertWithinDoubleArray((UNITY_DOUBLE)(delta), (const UNITY_DOUBLE*)(expected), (const UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertWithinDoubleArray((UNITY_DOUBLE)0, (const UNITY_DOUBLE*)(expected), (const UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_ARRAY) +#define UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements, line, message) UnityAssertWithinDoubleArray((UNITY_DOUBLE)0, UnityDoubleToPtr(expected), (const UNITY_DOUBLE*)(actual), (UNITY_UINT32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_ARRAY_TO_VAL) +#define UNITY_TEST_ASSERT_GREATER_THAN_DOUBLE(threshold, actual, line, message) UnityAssertGreaterOrLessDouble((UNITY_DOUBLE)(threshold), (UNITY_DOUBLE)(actual), UNITY_GREATER_THAN, (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE(threshold, actual, line, message) UnityAssertGreaterOrLessDouble((UNITY_DOUBLE)(threshold), (UNITY_DOUBLE)(actual), UNITY_GREATER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_LESS_THAN_DOUBLE(threshold, actual, line, message) UnityAssertGreaterOrLessDouble((UNITY_DOUBLE)(threshold), (UNITY_DOUBLE)(actual), UNITY_SMALLER_THAN, (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_LESS_OR_EQUAL_DOUBLE(threshold, actual, line, message) UnityAssertGreaterOrLessDouble((UNITY_DOUBLE)(threshold), (UNITY_DOUBLE)(actual), UNITY_SMALLER_OR_EQUAL, (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) +#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_DET) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NEG_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NAN) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((UNITY_DOUBLE)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET) +#endif + +/* End of UNITY_INTERNALS_H */ +#endif From 8206ae3bf1e1ed54c692d3c8330d5b1542f17e83 Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Sun, 31 Dec 2023 02:13:10 +0000 Subject: [PATCH 03/57] Makefile unitclean --- Makefile | 2 ++ Tests/UnitTests/HelloWorld.c | 1 + Tests/UnitTests/Makefile | 1 + 3 files changed, 4 insertions(+) diff --git a/Makefile b/Makefile index cd75d056c..cc464fd59 100644 --- a/Makefile +++ b/Makefile @@ -61,6 +61,8 @@ help: @echo " excluding the file type (.c) e.g. say you want to test Voltage.c, call" @echo " ${ORANGE}make ${BLUE}stm32f413 ${ORANGE}TEST=${PURPLE}Voltage${NC}" +unitclean: + rm -fR Tests/UnitTests/Objects clean: rm -fR Objects diff --git a/Tests/UnitTests/HelloWorld.c b/Tests/UnitTests/HelloWorld.c index db8170042..281700aa5 100644 --- a/Tests/UnitTests/HelloWorld.c +++ b/Tests/UnitTests/HelloWorld.c @@ -2,6 +2,7 @@ #include "fff.h" #define MOCK_CONTACTORS #include "Contactors.h" +#include "Unity/unity.h" int main(void) { printf("\rHello world\n\r"); diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index 32a5d4c5b..e340b3e8e 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -92,6 +92,7 @@ $(BUILD_DIR)/$(TARGET).o: $(BUILD_DIR) $(TOCOMPILE).c @echo "LD $(<:../../%=%)" @$(CC) $(C_INCLUDES) $(TOCOMPILE).c -o $(BUILD_DIR)/$(TOCOMPILE).o @echo "SZ $(<:../../%=%)" + - ./$(BUILD_DIR)/$(TOCOMPILE).o #end add ^^ use to be @$(SZ) $@ From bf0c830e21ab8a7ec4ff42ace9ba83932764ab7c Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Sun, 31 Dec 2023 02:57:14 +0000 Subject: [PATCH 04/57] Unit Test for Contactors written, not working --- BSP/Inc/BSP_GPIO.h | 16 ++++++++++++++++ Drivers/Inc/Contactors.h | 2 ++ Tests/UnitTests/Makefile | 2 ++ Tests/UnitTests/Test_Contactors.c | 20 ++++++++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/BSP/Inc/BSP_GPIO.h b/BSP/Inc/BSP_GPIO.h index 66db068c4..fb11c7a8e 100644 --- a/BSP/Inc/BSP_GPIO.h +++ b/BSP/Inc/BSP_GPIO.h @@ -13,14 +13,29 @@ #define __BSP_GPIO_H #include "common.h" +#ifdef MOCK_BSP_GPIO +#include "fff.h" +#else #include "config.h" #include "stm32f4xx_gpio.h" #include #include +#endif typedef enum {PORTA = 0, PORTB, PORTC, PORTD, NUM_PORTS} port_t; typedef enum {INPUT = 0, OUTPUT} direction_t; +#ifdef MOCK_BSP_GPIO +DEFINE_FFF_GLOBALS; +FAKE_VOID_FUNC(BSP_GPIO_Write_Pin, port_t, uint16_t, bool); +FAKE_VOID_FUNC(BSP_GPIO_Init, port_t, uint16_t, direction_t); +//FAKE_VOID_FUNC3(OSMutexCreate, struct os_mutex, CPU_CHAR, OS_ERR); +FAKE_VALUE_FUNC(uint8_t,BSP_GPIO_Get_State, port_t, uint16_t ); +//FAKE_VOID_FUNC5(OSMutexPend, OS_MUTEX, OS_TICK, OS_OPT, CPU_TS, OS_ERR); +//FAKE_VOID_FUNC3(OSMutexPost, OS_MUTEX, OS_OPT, OS_ERR); +FAKE_VOID_FUNC(assertOSError, int); +#else + /** * @brief Initializes a GPIO port * @param port - port to initialize @@ -71,6 +86,7 @@ void BSP_GPIO_Write_Pin(port_t port, uint16_t pinmask, bool state); uint8_t BSP_GPIO_Get_State(port_t port, uint16_t pin); #endif +#endif /* @} */ diff --git a/Drivers/Inc/Contactors.h b/Drivers/Inc/Contactors.h index f7b6efbad..89fb70e8c 100644 --- a/Drivers/Inc/Contactors.h +++ b/Drivers/Inc/Contactors.h @@ -17,8 +17,10 @@ #else #include "config.h" #include "BSP_GPIO.h" +#ifndef MOCK_BSP_GPIO #include "stm32f4xx_gpio.h" #endif +#endif #define CONTACTORS_PORT PORTC diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index e340b3e8e..f646a57fc 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -58,6 +58,8 @@ C_INCLUDES := \ -I../../BSP/Inc \ -I../../Tests/Inc/ \ -I../../Tests/UnitTests \ +-I../../Tests/UnitTests/Unity \ +-I../../RTOS/uCOS-III-STM32F4/uCOS-III/Source \ -IInc ifeq ($(DEBUG), 1) diff --git a/Tests/UnitTests/Test_Contactors.c b/Tests/UnitTests/Test_Contactors.c index e69de29bb..034512ec6 100644 --- a/Tests/UnitTests/Test_Contactors.c +++ b/Tests/UnitTests/Test_Contactors.c @@ -0,0 +1,20 @@ +#define MOCK_BSP_GPIO +#include "unity.h" +#include "Contactors.h" + + +void setUp(void) {} + +void tearDown(void) {} + +void test_UnitTestContactors(void){ + Contactors_Set(ARRAY_PRECHARGE_BYPASS_CONTACTOR, true, true); +} + +/*=======MAIN=====*/ +int main(void) +{ + UNITY_BEGIN(); + RUN_TEST(test_UnitTestContactors); + return UNITY_END(); +} \ No newline at end of file From 409b67fc20324702421a42ff830d5f7b60a87786 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 2 Jan 2024 00:17:05 -0600 Subject: [PATCH 05/57] Changed Makefile to use variable TEST instead of TEST_LEADER since TEST_LEADER checks if there is a valid test file in the Tests folder but unit tests are kept in a different directory. Unit tests currently don't use the Test_ prefix nor do they check for a valid file, but we may want to add these features later on. --- Makefile | 4 ++-- Tests/UnitTests/Makefile | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index cc464fd59..d6fb73967 100644 --- a/Makefile +++ b/Makefile @@ -36,10 +36,10 @@ leader: @echo "${YELLOW}Compiling for leader...${NC}" $(MAKE) -C BSP -C STM32F413 -j TARGET=$(LEADER) TEST=$(TEST_LEADER) @echo "${BLUE}Compiled for leader! Jolly Good!${NC}" - + #TEST - need to add .c somehow, also no longer TEST_LEADER but we may want to check that there's a valid file first unittest: @echo "${YELLOW}Compiling unit test...${NC}" - $(MAKE) -C Tests -C UnitTests -j TARGET=$(LEADER) TEST=$(TEST_LEADER) + $(MAKE) -C Tests -C UnitTests -j TARGET=$(LEADER) TEST=$(TEST) @echo "${BLUE}Compiled unit test! Jolly Good!${NC}" flash: diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index f646a57fc..70fec0ede 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -6,8 +6,10 @@ BUILD_DIR = Objects#../../Objects # source # changed to -C_SOURCES = \ -../$(TEST) +# since current path is in the BSP folder, go to the top level with ../../ +# C_SOURCES = \ +# $(wildcard ../../Drivers/Src/*.c) \ +# $(filter-out ../../Apps/Src/main.c, $(wildcard ../../Apps/Src/*.c)) ####################################### # binaries @@ -86,7 +88,7 @@ OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) vpath %.s $(sort $(dir $(ASM_SOURCES))) ##Added -TOCOMPILE := $(TEST_LEADER) +TOCOMPILE := $(TEST) ## # @$(CC) $(OBJECTS) -o $@ #added From e33eee126a4b8cc48c36fc59eaae7592cd1438a0 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 2 Jan 2024 19:25:40 -0600 Subject: [PATCH 06/57] C Source looks for the right (hopefully) file, also added mocking flag for ifdefs to see if it helps with including files. --- Makefile | 10 +++++++++- Tests/UnitTests/Makefile | 25 +++++++++++++++---------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index d6fb73967..2253db72c 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,13 @@ else TEST_LEADER ?= Apps/Src/main.c endif +#Check if unit test file exists (and yes we don't use unittest right now but maybe we will in the future) +ifneq (,$(wildcard Tests/UnitTests/Test_$(TEST).c)) + UNITTEST ?= Tests/UnitTests/Test_$(TEST).c +else + UNITTEST ?= no test found +endif + LEADER = controls-leader all: @@ -39,7 +46,8 @@ leader: #TEST - need to add .c somehow, also no longer TEST_LEADER but we may want to check that there's a valid file first unittest: @echo "${YELLOW}Compiling unit test...${NC}" - $(MAKE) -C Tests -C UnitTests -j TARGET=$(LEADER) TEST=$(TEST) + echo "$(UNITTEST)" + $(MAKE) -C Tests -C UnitTests -j TARGET=$(LEADER) TEST=$(TEST) @echo "${BLUE}Compiled unit test! Jolly Good!${NC}" flash: diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index 70fec0ede..a52b05e19 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -7,9 +7,9 @@ BUILD_DIR = Objects#../../Objects # changed to # since current path is in the BSP folder, go to the top level with ../../ -# C_SOURCES = \ -# $(wildcard ../../Drivers/Src/*.c) \ -# $(filter-out ../../Apps/Src/main.c, $(wildcard ../../Apps/Src/*.c)) +C_SOURCES = $(wildcard ../../*/Src/$(TEST).c) \ +$(wildcard Stubs/*.c) +#echo "$(C_SOURCE) is c source" ####################################### # binaries @@ -59,11 +59,12 @@ C_INCLUDES := \ -I../../Config/Inc \ -I../../BSP/Inc \ -I../../Tests/Inc/ \ --I../../Tests/UnitTests \ --I../../Tests/UnitTests/Unity \ --I../../RTOS/uCOS-III-STM32F4/uCOS-III/Source \ --IInc - +-I../../Tests/UnitTests \ +-I../../Tests/UnitTests/Unity \ +-I../../BSP/STM32F413/STM32F4xx_StdPeriph_Driver/Inc \ +-I../../RTOS/uCOS-III-STM32F4/uCOS-III/Source \ +-IInc + ifeq ($(DEBUG), 1) CFLAGS += -g3 -gdwarf-2 -DDEBUG endif @@ -76,6 +77,9 @@ ifeq ($(CAR_LOOPBACK), 1) CFLAGS += -DCAR_LOOPBACK endif + MOCKING=1 + export MOCKING + CFLAGS += -DMOCKING ####################################### # build the application @@ -88,13 +92,14 @@ OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) vpath %.s $(sort $(dir $(ASM_SOURCES))) ##Added -TOCOMPILE := $(TEST) +TOCOMPILE := Test_$(TEST) ## # @$(CC) $(OBJECTS) -o $@ #added $(BUILD_DIR)/$(TARGET).o: $(BUILD_DIR) $(TOCOMPILE).c @echo "LD $(<:../../%=%)" - @$(CC) $(C_INCLUDES) $(TOCOMPILE).c -o $(BUILD_DIR)/$(TOCOMPILE).o + @echo "Mocking is $(MOCKING)" + @$(CC) $(CFLAGS) $(C_INCLUDES) $(TOCOMPILE).c $(C_SOURCES) -o $(BUILD_DIR)/$(TOCOMPILE).o @echo "SZ $(<:../../%=%)" - ./$(BUILD_DIR)/$(TOCOMPILE).o From 2aa882cbfd5221e5b53712ec587dd3dfb65f5921 Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Thu, 4 Jan 2024 21:34:54 +0000 Subject: [PATCH 07/57] working pedals and contactors without OS mocking --- .vscode/LHR.code-workspace | 13 ++++++++ BSP/Inc/BSP_ADC.h | 19 ++++++++--- BSP/Inc/BSP_GPIO.h | 13 ++++---- BSP/STM32F413/Makefile | 8 ----- BSP/STM32F413/Src/BSP_ADC.c | 16 +++++++-- BSP/STM32F413/Src/BSP_GPIO.c | 17 +++++++++- Drivers/Inc/Contactors.h | 18 +++------- Drivers/Inc/Pedals.h | 10 +++--- Drivers/Src/Contactors.c | 31 ++++++++--------- Drivers/Src/Pedals.c | 3 +- Makefile | 8 +++-- Tests/UnitTests/HelloWorld.c | 18 ---------- Tests/UnitTests/Makefile | 55 +++++++++++++++++++++++++++---- Tests/UnitTests/Test_Contactors.c | 38 ++++++++++++++++++--- Tests/UnitTests/Test_Pedals.c | 41 +++++++++++++++++++++++ 15 files changed, 218 insertions(+), 90 deletions(-) delete mode 100644 Tests/UnitTests/HelloWorld.c create mode 100644 Tests/UnitTests/Test_Pedals.c diff --git a/.vscode/LHR.code-workspace b/.vscode/LHR.code-workspace index 9e5310e01..1db206007 100644 --- a/.vscode/LHR.code-workspace +++ b/.vscode/LHR.code-workspace @@ -17,6 +17,19 @@ "args": ["-i"] }, }, + "files.associations": { + "*.db": "sql", + "contactors.h": "c", + "pedals.h": "c", + "bsp_adc.h": "c", + "config.h": "c", + "unity.h": "c", + "fff.h": "c", + "common.h": "c", + "stdio.h": "c", + "stm32f4xx.h": "c", + "bsp_gpio.h": "c" + }, }, "tasks": { "version": "2.0.0", diff --git a/BSP/Inc/BSP_ADC.h b/BSP/Inc/BSP_ADC.h index 33ccd47b4..20ce8213b 100644 --- a/BSP/Inc/BSP_ADC.h +++ b/BSP/Inc/BSP_ADC.h @@ -11,8 +11,10 @@ #ifndef __BSP_ADC_H #define __BSP_ADC_H - +#define MOCK_BSP_ADC +#ifndef MOCK_BSP_ADC #include "bsp.h" +#endif #include "common.h" #include "config.h" @@ -27,27 +29,34 @@ typedef enum NUMBER_OF_CHANNELS } ADC_t; +#ifdef MOCKING +#include "fff.h" +DECLARE_FAKE_VOID_FUNC(BSP_ADC_Init); +DECLARE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Millivoltage, int); +DECLARE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Value, int); +#else + /** * @brief Initialize the ADC module * @return None */ -void BSP_ADC_Init(void); +extern void BSP_ADC_Init(void); /** * @brief Provides the ADC value of the channel at the specified index * @param hardwareDevice pedal enum that represents the specific device * @return Raw ADC value without conversion */ -int16_t BSP_ADC_Get_Value(ADC_t hardwareDevice); +extern int16_t BSP_ADC_Get_Value(ADC_t hardwareDevice); /** * @brief Provides the ADC value in millivolts of the channel at the specified index * @param hardwareDevice pedal enum that represents the specific device * @return ADC value in millivolts */ -int16_t BSP_ADC_Get_Millivoltage(ADC_t hardwareDevice); +extern int16_t BSP_ADC_Get_Millivoltage(ADC_t hardwareDevice); #endif - +#endif /* @} */ diff --git a/BSP/Inc/BSP_GPIO.h b/BSP/Inc/BSP_GPIO.h index fb11c7a8e..5167b64f4 100644 --- a/BSP/Inc/BSP_GPIO.h +++ b/BSP/Inc/BSP_GPIO.h @@ -13,7 +13,7 @@ #define __BSP_GPIO_H #include "common.h" -#ifdef MOCK_BSP_GPIO +#ifdef MOCKING #include "fff.h" #else #include "config.h" @@ -25,15 +25,14 @@ typedef enum {PORTA = 0, PORTB, PORTC, PORTD, NUM_PORTS} port_t; typedef enum {INPUT = 0, OUTPUT} direction_t; -#ifdef MOCK_BSP_GPIO -DEFINE_FFF_GLOBALS; -FAKE_VOID_FUNC(BSP_GPIO_Write_Pin, port_t, uint16_t, bool); -FAKE_VOID_FUNC(BSP_GPIO_Init, port_t, uint16_t, direction_t); +#ifdef MOCKING +DECLARE_FAKE_VOID_FUNC(BSP_GPIO_Write_Pin, port_t, uint16_t, bool); +DECLARE_FAKE_VOID_FUNC(BSP_GPIO_Init, port_t, uint16_t, direction_t); //FAKE_VOID_FUNC3(OSMutexCreate, struct os_mutex, CPU_CHAR, OS_ERR); -FAKE_VALUE_FUNC(uint8_t,BSP_GPIO_Get_State, port_t, uint16_t ); +DECLARE_FAKE_VALUE_FUNC(uint8_t,BSP_GPIO_Get_State, port_t, uint16_t ); //FAKE_VOID_FUNC5(OSMutexPend, OS_MUTEX, OS_TICK, OS_OPT, CPU_TS, OS_ERR); //FAKE_VOID_FUNC3(OSMutexPost, OS_MUTEX, OS_OPT, OS_ERR); -FAKE_VOID_FUNC(assertOSError, int); +DECLARE_FAKE_VOID_FUNC(assertOSError, int); #else /** diff --git a/BSP/STM32F413/Makefile b/BSP/STM32F413/Makefile index 62a2a6274..0f26a319e 100644 --- a/BSP/STM32F413/Makefile +++ b/BSP/STM32F413/Makefile @@ -41,11 +41,6 @@ C_SOURCES += \ $(filter-out ../../Apps/Src/main.c, $(wildcard ../../Apps/Src/*.c)) \ ../../$(TEST) -# ASM sources -ASM_SOURCES = \ -../../BSP/STM32F413/Src/startup_stm32f413xx.s \ -../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/os_cpu_a.s \ -../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/cpu_a.s ####################################### @@ -155,9 +150,6 @@ all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET # list of objects OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) vpath %.c $(sort $(dir $(C_SOURCES))) -# list of ASM program objects -OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) -vpath %.s $(sort $(dir $(ASM_SOURCES))) $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) @echo "CC $(<:../../%=%)" diff --git a/BSP/STM32F413/Src/BSP_ADC.c b/BSP/STM32F413/Src/BSP_ADC.c index f49dac17b..23980d3a4 100644 --- a/BSP/STM32F413/Src/BSP_ADC.c +++ b/BSP/STM32F413/Src/BSP_ADC.c @@ -1,7 +1,16 @@ /* Copyright (c) 2020 UT Longhorn Racing Solar */ #include "BSP_ADC.h" -#include "stm32f4xx.h" +//#include "stm32f4xx.h" + + + +#ifdef MOCKING +//DEFINE_FFF_GLOBALS; +DEFINE_FAKE_VOID_FUNC(BSP_ADC_Init); +DEFINE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Millivoltage, int); +DEFINE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Value, int); +#else static volatile uint16_t ADCresults[2]; @@ -39,7 +48,7 @@ static void ADC_InitDMA(void) { * @param None * @return None */ -void BSP_ADC_Init(void) { +static void BSP_ADC_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // Enable the ADC clock RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); // Enable the PC clock for port C @@ -113,3 +122,6 @@ int16_t BSP_ADC_Get_Millivoltage(ADC_t hardwareDevice) { // Convert to millivoltage return (ADC_RANGE_MILLIVOLTS * data) >> ADC_PRECISION_BITS; } + + +#endif \ No newline at end of file diff --git a/BSP/STM32F413/Src/BSP_GPIO.c b/BSP/STM32F413/Src/BSP_GPIO.c index ffd20a800..bcbbb3338 100755 --- a/BSP/STM32F413/Src/BSP_GPIO.c +++ b/BSP/STM32F413/Src/BSP_GPIO.c @@ -1,7 +1,21 @@ /* Copyright (c) 2021 UT Longhorn Racing Solar */ #include "BSP_GPIO.h" -#include "Tasks.h" +//#include "Tasks.h" + +#ifdef MOCKING +#include "fff.h" +DEFINE_FFF_GLOBALS; +DEFINE_FAKE_VOID_FUNC(BSP_GPIO_Write_Pin, port_t, uint16_t, bool); +DEFINE_FAKE_VOID_FUNC(BSP_GPIO_Init, port_t, uint16_t, direction_t); +//FAKE_VOID_FUNC3(OSMutexCreate, struct os_mutex, CPU_CHAR, OS_ERR); +DEFINE_FAKE_VALUE_FUNC(uint8_t,BSP_GPIO_Get_State, port_t, uint16_t ); +//FAKE_VOID_FUNC5(OSMutexPend, OS_MUTEX, OS_TICK, OS_OPT, CPU_TS, OS_ERR); +//FAKE_VOID_FUNC3(OSMutexPost, OS_MUTEX, OS_OPT, OS_ERR); +DEFINE_FAKE_VOID_FUNC(assertOSError, int); +#else + + static GPIO_TypeDef* GPIO_GetPort(port_t port){ const GPIO_TypeDef* gpio_mapping[4] = {GPIOA, GPIOB, GPIOC, GPIOD}; @@ -108,3 +122,4 @@ uint8_t BSP_GPIO_Get_State(port_t port, uint16_t pin){ return GPIO_ReadOutputDataBit(gpio_port, pin); } +#endif \ No newline at end of file diff --git a/Drivers/Inc/Contactors.h b/Drivers/Inc/Contactors.h index 89fb70e8c..d15bc864d 100644 --- a/Drivers/Inc/Contactors.h +++ b/Drivers/Inc/Contactors.h @@ -12,15 +12,12 @@ #define __CONTACTORS_H #include "common.h" -#ifdef MOCK_CONTACTORS ///////////////////////////////// #include "fff.h" -#else #include "config.h" #include "BSP_GPIO.h" -#ifndef MOCK_BSP_GPIO -#include "stm32f4xx_gpio.h" -#endif -#endif +//#include "stm32f4xx_gpio.h" +#define GPIO_Pin_10 ((uint16_t)0x0400) /* Pin 10 selected */ +#define GPIO_Pin_12 ((uint16_t)0x0400) /* Pin 10 selected */ #define CONTACTORS_PORT PORTC @@ -37,12 +34,7 @@ typedef enum contactor_ENUM { }contactor_t; -#ifdef MOCK_CONTACTORS -DEFINE_FFF_GLOBALS; -FAKE_VOID_FUNC(Contactors_Init); -FAKE_VALUE_FUNC(bool, Contactors_Get, contactor_t); -FAKE_VALUE_FUNC(bool, Contactors_Set, contactor_t, bool, bool); -#else + /** * @brief Initializes contactors to be used * in connection with the Motor and Array @@ -68,7 +60,5 @@ bool Contactors_Get(contactor_t contactor); */ ErrorStatus Contactors_Set(contactor_t contactor, bool state, bool blocking); #endif -#endif - /* @} */ diff --git a/Drivers/Inc/Pedals.h b/Drivers/Inc/Pedals.h index 365180e10..4363d8053 100644 --- a/Drivers/Inc/Pedals.h +++ b/Drivers/Inc/Pedals.h @@ -11,6 +11,8 @@ #ifndef __PEDALS_H #define __PEDALS_H +#include +#include #include "BSP_ADC.h" /** @@ -29,17 +31,15 @@ typedef enum * @param None * @return None */ -void Pedals_Init(void); + void Pedals_Init(void); /** * @brief Provides the pedal distance pressed in percetage (accelerator or brake) * @param pedal_t pedal, ACCELERATOR or BRAKE as defined in enum * @return distance the pedal has been pressed in percentage */ -int8_t Pedals_Read(pedal_t pedal); - + int8_t Pedals_Read(pedal_t pedal); #endif - -/* @} */ +/* @ */ diff --git a/Drivers/Src/Contactors.c b/Drivers/Src/Contactors.c index 66ec45e0f..6b631a4c9 100644 --- a/Drivers/Src/Contactors.c +++ b/Drivers/Src/Contactors.c @@ -6,10 +6,11 @@ */ #include "Contactors.h" -#include "stm32f4xx_gpio.h" -#include "Tasks.h" +//#include "stm32f4xx_gpio.h" +//#include "Tasks.h" -static OS_MUTEX contactorsMutex; + +//static OS_MUTEX contactorsMutex; /** * @brief Helper function for setting contactors without mutex. @@ -49,9 +50,9 @@ void Contactors_Init() { } // initialize mutex - OS_ERR err; - OSMutexCreate(&contactorsMutex, "Contactors lock", &err); - assertOSError(err); + //OS_ERR err; + //OSMutexCreate(&contactorsMutex, "Contactors lock", &err); + // assertOSError(err); } /** @@ -86,17 +87,17 @@ bool Contactors_Get(contactor_t contactor) { * @return Whether or not the contactor was successfully set */ ErrorStatus Contactors_Set(contactor_t contactor, bool state, bool blocking) { - CPU_TS timestamp; - OS_ERR err; + //CPU_TS timestamp; + //OS_ERR err; ErrorStatus result = ERROR; // acquire lock if its available - OSMutexPend(&contactorsMutex, 0, blocking ? OS_OPT_PEND_BLOCKING : OS_OPT_PEND_NON_BLOCKING, ×tamp, &err); + //OSMutexPend(&contactorsMutex, 0, blocking ? OS_OPT_PEND_BLOCKING : OS_OPT_PEND_NON_BLOCKING, ×tamp, &err); - if(err == OS_ERR_PEND_WOULD_BLOCK){ - return ERROR; - } - assertOSError(err); + //if(err == OS_ERR_PEND_WOULD_BLOCK){ + // return ERROR; + // } + // assertOSError(err); // change contactor to match state and make sure it worked setContactor(contactor, state); @@ -104,8 +105,8 @@ ErrorStatus Contactors_Set(contactor_t contactor, bool state, bool blocking) { result = (ret == state) ? SUCCESS: ERROR; // release lock - OSMutexPost(&contactorsMutex, OS_OPT_POST_NONE, &err); - assertOSError(err); + // OSMutexPost(&contactorsMutex, OS_OPT_POST_NONE, &err); + // assertOSError(err); return result; } diff --git a/Drivers/Src/Pedals.c b/Drivers/Src/Pedals.c index e28397fdf..bab2e0e58 100755 --- a/Drivers/Src/Pedals.c +++ b/Drivers/Src/Pedals.c @@ -6,10 +6,11 @@ */ #include "Pedals.h" - +#include "BSP_ADC.h" // Constants used to tune the pedals // Indexed using pedal_t // Refine in testing + static const int16_t LowerBound[NUMBER_OF_PEDALS] = { 400, // Accelerator lower bound 2100, // Brake lower bound diff --git a/Makefile b/Makefile index 2253db72c..ab37ff1f5 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ leader: #TEST - need to add .c somehow, also no longer TEST_LEADER but we may want to check that there's a valid file first unittest: @echo "${YELLOW}Compiling unit test...${NC}" - echo "$(UNITTEST)" + @echo "$(UNITTEST)" $(MAKE) -C Tests -C UnitTests -j TARGET=$(LEADER) TEST=$(TEST) @echo "${BLUE}Compiled unit test! Jolly Good!${NC}" @@ -70,10 +70,12 @@ help: @echo " ${ORANGE}make ${BLUE}stm32f413 ${ORANGE}TEST=${PURPLE}Voltage${NC}" unitclean: - rm -fR Tests/UnitTests/Objects + clean: + rm -fR Tests/UnitTests/Objects rm -fR Objects rm -f *.out rm -fr Docs/doxygen - rm -fr Docs/build \ No newline at end of file + rm -fr Docs/build + \ No newline at end of file diff --git a/Tests/UnitTests/HelloWorld.c b/Tests/UnitTests/HelloWorld.c deleted file mode 100644 index 281700aa5..000000000 --- a/Tests/UnitTests/HelloWorld.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include "fff.h" -#define MOCK_CONTACTORS -#include "Contactors.h" -#include "Unity/unity.h" - -int main(void) { - printf("\rHello world\n\r"); - Contactors_Init(); - printf("\n\rHello world?\n\r"); - bool x = Contactors_Get(ARRAY_PRECHARGE_BYPASS_CONTACTOR); - printf("\n\rHello world!\n\r"); - Contactors_Set(ARRAY_PRECHARGE_BYPASS_CONTACTOR, false, true); - printf("\n\rHello world...\n\r"); - - printf("\n\rCall argument for set: %d\n\r", Contactors_Set_fake.arg1_history[0]); - printf("\n\rHello world~\n\r"); -} \ No newline at end of file diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index a52b05e19..b5be3675a 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -1,3 +1,14 @@ +# COLORS +RED=\033[0;31m +GREEN=\033[0;32m +ORANGE=\033[0;33m +BLUE=\033[0;34m +PURPLE=\033[0;35m +CYAN=\033[0;36m +LIGHTGRAY=\033[0;37m +DARKGRAY=\033[1;30m +YELLOW=\033[0;33m +NC=\033[0m # No Color # Build path BUILD_DIR = Objects#../../Objects @@ -5,10 +16,18 @@ BUILD_DIR = Objects#../../Objects ###################################### # source -# changed to -# since current path is in the BSP folder, go to the top level with ../../ -C_SOURCES = $(wildcard ../../*/Src/$(TEST).c) \ -$(wildcard Stubs/*.c) +# C sources changed to + +C_SOURCES = \ +$(wildcard ../../*/Src/$(TEST).c) \ +Unity/unity.c \ +../../BSP/STM32F413/Src/BSP_GPIO.c \ +../../BSP/STM32F413/Src/BSP_ADC.c + + +$(foreach src,$(C_SOURCES),$(info --- $(src))) + +#$(wildcard Stubs/*.c) #echo "$(C_SOURCE) is c source" ####################################### @@ -61,8 +80,6 @@ C_INCLUDES := \ -I../../Tests/Inc/ \ -I../../Tests/UnitTests \ -I../../Tests/UnitTests/Unity \ --I../../BSP/STM32F413/STM32F4xx_StdPeriph_Driver/Inc \ --I../../RTOS/uCOS-III-STM32F4/uCOS-III/Source \ -IInc ifeq ($(DEBUG), 1) @@ -96,12 +113,36 @@ TOCOMPILE := Test_$(TEST) ## # @$(CC) $(OBJECTS) -o $@ #added -$(BUILD_DIR)/$(TARGET).o: $(BUILD_DIR) $(TOCOMPILE).c +$(BUILD_DIR)/$(TOCOMPILE).o: $(BUILD_DIR) $(TOCOMPILE).c @echo "LD $(<:../../%=%)" @echo "Mocking is $(MOCKING)" @$(CC) $(CFLAGS) $(C_INCLUDES) $(TOCOMPILE).c $(C_SOURCES) -o $(BUILD_DIR)/$(TOCOMPILE).o @echo "SZ $(<:../../%=%)" - ./$(BUILD_DIR)/$(TOCOMPILE).o + + +# $(BUILD_DIR)/$(TOCOMPILE).o: $(TOCOMPILE).c Makefile | $(BUILD_DIR) +# @echo "CC $(<:../../%=%)" +# @$(CC) $(C_INCLUDES) -c $(CFLAGS) $< -o $@ +# - ./$(BUILD_DIR)/$(TOCOMPILE).o + +# $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) +# @echo "AS $(<:../../%=%)" +# @$(AS) -c $(CFLAGS) $< -o $@ + +# $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile +# @echo "LD $(<:../../%=%)" +# @$(CC) $(OBJECTS) $(LDFLAGS) -o $@ +# @echo "SZ $(<:../../%=%)" +# @$(SZ) $@ + +# $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) +# @echo "HEX $(<:../../%=%)" +# @$(HEX) $< $@ + +# $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) +# @echo "BIN $(<:../../%=%)" +# @$(BIN) $< $@ #end add ^^ use to be @$(SZ) $@ diff --git a/Tests/UnitTests/Test_Contactors.c b/Tests/UnitTests/Test_Contactors.c index 034512ec6..d3c9bef60 100644 --- a/Tests/UnitTests/Test_Contactors.c +++ b/Tests/UnitTests/Test_Contactors.c @@ -1,5 +1,10 @@ -#define MOCK_BSP_GPIO +////////////////////////////////////////// +////////////////////////////////////////// +// Unity required for this testing format #include "unity.h" +////////////////////////////////////////// +////////////////////////////////////////// +// The header file we are unit testing: #include "Contactors.h" @@ -7,14 +12,39 @@ void setUp(void) {} void tearDown(void) {} -void test_UnitTestContactors(void){ - Contactors_Set(ARRAY_PRECHARGE_BYPASS_CONTACTOR, true, true); +void test_UnitTestContactors_Init(void){ + Contactors_Init(); } +void test_UnitTestContactors_Get(void){ + // Contactors_Get(1); + BSP_GPIO_Get_State_fake.return_val = 1; + printf("VALUE:%d\n", Contactors_Get(1)); + + BSP_GPIO_Get_State_fake.return_val = 0; + printf("VALUE:%d\n", Contactors_Get(1)); + for(int x = 500; x < 1000; x+=100){ + + } +} + +void test_UnitTestContactors_Set(void){ + printf("VALUE:%d\n", Contactors_Set(ARRAY_PRECHARGE_BYPASS_CONTACTOR, 1, 1)); + + BSP_GPIO_Get_State_fake.return_val = 1; + printf("VALUE:%d\n", Contactors_Set(ARRAY_PRECHARGE_BYPASS_CONTACTOR, 1, 1)); + + +} + + + /*=======MAIN=====*/ int main(void) { UNITY_BEGIN(); - RUN_TEST(test_UnitTestContactors); + RUN_TEST(test_UnitTestContactors_Init); + RUN_TEST(test_UnitTestContactors_Get); + RUN_TEST(test_UnitTestContactors_Set); return UNITY_END(); } \ No newline at end of file diff --git a/Tests/UnitTests/Test_Pedals.c b/Tests/UnitTests/Test_Pedals.c new file mode 100644 index 000000000..87edbdafa --- /dev/null +++ b/Tests/UnitTests/Test_Pedals.c @@ -0,0 +1,41 @@ +////////////////////////////////////////// +////////////////////////////////////////// +// Unity required for this testing format +#include "unity.h" +////////////////////////////////////////// +////////////////////////////////////////// +// The header file we are unit testing: +#include "Pedals.h" + + +void setUp(void) {} + +void tearDown(void) {} + +void test_UnitTestPedals_Init(void){ + Pedals_Init(); +} + +void test_UnitTestPedals_Read(void){ + for(int x = 500; x < 1000; x+=100){ + BSP_ADC_Get_Millivoltage_fake.return_val = x; + Pedals_Read(ACCELERATOR); + //printf("\n\r%d\r", Pedals_Read(ACCELERATOR)); + } +} + +void test_UnitTestPedals_Read_This_Will_Fail(void){ + TEST_ASSERT_EQUAL(Pedals_Read(ACCELERATOR), 30); +} + + + +/*=======MAIN=====*/ +int main(void) +{ + UNITY_BEGIN(); + RUN_TEST(test_UnitTestPedals_Init); + RUN_TEST(test_UnitTestPedals_Read); + RUN_TEST(test_UnitTestPedals_Read_This_Will_Fail); + return UNITY_END(); +} \ No newline at end of file From 9f4bb42f341ed95c062b2976c152fa7401151bbf Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Sat, 6 Jan 2024 21:03:06 +0000 Subject: [PATCH 08/57] Created Mock folder structure and reflected restructure in the makefile --- BSP/STM32F413/Src/BSP_ADC.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BSP/STM32F413/Src/BSP_ADC.c b/BSP/STM32F413/Src/BSP_ADC.c index 23980d3a4..d79af7c9c 100644 --- a/BSP/STM32F413/Src/BSP_ADC.c +++ b/BSP/STM32F413/Src/BSP_ADC.c @@ -1,7 +1,7 @@ /* Copyright (c) 2020 UT Longhorn Racing Solar */ #include "BSP_ADC.h" -//#include "stm32f4xx.h" +#include "stm32f4xx.h" From e122e69112368160a07452ea6c33c414ccfd13b8 Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Sat, 6 Jan 2024 21:03:52 +0000 Subject: [PATCH 09/57] Created Mock folder structure and reflected restructure in the makefile and also life Co-authored-by: Madeleine Lee --- BSP/Inc/BSP_ADC.h | 8 ++++---- BSP/STM32F413/Src/BSP_ADC.c | 5 +---- Drivers/Inc/Contactors.h | 5 +---- Tests/UnitTests/Makefile | 14 +++++++++----- Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h | 12 ++++++++++++ Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c | 0 Tests/UnitTests/{ => Tests}/Test_Contactors.c | 0 Tests/UnitTests/{ => Tests}/Test_Pedals.c | 0 8 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h create mode 100644 Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c rename Tests/UnitTests/{ => Tests}/Test_Contactors.c (100%) rename Tests/UnitTests/{ => Tests}/Test_Pedals.c (100%) diff --git a/BSP/Inc/BSP_ADC.h b/BSP/Inc/BSP_ADC.h index 20ce8213b..9b133b299 100644 --- a/BSP/Inc/BSP_ADC.h +++ b/BSP/Inc/BSP_ADC.h @@ -13,8 +13,8 @@ #define __BSP_ADC_H #define MOCK_BSP_ADC #ifndef MOCK_BSP_ADC -#include "bsp.h" #endif +#include "bsp.h" #include "common.h" #include "config.h" @@ -40,21 +40,21 @@ DECLARE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Value, int); * @brief Initialize the ADC module * @return None */ -extern void BSP_ADC_Init(void); +void BSP_ADC_Init(void); /** * @brief Provides the ADC value of the channel at the specified index * @param hardwareDevice pedal enum that represents the specific device * @return Raw ADC value without conversion */ -extern int16_t BSP_ADC_Get_Value(ADC_t hardwareDevice); +int16_t BSP_ADC_Get_Value(ADC_t hardwareDevice); /** * @brief Provides the ADC value in millivolts of the channel at the specified index * @param hardwareDevice pedal enum that represents the specific device * @return ADC value in millivolts */ -extern int16_t BSP_ADC_Get_Millivoltage(ADC_t hardwareDevice); +int16_t BSP_ADC_Get_Millivoltage(ADC_t hardwareDevice); #endif #endif diff --git a/BSP/STM32F413/Src/BSP_ADC.c b/BSP/STM32F413/Src/BSP_ADC.c index d79af7c9c..51737d4b0 100644 --- a/BSP/STM32F413/Src/BSP_ADC.c +++ b/BSP/STM32F413/Src/BSP_ADC.c @@ -6,10 +6,7 @@ #ifdef MOCKING -//DEFINE_FFF_GLOBALS; -DEFINE_FAKE_VOID_FUNC(BSP_ADC_Init); -DEFINE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Millivoltage, int); -DEFINE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Value, int); + #else static volatile uint16_t ADCresults[2]; diff --git a/Drivers/Inc/Contactors.h b/Drivers/Inc/Contactors.h index d15bc864d..7ccaaabef 100644 --- a/Drivers/Inc/Contactors.h +++ b/Drivers/Inc/Contactors.h @@ -12,12 +12,9 @@ #define __CONTACTORS_H #include "common.h" -#include "fff.h" #include "config.h" #include "BSP_GPIO.h" -//#include "stm32f4xx_gpio.h" -#define GPIO_Pin_10 ((uint16_t)0x0400) /* Pin 10 selected */ -#define GPIO_Pin_12 ((uint16_t)0x0400) /* Pin 10 selected */ +#include "stm32f4xx_gpio.h" #define CONTACTORS_PORT PORTC diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index b5be3675a..0b746bf36 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -17,12 +17,13 @@ BUILD_DIR = Objects#../../Objects # source # C sources changed to - +# Need to include test, unity, source file for the test, mock c functions minus source file for test C_SOURCES = \ -$(wildcard ../../*/Src/$(TEST).c) \ +Tests/Test_$(TEST).c \ Unity/unity.c \ -../../BSP/STM32F413/Src/BSP_GPIO.c \ -../../BSP/STM32F413/Src/BSP_ADC.c +$(wildcard ../../*/Src/$(TEST).c) \ +$(filter-out $(wildcard Mocks/*/Src/$(TEST).c), $(wildcard Mocks/*/Src/*)) + $(foreach src,$(C_SOURCES),$(info --- $(src))) @@ -70,9 +71,10 @@ SF = st-flash # AS includes -#AS_INCLUDES = #co +#AS_INCLUDES = #co TEST=Pedals -> include Pedals.c and Pedals.h C_INCLUDES := \ +$(filter-out $(wildcard Mocks/*/$(TEST).h), $(wildcard Mocks/*/Inc)) \ -I../../Apps/Inc \ -I../../Drivers/Inc \ -I../../Config/Inc \ @@ -81,6 +83,8 @@ C_INCLUDES := \ -I../../Tests/UnitTests \ -I../../Tests/UnitTests/Unity \ -IInc +$(foreach src,$(C_INCLUDES),$(info --- $(src))) + ifeq ($(DEBUG), 1) CFLAGS += -g3 -gdwarf-2 -DDEBUG diff --git a/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h b/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h new file mode 100644 index 000000000..c843a89f0 --- /dev/null +++ b/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h @@ -0,0 +1,12 @@ +#ifndef __BSP_ADC_H +#define __BSP_ADC_H + +#include "common.h" + + +DEFINE_FFF_GLOBALS; +DECLARE_FAKE_VOID_FUNC(BSP_ADC_Init); +DECLARE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Millivoltage, int); +DECLARE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Value, int); + +#endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c b/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c new file mode 100644 index 000000000..e69de29bb diff --git a/Tests/UnitTests/Test_Contactors.c b/Tests/UnitTests/Tests/Test_Contactors.c similarity index 100% rename from Tests/UnitTests/Test_Contactors.c rename to Tests/UnitTests/Tests/Test_Contactors.c diff --git a/Tests/UnitTests/Test_Pedals.c b/Tests/UnitTests/Tests/Test_Pedals.c similarity index 100% rename from Tests/UnitTests/Test_Pedals.c rename to Tests/UnitTests/Tests/Test_Pedals.c From eb426b73532d4dbb5403f4c945f5fc023bd42d27 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 6 Jan 2024 16:01:43 -0600 Subject: [PATCH 10/57] Moved fff globals and fff.h files in BSP_ADC test files, small fix to makefile, made a new Test_Pedals.c in UnitTests as a temporary file to make it compile since the makefile can't seem to find the test in the Tests folder. --- Tests/UnitTests/Makefile | 9 +++++++-- Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h | 3 ++- Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c | 8 ++++++++ Tests/UnitTests/Test_Pedals.c | 1 + 4 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 Tests/UnitTests/Test_Pedals.c diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index 0b746bf36..9e1386446 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -22,7 +22,7 @@ C_SOURCES = \ Tests/Test_$(TEST).c \ Unity/unity.c \ $(wildcard ../../*/Src/$(TEST).c) \ -$(filter-out $(wildcard Mocks/*/Src/$(TEST).c), $(wildcard Mocks/*/Src/*)) +$(filter-out $(wildcard Mocks/*/Src/$(TEST).c), $(wildcard Mocks/*/Src/*.c)) @@ -74,7 +74,7 @@ SF = st-flash #AS_INCLUDES = #co TEST=Pedals -> include Pedals.c and Pedals.h C_INCLUDES := \ -$(filter-out $(wildcard Mocks/*/$(TEST).h), $(wildcard Mocks/*/Inc)) \ +$(filter-out $(wildcard Mocks/*/$(TEST).h), $(wildcard Mocks/*/Inc/*.h)) \ -I../../Apps/Inc \ -I../../Drivers/Inc \ -I../../Config/Inc \ @@ -82,6 +82,11 @@ $(filter-out $(wildcard Mocks/*/$(TEST).h), $(wildcard Mocks/*/Inc)) \ -I../../Tests/Inc/ \ -I../../Tests/UnitTests \ -I../../Tests/UnitTests/Unity \ +-I../../RTOS/uCOS-III-STM32F4/uCOS-III/Source/ \ +-I../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/ \ +-I../../RTOS/uCOS-III-STM32F4/uC-CPU/ \ +-I../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/ \ +-I../../RTOS/uCOS-III-STM32F4/uC-LIB/ \ -IInc $(foreach src,$(C_INCLUDES),$(info --- $(src))) diff --git a/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h b/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h index c843a89f0..49495c2aa 100644 --- a/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h +++ b/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h @@ -2,9 +2,10 @@ #define __BSP_ADC_H #include "common.h" +#include "fff.h" + -DEFINE_FFF_GLOBALS; DECLARE_FAKE_VOID_FUNC(BSP_ADC_Init); DECLARE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Millivoltage, int); DECLARE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Value, int); diff --git a/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c b/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c index e69de29bb..7c65156ea 100644 --- a/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c +++ b/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c @@ -0,0 +1,8 @@ +#include "common.h" +#include "fff.h" +#include "BSP_ADC.h" + +DEFINE_FFF_GLOBALS; +DEFINE_FAKE_VOID_FUNC(BSP_ADC_Init); +DEFINE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Millivoltage, int); +DEFINE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Value, int); \ No newline at end of file diff --git a/Tests/UnitTests/Test_Pedals.c b/Tests/UnitTests/Test_Pedals.c new file mode 100644 index 000000000..73c48767c --- /dev/null +++ b/Tests/UnitTests/Test_Pedals.c @@ -0,0 +1 @@ +// This is a fake Test_Pedals that is only here because the makefile can't seem to find the one in the test folder \ No newline at end of file From 1e34a3c505dc7d5104863afc98026b1126afca60 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sun, 7 Jan 2024 17:49:20 -0600 Subject: [PATCH 11/57] Fixed Tests/Test_Pedals.c not found error by removing the TOCOMPILE variable, which didn't take into account the Tests/ directory. Also renamed the output file executable to be .out instead of .o since it is full, linked executable and not just an object file. FInally, add as a prerequisite to compile the unit test. I believe this will tell the Makefile to recompile the executable if any of the C_SOURCES have been changed since it was last compiled. --- Tests/UnitTests/Makefile | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index 9e1386446..3d768fe87 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -117,17 +117,16 @@ vpath %.c $(sort $(dir $(C_SOURCES))) OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) vpath %.s $(sort $(dir $(ASM_SOURCES))) -##Added -TOCOMPILE := Test_$(TEST) + ## # @$(CC) $(OBJECTS) -o $@ #added -$(BUILD_DIR)/$(TOCOMPILE).o: $(BUILD_DIR) $(TOCOMPILE).c +$(BUILD_DIR)/$(TEST): $(BUILD_DIR) $(C_SOURCES) @echo "LD $(<:../../%=%)" @echo "Mocking is $(MOCKING)" - @$(CC) $(CFLAGS) $(C_INCLUDES) $(TOCOMPILE).c $(C_SOURCES) -o $(BUILD_DIR)/$(TOCOMPILE).o + @$(CC) $(CFLAGS) $(C_INCLUDES) $(C_SOURCES) -o $(BUILD_DIR)/Test_$(TEST).out @echo "SZ $(<:../../%=%)" - - ./$(BUILD_DIR)/$(TOCOMPILE).o + - ./$(BUILD_DIR)/Test_$(TEST).out # $(BUILD_DIR)/$(TOCOMPILE).o: $(TOCOMPILE).c Makefile | $(BUILD_DIR) From c710daa3b733ca59b8c0e67c104a1934b384645a Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sun, 7 Jan 2024 17:51:41 -0600 Subject: [PATCH 12/57] Made BSP_ADC_Init non-static so that leader compiles. The function is public on the master branch, so I'm pretty sure it's okay. --- BSP/STM32F413/Src/BSP_ADC.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BSP/STM32F413/Src/BSP_ADC.c b/BSP/STM32F413/Src/BSP_ADC.c index 51737d4b0..1972ae111 100644 --- a/BSP/STM32F413/Src/BSP_ADC.c +++ b/BSP/STM32F413/Src/BSP_ADC.c @@ -45,7 +45,7 @@ static void ADC_InitDMA(void) { * @param None * @return None */ -static void BSP_ADC_Init(void) { +void BSP_ADC_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // Enable the ADC clock RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); // Enable the PC clock for port C From a2a0eabb6ab8bf9e9abd030b5f344954702364bb Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sun, 7 Jan 2024 19:33:30 -0600 Subject: [PATCH 13/57] Changed Makefile and got Test_Contactors working! Makefile changes: C_INCLUDES now uses the explicit paths for the mocks instead of the wildcard function since it wanted a directory instead of files and also because it needed the -I part appended to each path anyways; New flag -DTEST_ uses the name of the file we're testing and defines it as TEST_. This can be used in #ifdefs to determine if we want to include a regular header or a mock header. I'm not sure if putting an ifdef in each mock header is the best way to do it, but it was the easiest way I could think of at the moment. The mock Contactors.h is an example of this. Test changes: Made additional mocks so that Test_Contactors runs; moved the DEFINE_FFF_GLOBALS to the test file since this can only be defined once, and we at least know we'll only be running one test file at a time. In mock headers where we sometimes want to mock and sometimes want to test (ex: Contactors, Apps), the #include_next macros will include the second instance of the file on the search path. This means if we include the mocks before the normal headers in C_INCLUDES, we can use #include_next to choose the normal header. Not the cleanest way of doing things, but hopefully it at least works for now. --- Tests/UnitTests/Makefile | 16 +- Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h | 24 + .../UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h | 592 ++++++++++++++++++ Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c | 1 - Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c | 11 + .../UnitTests/Mocks/Drivers/Inc/Contactors.h | 29 + .../UnitTests/Mocks/Drivers/Src/Contactors.c | 6 + Tests/UnitTests/Test_Pedals.c | 1 - Tests/UnitTests/Tests/Test_Contactors.c | 5 + Tests/UnitTests/Tests/Test_Pedals.c | 27 +- 10 files changed, 692 insertions(+), 20 deletions(-) create mode 100644 Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h create mode 100644 Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h create mode 100644 Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c create mode 100644 Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h create mode 100644 Tests/UnitTests/Mocks/Drivers/Src/Contactors.c delete mode 100644 Tests/UnitTests/Test_Pedals.c diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index 3d768fe87..92e275d36 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -73,8 +73,10 @@ SF = st-flash # AS includes #AS_INCLUDES = #co TEST=Pedals -> include Pedals.c and Pedals.h +#$(filter-out $(wildcard Mocks/*/$(TEST).h), $(wildcard Mocks/*/Inc/*.h)) *Doesn't work since we can only include directories as search paths, not actual files C_INCLUDES := \ -$(filter-out $(wildcard Mocks/*/$(TEST).h), $(wildcard Mocks/*/Inc/*.h)) \ +-I../../Tests/UnitTests/Mocks/Drivers/Inc \ +-I../../Tests/UnitTests/Mocks/BSP/Inc \ -I../../Apps/Inc \ -I../../Drivers/Inc \ -I../../Config/Inc \ @@ -87,10 +89,9 @@ $(filter-out $(wildcard Mocks/*/$(TEST).h), $(wildcard Mocks/*/Inc/*.h)) \ -I../../RTOS/uCOS-III-STM32F4/uC-CPU/ \ -I../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/ \ -I../../RTOS/uCOS-III-STM32F4/uC-LIB/ \ --IInc + $(foreach src,$(C_INCLUDES),$(info --- $(src))) - ifeq ($(DEBUG), 1) CFLAGS += -g3 -gdwarf-2 -DDEBUG endif @@ -103,9 +104,11 @@ ifeq ($(CAR_LOOPBACK), 1) CFLAGS += -DCAR_LOOPBACK endif - MOCKING=1 - export MOCKING - CFLAGS += -DMOCKING +MOCKING=1 +CFLAGS += -DMOCKING + +FILETOTEST = $(shell echo '$(TEST)' | tr '[:lower:]' '[:upper:]') #Uses shell to make TEST file uppercase to define a macro +CFLAGS += -DTEST_$(FILETOTEST) #Defines a macro TEST_ to determine if we should use a mock or regular header file ####################################### # build the application @@ -123,7 +126,6 @@ vpath %.s $(sort $(dir $(ASM_SOURCES))) #added $(BUILD_DIR)/$(TEST): $(BUILD_DIR) $(C_SOURCES) @echo "LD $(<:../../%=%)" - @echo "Mocking is $(MOCKING)" @$(CC) $(CFLAGS) $(C_INCLUDES) $(C_SOURCES) -o $(BUILD_DIR)/Test_$(TEST).out @echo "SZ $(<:../../%=%)" - ./$(BUILD_DIR)/Test_$(TEST).out diff --git a/Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h b/Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h new file mode 100644 index 000000000..4f14ae69e --- /dev/null +++ b/Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h @@ -0,0 +1,24 @@ + +#ifndef __BSP_GPIO_H +#define __BSP_GPIO_H + +#include "common.h" +#include "fff.h" + + +typedef enum {PORTA = 0, PORTB, PORTC, PORTD, NUM_PORTS} port_t; +typedef enum {INPUT = 0, OUTPUT} direction_t; + +DECLARE_FAKE_VOID_FUNC(BSP_GPIO_Write_Pin, port_t, uint16_t, bool); +DECLARE_FAKE_VOID_FUNC(BSP_GPIO_Init, port_t, uint16_t, direction_t); +//FAKE_VOID_FUNC3(OSMutexCreate, struct os_mutex, CPU_CHAR, OS_ERR); +DECLARE_FAKE_VALUE_FUNC(uint8_t,BSP_GPIO_Get_State, port_t, uint16_t ); +//FAKE_VOID_FUNC5(OSMutexPend, OS_MUTEX, OS_TICK, OS_OPT, CPU_TS, OS_ERR); +//FAKE_VOID_FUNC3(OSMutexPost, OS_MUTEX, OS_OPT, OS_ERR); +DECLARE_FAKE_VOID_FUNC(assertOSError, int); + + +#endif + + +/* @} */ diff --git a/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h b/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h new file mode 100644 index 000000000..d15b0f6e4 --- /dev/null +++ b/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h @@ -0,0 +1,592 @@ +// /** +// ****************************************************************************** +// * @file stm32f4xx_gpio.h +// * @author MCD Application Team +// * @version V1.8.0 +// * @date 04-November-2016 +// * @brief This file contains all the functions prototypes for the GPIO firmware +// * library. +// ****************************************************************************** +// * @attention +// * +// *

© COPYRIGHT 2016 STMicroelectronics

+// * +// * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); +// * You may not use this file except in compliance with the License. +// * You may obtain a copy of the License at: +// * +// * http://www.st.com/software_license_agreement_liberty_v2 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// * +// ****************************************************************************** +// */ + +// /* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_GPIO_H +#define __STM32F4xx_GPIO_H + +// #ifdef __cplusplus +// extern "C" { +// #endif + +// /* Includes ------------------------------------------------------------------*/ +// #include "stm32f4xx.h" + +// /** @addtogroup STM32F4xx_StdPeriph_Driver +// * @{ +// */ + +// /** @addtogroup GPIO +// * @{ +// */ + +// /* Exported types ------------------------------------------------------------*/ + +// #define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ +// ((PERIPH) == GPIOB) || \ +// ((PERIPH) == GPIOC) || \ +// ((PERIPH) == GPIOD) || \ +// ((PERIPH) == GPIOE) || \ +// ((PERIPH) == GPIOF) || \ +// ((PERIPH) == GPIOG) || \ +// ((PERIPH) == GPIOH) || \ +// ((PERIPH) == GPIOI) || \ +// ((PERIPH) == GPIOJ) || \ +// ((PERIPH) == GPIOK)) + +// /** +// * @brief GPIO Configuration Mode enumeration +// */ +// typedef enum +// { +// GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ +// GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ +// GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ +// GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */ +// }GPIOMode_TypeDef; +// #define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN) || ((MODE) == GPIO_Mode_OUT) || \ +// ((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN)) + +// /** +// * @brief GPIO Output type enumeration +// */ +// typedef enum +// { +// GPIO_OType_PP = 0x00, +// GPIO_OType_OD = 0x01 +// }GPIOOType_TypeDef; +// #define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD)) + + +// /** +// * @brief GPIO Output Maximum frequency enumeration +// */ +// typedef enum +// { +// GPIO_Low_Speed = 0x00, /*!< Low speed */ +// GPIO_Medium_Speed = 0x01, /*!< Medium speed */ +// GPIO_Fast_Speed = 0x02, /*!< Fast speed */ +// GPIO_High_Speed = 0x03 /*!< High speed */ +// }GPIOSpeed_TypeDef; + +// /* Add legacy definition */ +// #define GPIO_Speed_2MHz GPIO_Low_Speed +// #define GPIO_Speed_25MHz GPIO_Medium_Speed +// #define GPIO_Speed_50MHz GPIO_Fast_Speed +// #define GPIO_Speed_100MHz GPIO_High_Speed + +// #define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Low_Speed) || ((SPEED) == GPIO_Medium_Speed) || \ +// ((SPEED) == GPIO_Fast_Speed)|| ((SPEED) == GPIO_High_Speed)) + +// /** +// * @brief GPIO Configuration PullUp PullDown enumeration +// */ +// typedef enum +// { +// GPIO_PuPd_NOPULL = 0x00, +// GPIO_PuPd_UP = 0x01, +// GPIO_PuPd_DOWN = 0x02 +// }GPIOPuPd_TypeDef; +// #define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \ +// ((PUPD) == GPIO_PuPd_DOWN)) + +// /** +// * @brief GPIO Bit SET and Bit RESET enumeration +// */ +// typedef enum +// { +// Bit_RESET = 0, +// Bit_SET +// }BitAction; +// #define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) + + +// /** +// * @brief GPIO Init structure definition +// */ +// typedef struct +// { +// uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. +// This parameter can be any value of @ref GPIO_pins_define */ + +// GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. +// This parameter can be a value of @ref GPIOMode_TypeDef */ + +// GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. +// This parameter can be a value of @ref GPIOSpeed_TypeDef */ + +// GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins. +// This parameter can be a value of @ref GPIOOType_TypeDef */ + +// GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. +// This parameter can be a value of @ref GPIOPuPd_TypeDef */ +// }GPIO_InitTypeDef; + +// /* Exported constants --------------------------------------------------------*/ + +// /** @defgroup GPIO_Exported_Constants +// * @{ +// */ + +/** @defgroup GPIO_pins_define + * @{ + */ +#define GPIO_Pin_0 ((uint16_t)0x0001) /* Pin 0 selected */ +#define GPIO_Pin_1 ((uint16_t)0x0002) /* Pin 1 selected */ +#define GPIO_Pin_2 ((uint16_t)0x0004) /* Pin 2 selected */ +#define GPIO_Pin_3 ((uint16_t)0x0008) /* Pin 3 selected */ +#define GPIO_Pin_4 ((uint16_t)0x0010) /* Pin 4 selected */ +#define GPIO_Pin_5 ((uint16_t)0x0020) /* Pin 5 selected */ +#define GPIO_Pin_6 ((uint16_t)0x0040) /* Pin 6 selected */ +#define GPIO_Pin_7 ((uint16_t)0x0080) /* Pin 7 selected */ +#define GPIO_Pin_8 ((uint16_t)0x0100) /* Pin 8 selected */ +#define GPIO_Pin_9 ((uint16_t)0x0200) /* Pin 9 selected */ +#define GPIO_Pin_10 ((uint16_t)0x0400) /* Pin 10 selected */ +#define GPIO_Pin_11 ((uint16_t)0x0800) /* Pin 11 selected */ +#define GPIO_Pin_12 ((uint16_t)0x1000) /* Pin 12 selected */ +#define GPIO_Pin_13 ((uint16_t)0x2000) /* Pin 13 selected */ +#define GPIO_Pin_14 ((uint16_t)0x4000) /* Pin 14 selected */ +#define GPIO_Pin_15 ((uint16_t)0x8000) /* Pin 15 selected */ +#define GPIO_Pin_All ((uint16_t)0xFFFF) /* All pins selected */ + +#define GPIO_PIN_MASK ((uint32_t)0x0000FFFF) /* PIN mask for assert test */ +#define IS_GPIO_PIN(PIN) (((PIN) & GPIO_PIN_MASK ) != (uint32_t)0x00) +#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \ + ((PIN) == GPIO_Pin_1) || \ + ((PIN) == GPIO_Pin_2) || \ + ((PIN) == GPIO_Pin_3) || \ + ((PIN) == GPIO_Pin_4) || \ + ((PIN) == GPIO_Pin_5) || \ + ((PIN) == GPIO_Pin_6) || \ + ((PIN) == GPIO_Pin_7) || \ + ((PIN) == GPIO_Pin_8) || \ + ((PIN) == GPIO_Pin_9) || \ + ((PIN) == GPIO_Pin_10) || \ + ((PIN) == GPIO_Pin_11) || \ + ((PIN) == GPIO_Pin_12) || \ + ((PIN) == GPIO_Pin_13) || \ + ((PIN) == GPIO_Pin_14) || \ + ((PIN) == GPIO_Pin_15)) +/** + * @} + */ + + +// /** @defgroup GPIO_Pin_sources +// * @{ +// */ +// #define GPIO_PinSource0 ((uint8_t)0x00) +// #define GPIO_PinSource1 ((uint8_t)0x01) +// #define GPIO_PinSource2 ((uint8_t)0x02) +// #define GPIO_PinSource3 ((uint8_t)0x03) +// #define GPIO_PinSource4 ((uint8_t)0x04) +// #define GPIO_PinSource5 ((uint8_t)0x05) +// #define GPIO_PinSource6 ((uint8_t)0x06) +// #define GPIO_PinSource7 ((uint8_t)0x07) +// #define GPIO_PinSource8 ((uint8_t)0x08) +// #define GPIO_PinSource9 ((uint8_t)0x09) +// #define GPIO_PinSource10 ((uint8_t)0x0A) +// #define GPIO_PinSource11 ((uint8_t)0x0B) +// #define GPIO_PinSource12 ((uint8_t)0x0C) +// #define GPIO_PinSource13 ((uint8_t)0x0D) +// #define GPIO_PinSource14 ((uint8_t)0x0E) +// #define GPIO_PinSource15 ((uint8_t)0x0F) + +// #define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \ +// ((PINSOURCE) == GPIO_PinSource1) || \ +// ((PINSOURCE) == GPIO_PinSource2) || \ +// ((PINSOURCE) == GPIO_PinSource3) || \ +// ((PINSOURCE) == GPIO_PinSource4) || \ +// ((PINSOURCE) == GPIO_PinSource5) || \ +// ((PINSOURCE) == GPIO_PinSource6) || \ +// ((PINSOURCE) == GPIO_PinSource7) || \ +// ((PINSOURCE) == GPIO_PinSource8) || \ +// ((PINSOURCE) == GPIO_PinSource9) || \ +// ((PINSOURCE) == GPIO_PinSource10) || \ +// ((PINSOURCE) == GPIO_PinSource11) || \ +// ((PINSOURCE) == GPIO_PinSource12) || \ +// ((PINSOURCE) == GPIO_PinSource13) || \ +// ((PINSOURCE) == GPIO_PinSource14) || \ +// ((PINSOURCE) == GPIO_PinSource15)) +// /** +// * @} +// */ + +// /** @defgroup GPIO_Alternat_function_selection_define +// * @{ +// */ +// /** +// * @brief AF 0 selection +// */ +// #define GPIO_AF_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ +// #define GPIO_AF_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ +// #define GPIO_AF_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ +// #define GPIO_AF_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ +// #define GPIO_AF_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ +// #if defined(STM32F446xx) +// #define GPIO_AF0_TIM2 ((uint8_t)0x00) /* TIM2 Alternate Function mapping */ +// #endif /* STM32F446xx */ + +// /** +// * @brief AF 1 selection +// */ +// #define GPIO_AF_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ +// #define GPIO_AF_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ +// #if defined(STM32F410xx) || defined(STM32F413_423xx) +// #define GPIO_AF_LPTIM ((uint8_t)0x01) /* LPTIM Alternate Function mapping */ +// #endif /* STM32F410xx || STM32F413_423xx */ +// /** +// * @brief AF 2 selection +// */ +// #define GPIO_AF_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ +// #define GPIO_AF_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ +// #define GPIO_AF_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ + +// /** +// * @brief AF 3 selection +// */ +// #define GPIO_AF_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */ +// #define GPIO_AF_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */ +// #define GPIO_AF_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */ +// #define GPIO_AF_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */ +// #if defined(STM32F446xx) +// #define GPIO_AF3_CEC ((uint8_t)0x03) /* CEC Alternate Function mapping */ +// #endif /* STM32F446xx */ +// #if defined(STM32F413_423xx) +// #define GPIO_AF3_DFSDM2 ((uint8_t)0x03) /* DFSDM2 Alternate Function mapping */ +// #endif /* STM32F413_423xx */ +// /** +// * @brief AF 4 selection +// */ +// #define GPIO_AF_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ +// #define GPIO_AF_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ +// #define GPIO_AF_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ +// #if defined(STM32F446xx) +// #define GPIO_AF4_CEC ((uint8_t)0x04) /* CEC Alternate Function mapping */ +// #endif /* STM32F446xx */ +// #if defined(STM32F410xx) || defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) +// #define GPIO_AF_FMPI2C ((uint8_t)0x04) /* FMPI2C Alternate Function mapping */ +// #endif /* STM32F410xx || STM32F446xx */ + +// /** +// * @brief AF 5 selection +// */ +// #define GPIO_AF_SPI1 ((uint8_t)0x05) /* SPI1/I2S1 Alternate Function mapping */ +// #define GPIO_AF_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */ +// #define GPIO_AF5_SPI3 ((uint8_t)0x05) /* SPI3/I2S3 Alternate Function mapping (Only for STM32F411xE and STM32F413_423xx Devices) */ +// #define GPIO_AF_SPI4 ((uint8_t)0x05) /* SPI4/I2S4 Alternate Function mapping */ +// #define GPIO_AF_SPI5 ((uint8_t)0x05) /* SPI5 Alternate Function mapping */ +// #define GPIO_AF_SPI6 ((uint8_t)0x05) /* SPI6 Alternate Function mapping */ + +// /** +// * @brief AF 6 selection +// */ +// #define GPIO_AF_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */ +// #define GPIO_AF6_SPI1 ((uint8_t)0x06) /* SPI1 Alternate Function mapping (Only for STM32F410xx Devices) */ +// #define GPIO_AF6_SPI2 ((uint8_t)0x06) /* SPI2 Alternate Function mapping (Only for STM32F410xx/STM32F411xE Devices) */ +// #define GPIO_AF6_SPI4 ((uint8_t)0x06) /* SPI4 Alternate Function mapping (Only for STM32F411xE Devices) */ +// #define GPIO_AF6_SPI5 ((uint8_t)0x06) /* SPI5 Alternate Function mapping (Only for STM32F410xx/STM32F411xE Devices) */ +// #define GPIO_AF_SAI1 ((uint8_t)0x06) /* SAI1 Alternate Function mapping */ +// #define GPIO_AF_I2S2ext ((uint8_t)0x06) /* I2S2ext_SD Alternate Function mapping (only for STM32F412xG and STM32F413_423xx Devices) */ +// #if defined(STM32F412xG) || defined(STM32F413_423xx) +// #define GPIO_AF6_DFSDM1 ((uint8_t)0x06) /* DFSDM1 Alternate Function mapping */ +// #endif /* STM32F412xG || STM32F413_423xx */ +// #if defined(STM32F413_423xx) +// #define GPIO_AF6_DFSDM2 ((uint8_t)0x06) /* DFSDM2 Alternate Function mapping */ +// #endif /* STM32F413_423xx */ + +// /** +// * @brief AF 7 selection +// */ +// #define GPIO_AF_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ +// #define GPIO_AF_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ +// #define GPIO_AF_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */ +// #define GPIO_AF7_SPI3 ((uint8_t)0x07) /* SPI3/I2S3ext Alternate Function mapping */ +// #if defined(STM32F413_423xx) +// #define GPIO_AF7_DFSDM2 ((uint8_t)0x07) /* DFSDM2 Alternate Function mapping */ +// #define GPIO_AF7_SAI1 ((uint8_t)0x07) /* SAI1 Alternate Function mapping */ +// #endif /* STM32F413_423xx */ + +// /** +// * @brief AF 7 selection Legacy +// */ +// #define GPIO_AF_I2S3ext GPIO_AF7_SPI3 + +// /** +// * @brief AF 8 selection +// */ +// #define GPIO_AF_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */ +// #define GPIO_AF_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */ +// #define GPIO_AF_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */ +// #define GPIO_AF_UART7 ((uint8_t)0x08) /* UART7 Alternate Function mapping */ +// #define GPIO_AF_UART8 ((uint8_t)0x08) /* UART8 Alternate Function mapping */ +// #if defined(STM32F412xG) || defined(STM32F413_423xx) +// #define GPIO_AF8_USART3 ((uint8_t)0x08) /* USART3 Alternate Function mapping */ +// #define GPIO_AF8_DFSDM1 ((uint8_t)0x08) /* DFSDM Alternate Function mapping */ +// #define GPIO_AF8_CAN1 ((uint8_t)0x08) /* CAN1 Alternate Function mapping */ +// #endif /* STM32F412xG || STM32F413_423xx */ +// #if defined(STM32F446xx) +// #define GPIO_AF8_SAI2 ((uint8_t)0x08) /* SAI2 Alternate Function mapping */ +// #define GPIO_AF_SPDIF ((uint8_t)0x08) /* SPDIF Alternate Function mapping */ +// #endif /* STM32F446xx */ + +// /** +// * @brief AF 9 selection +// */ +// #define GPIO_AF_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */ +// #define GPIO_AF_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */ +// #define GPIO_AF_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */ +// #define GPIO_AF_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */ +// #define GPIO_AF_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ +// #define GPIO_AF9_I2C2 ((uint8_t)0x09) /* I2C2 Alternate Function mapping (Only for STM32F401xx/STM32F410xx/STM32F411xE/STM32F412xG/STM32F413_423xx Devices) */ +// #define GPIO_AF9_I2C3 ((uint8_t)0x09) /* I2C3 Alternate Function mapping (Only for STM32F401xx/STM32F411xE/STM32F412xG and STM32F413_423xx Devices) */ +// #if defined(STM32F446xx) +// #define GPIO_AF9_SAI2 ((uint8_t)0x09) /* SAI2 Alternate Function mapping */ +// #endif /* STM32F446xx */ +// #define GPIO_AF9_LTDC ((uint8_t)0x09) /* LTDC Alternate Function mapping */ +// #if defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) || defined(STM32F469_479xx) +// #define GPIO_AF9_QUADSPI ((uint8_t)0x09) /* QuadSPI Alternate Function mapping */ +// #endif /* STM32F412xG || STM32F413_423xx || STM32F446xx || STM32F469_479xx */ +// #if defined(STM32F410xx) || defined(STM32F412xG) || defined(STM32F413_423xx) +// #define GPIO_AF9_FMPI2C ((uint8_t)0x09) /* FMPI2C Alternate Function mapping (Only for STM32F410xx Devices) */ +// #endif /* STM32F410xx || STM32F412xG || STM32F413_423xx */ + +// /** +// * @brief AF 10 selection +// */ +// #define GPIO_AF_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ +// #define GPIO_AF_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */ +// #if defined(STM32F446xx) +// #define GPIO_AF10_SAI2 ((uint8_t)0x0A) /* SAI2 Alternate Function mapping */ +// #endif /* STM32F446xx */ +// #if defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) || defined(STM32F469_479xx) +// #define GPIO_AF10_QUADSPI ((uint8_t)0x0A) /* QuadSPI Alternate Function mapping */ +// #endif /* STM32F412xG || STM32F413_423xx || STM32F446xx || STM32F469_479xx */ +// #if defined(STM32F412xG) || defined(STM32F413_423xx) +// #define GPIO_AF10_FMC ((uint8_t)0xA) /* FMC Alternate Function mapping */ +// #define GPIO_AF10_DFSDM1 ((uint8_t)0xA) /* DFSDM Alternate Function mapping */ +// #endif /* STM32F412xG || STM32F413_423xx */ +// #if defined(STM32F413_423xx) +// #define GPIO_AF10_DFSDM2 ((uint8_t)0x0A) /* DFSDM2 Alternate Function mapping */ +// #define GPIO_AF10_SAI1 ((uint8_t)0x0A) /* SAI1 Alternate Function mapping */ +// #endif /* STM32F413_423xx */ +// /** +// * @brief AF 11 selection +// */ +// #define GPIO_AF_ETH ((uint8_t)0x0B) /* ETHERNET Alternate Function mapping */ +// #if defined(STM32F413_423xx) +// #define GPIO_AF11_UART4 ((uint8_t)0x0B) /* UART4 Alternate Function mapping */ +// #define GPIO_AF11_UART5 ((uint8_t)0x0B) /* UART5 Alternate Function mapping */ +// #define GPIO_AF11_UART9 ((uint8_t)0x0B) /* UART9 Alternate Function mapping */ +// #define GPIO_AF11_UART10 ((uint8_t)0x0B) /* UART10 Alternate Function mapping */ +// #define GPIO_AF11_CAN3 ((uint8_t)0x0B) /* CAN3 Alternate Function mapping */ +// #endif /* STM32F413_423xx */ + +// /** +// * @brief AF 12 selection +// */ +// #if defined(STM32F40_41xxx) || defined(STM32F412xG) || defined(STM32F413_423xx) +// #define GPIO_AF_FSMC ((uint8_t)0xC) /* FSMC Alternate Function mapping */ +// #endif /* STM32F40_41xxx || STM32F412xG || STM32F413_423xx */ + +// #if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx) +// #define GPIO_AF_FMC ((uint8_t)0xC) /* FMC Alternate Function mapping */ +// #endif /* STM32F427_437xx || STM32F429_439xx || STM32F446xx || STM32F469_479xx */ + +// #define GPIO_AF_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */ +// #define GPIO_AF_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */ + +// /** +// * @brief AF 13 selection +// */ +// #define GPIO_AF_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */ +// #if defined(STM32F469_479xx) +// #define GPIO_AF_DSI ((uint8_t)0x0D) /* DSI Alternate Function mapping */ +// #endif /* STM32F469_479xx */ +// /** +// * @brief AF 14 selection +// */ +// #define GPIO_AF_LTDC ((uint8_t)0x0E) /* LCD-TFT Alternate Function mapping */ +// #if defined(STM32F413_423xx) +// #define GPIO_AF14_RNG ((uint8_t)0x0E) /* RNG Alternate Function mapping */ +// #endif /* STM32F413_423xx */ + +// /** +// * @brief AF 15 selection +// */ +// #define GPIO_AF_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ + +// #if defined(STM32F40_41xxx) +// #define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ +// ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ +// ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ +// ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ +// ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ +// ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ +// ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ +// ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ +// ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ +// ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ +// ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ +// ((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \ +// ((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \ +// ((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \ +// ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ +// ((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_OTG_HS_FS) || \ +// ((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_DCMI) || \ +// ((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_FSMC)) +// #endif /* STM32F40_41xxx */ + +// #if defined(STM32F401xx) +// #define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ +// ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ +// ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ +// ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ +// ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ +// ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ +// ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ +// ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ +// ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ +// ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ +// ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ +// ((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_USART6) || \ +// ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ +// ((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_SPI4)) +// #endif /* STM32F401xx */ + +// #if defined(STM32F411xE) +// #define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 13) && ((AF) != 14)) +// #endif /* STM32F411xE */ + +// #if defined(STM32F410xx) +// #define IS_GPIO_AF(AF) (((AF) < 10) || ((AF) == 15)) +// #endif /* STM32F410xx */ + +// #if defined(STM32F427_437xx) || defined(STM32F429_439xx) +// #define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ +// ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ +// ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ +// ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ +// ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ +// ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ +// ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ +// ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ +// ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ +// ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ +// ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ +// ((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \ +// ((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \ +// ((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \ +// ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ +// ((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_OTG_HS_FS) || \ +// ((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_DCMI) || \ +// ((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_SPI4) || \ +// ((AF) == GPIO_AF_SPI5) || ((AF) == GPIO_AF_SPI6) || \ +// ((AF) == GPIO_AF_UART7) || ((AF) == GPIO_AF_UART8) || \ +// ((AF) == GPIO_AF_FMC) || ((AF) == GPIO_AF_SAI1) || \ +// ((AF) == GPIO_AF_LTDC)) +// #endif /* STM32F427_437xx || STM32F429_439xx */ + +// #if defined(STM32F412xG) +// #define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 14)) +// #endif /* STM32F412xG */ + +// #if defined(STM32F413_423xx) +// #define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 13)) +// #endif /* STM32F413_423xx */ + +// #if defined(STM32F446xx) +// #define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 14)) +// #endif /* STM32F446xx */ + +// #if defined(STM32F469_479xx) +// #define IS_GPIO_AF(AF) ((AF) < 16) +// #endif /* STM32F469_479xx */ + +// /** +// * @} +// */ + +// /** @defgroup GPIO_Legacy +// * @{ +// */ + +// #define GPIO_Mode_AIN GPIO_Mode_AN + +// #define GPIO_AF_OTG1_FS GPIO_AF_OTG_FS +// #define GPIO_AF_OTG2_HS GPIO_AF_OTG_HS +// #define GPIO_AF_OTG2_FS GPIO_AF_OTG_HS_FS + +// /** +// * @} +// */ + +// /** +// * @} +// */ + +// /* Exported macro ------------------------------------------------------------*/ +// /* Exported functions --------------------------------------------------------*/ + +// /* Function used to set the GPIO configuration to the default reset state ****/ +// void GPIO_DeInit(GPIO_TypeDef* GPIOx); + +// /* Initialization and Configuration functions *********************************/ +// void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); +// void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); +// void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); + +// /* GPIO Read and Write functions **********************************************/ +// uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +// uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); +// uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +// uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); +// void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +// void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +// void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); +// void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); +// void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); + +// /* GPIO Alternate functions configuration function ****************************/ +// void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF); + +// #ifdef __cplusplus +// } +// #endif + +#endif /*__STM32F4xx_GPIO_H */ + +// /** +// * @} +// */ + +// /** +// * @} +// */ + +// /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c b/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c index 7c65156ea..0ceb33869 100644 --- a/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c +++ b/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c @@ -2,7 +2,6 @@ #include "fff.h" #include "BSP_ADC.h" -DEFINE_FFF_GLOBALS; DEFINE_FAKE_VOID_FUNC(BSP_ADC_Init); DEFINE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Millivoltage, int); DEFINE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Value, int); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c b/Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c new file mode 100644 index 000000000..ec9cf4966 --- /dev/null +++ b/Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c @@ -0,0 +1,11 @@ +#include "BSP_GPIO.h" +#include "fff.h" + + +DEFINE_FAKE_VOID_FUNC(BSP_GPIO_Write_Pin, port_t, uint16_t, bool); +DEFINE_FAKE_VOID_FUNC(BSP_GPIO_Init, port_t, uint16_t, direction_t); +//FAKE_VOID_FUNC3(OSMutexCreate, struct os_mutex, CPU_CHAR, OS_ERR); +DEFINE_FAKE_VALUE_FUNC(uint8_t,BSP_GPIO_Get_State, port_t, uint16_t ); +//FAKE_VOID_FUNC5(OSMutexPend, OS_MUTEX, OS_TICK, OS_OPT, CPU_TS, OS_ERR); +//FAKE_VOID_FUNC3(OSMutexPost, OS_MUTEX, OS_OPT, OS_ERR); +DEFINE_FAKE_VOID_FUNC(assertOSError, int); diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h b/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h new file mode 100644 index 000000000..e07a6354c --- /dev/null +++ b/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h @@ -0,0 +1,29 @@ +#ifdef TEST_CONTACTORS +#include_next "Contactors.h" // Include the next instance of the file. +// If the real version is in the include search paths after the mock one, it will include it here +#else // Mocked Contactors.h +#ifndef __CONTACTORS_H +#define __CONTACTORS_H +#include "fff.h" +#include "common.h" +#include "stm32f4xx_gpio.h" + +#define CONTACTORS_PORT PORTC +#define ARRAY_PRECHARGE_BYPASS_PIN GPIO_Pin_10 +#define MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN GPIO_Pin_12 + +#define FOREACH_contactor(contactor) \ + contactor(ARRAY_PRECHARGE_BYPASS_CONTACTOR), \ + contactor(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR), \ + +typedef enum contactor_ENUM { + FOREACH_contactor(GENERATE_ENUM) + NUM_CONTACTORS, +}contactor_t; + +DECLARE_FAKE_VOID_FUNC(Contactors_Init); +DECLARE_FAKE_VALUE_FUNC(bool, Contactors_Get); +DECLARE_FAKE_VALUE_FUNC(ErrorStatus, Contactors_Set, contactor_t, bool, bool); + +#endif +#endif diff --git a/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c b/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c new file mode 100644 index 000000000..5dd675955 --- /dev/null +++ b/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c @@ -0,0 +1,6 @@ +#include "fff.h" +#include "Contactors.h" + +DEFINE_FAKE_VOID_FUNC(Contactors_Init); +DEFINE_FAKE_VALUE_FUNC(bool, Contactors_Get); +DEFINE_FAKE_VALUE_FUNC(ErrorStatus, Contactors_Set, contactor_t, bool, bool); \ No newline at end of file diff --git a/Tests/UnitTests/Test_Pedals.c b/Tests/UnitTests/Test_Pedals.c deleted file mode 100644 index 73c48767c..000000000 --- a/Tests/UnitTests/Test_Pedals.c +++ /dev/null @@ -1 +0,0 @@ -// This is a fake Test_Pedals that is only here because the makefile can't seem to find the one in the test folder \ No newline at end of file diff --git a/Tests/UnitTests/Tests/Test_Contactors.c b/Tests/UnitTests/Tests/Test_Contactors.c index d3c9bef60..50e1656bc 100644 --- a/Tests/UnitTests/Tests/Test_Contactors.c +++ b/Tests/UnitTests/Tests/Test_Contactors.c @@ -6,7 +6,12 @@ ////////////////////////////////////////// // The header file we are unit testing: #include "Contactors.h" +////////////////////////////////////////// +// fff header so we can DEFINE_FFF_GLOBALS +// (can only happen once per test) +#include "fff.h" +DEFINE_FFF_GLOBALS; void setUp(void) {} diff --git a/Tests/UnitTests/Tests/Test_Pedals.c b/Tests/UnitTests/Tests/Test_Pedals.c index 87edbdafa..51eb14a16 100644 --- a/Tests/UnitTests/Tests/Test_Pedals.c +++ b/Tests/UnitTests/Tests/Test_Pedals.c @@ -1,31 +1,36 @@ ////////////////////////////////////////// ////////////////////////////////////////// // Unity required for this testing format -#include "unity.h" +#include "unity.h" ////////////////////////////////////////// ////////////////////////////////////////// // The header file we are unit testing: -#include "Pedals.h" +#include "Pedals.h" +////////////////////////////////////////// +// fff header so we can DEFINE_FFF_GLOBALS +// (can only happen once per test) +#include "fff.h" +DEFINE_FFF_GLOBALS; void setUp(void) {} void tearDown(void) {} void test_UnitTestPedals_Init(void){ - Pedals_Init(); + Pedals_Init(); } void test_UnitTestPedals_Read(void){ for(int x = 500; x < 1000; x+=100){ - BSP_ADC_Get_Millivoltage_fake.return_val = x; - Pedals_Read(ACCELERATOR); - //printf("\n\r%d\r", Pedals_Read(ACCELERATOR)); + BSP_ADC_Get_Millivoltage_fake.return_val = x; + Pedals_Read(ACCELERATOR); + printf("\n\r%d\r", Pedals_Read(ACCELERATOR)); } } void test_UnitTestPedals_Read_This_Will_Fail(void){ - TEST_ASSERT_EQUAL(Pedals_Read(ACCELERATOR), 30); + TEST_ASSERT_EQUAL(Pedals_Read(ACCELERATOR), 30); } @@ -33,9 +38,9 @@ void test_UnitTestPedals_Read_This_Will_Fail(void){ /*=======MAIN=====*/ int main(void) { - UNITY_BEGIN(); - RUN_TEST(test_UnitTestPedals_Init); + UNITY_BEGIN(); + RUN_TEST(test_UnitTestPedals_Init); RUN_TEST(test_UnitTestPedals_Read); - RUN_TEST(test_UnitTestPedals_Read_This_Will_Fail); - return UNITY_END(); + RUN_TEST(test_UnitTestPedals_Read_This_Will_Fail); + return UNITY_END(); } \ No newline at end of file From 7804bbd1e208a9405fa55d26b8167caecb760b6f Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Wed, 10 Jan 2024 03:42:22 +0000 Subject: [PATCH 14/57] added new mocks to define and declare OS fucntions and macros required for OS, contactors working with OS, initial version of RCC --- .vscode/LHR.code-workspace | 6 +- Apps/Inc/ReadCarCAN.h | 4 +- Apps/Inc/Tasks.h | 3 +- Apps/Src/ReadCarCAN.c | 124 +- Apps/Src/Tasks.c | 1 + Drivers/Src/Contactors.c | 34 +- Tests/Test_ReadCarCANrewrite.c | 1 + Tests/UnitTests/Makefile | 3 + Tests/UnitTests/Mocks/Apps/Inc/Tasks.h | 32 + Tests/UnitTests/Mocks/Apps/Src/Tasks.c | 24 + Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h | 90 ++ .../UnitTests/Mocks/Drivers/Inc/Contactors.h | 3 +- Tests/UnitTests/Mocks/Drivers/Inc/Minions.h | 41 + Tests/UnitTests/Mocks/Drivers/Src/CANbus.c | 8 + .../UnitTests/Mocks/Drivers/Src/Contactors.c | 2 +- Tests/UnitTests/Mocks/Drivers/Src/Minions.c | 6 + Tests/UnitTests/Mocks/RTOS/cpu.h | 387 +++++ Tests/UnitTests/Mocks/RTOS/cpu_cfg.h | 215 +++ Tests/UnitTests/Mocks/RTOS/cpu_core.h | 491 ++++++ Tests/UnitTests/Mocks/RTOS/cpu_def.h | 220 +++ Tests/UnitTests/Mocks/RTOS/lib_def.h | 1344 ++++++++++++++++ Tests/UnitTests/Mocks/RTOS/os.c | 29 + Tests/UnitTests/Mocks/RTOS/os.h | 1400 +++++++++++++++++ Tests/UnitTests/Mocks/RTOS/os_cfg.h | 117 ++ Tests/UnitTests/Mocks/RTOS/os_type.h | 98 ++ Tests/UnitTests/Tests/Test_ReadCarCAN.c | 44 + 26 files changed, 4641 insertions(+), 86 deletions(-) create mode 100644 Tests/UnitTests/Mocks/Apps/Inc/Tasks.h create mode 100644 Tests/UnitTests/Mocks/Apps/Src/Tasks.c create mode 100644 Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h create mode 100644 Tests/UnitTests/Mocks/Drivers/Inc/Minions.h create mode 100644 Tests/UnitTests/Mocks/Drivers/Src/CANbus.c create mode 100644 Tests/UnitTests/Mocks/Drivers/Src/Minions.c create mode 100644 Tests/UnitTests/Mocks/RTOS/cpu.h create mode 100644 Tests/UnitTests/Mocks/RTOS/cpu_cfg.h create mode 100644 Tests/UnitTests/Mocks/RTOS/cpu_core.h create mode 100644 Tests/UnitTests/Mocks/RTOS/cpu_def.h create mode 100644 Tests/UnitTests/Mocks/RTOS/lib_def.h create mode 100644 Tests/UnitTests/Mocks/RTOS/os.c create mode 100644 Tests/UnitTests/Mocks/RTOS/os.h create mode 100644 Tests/UnitTests/Mocks/RTOS/os_cfg.h create mode 100644 Tests/UnitTests/Mocks/RTOS/os_type.h create mode 100644 Tests/UnitTests/Tests/Test_ReadCarCAN.c diff --git a/.vscode/LHR.code-workspace b/.vscode/LHR.code-workspace index 1db206007..bf60f6eb5 100644 --- a/.vscode/LHR.code-workspace +++ b/.vscode/LHR.code-workspace @@ -28,7 +28,11 @@ "common.h": "c", "stdio.h": "c", "stm32f4xx.h": "c", - "bsp_gpio.h": "c" + "bsp_gpio.h": "c", + "os.h": "c", + "tasks.h": "c", + "canbus.h": "c", + "readcarcan.h": "c" }, }, "tasks": { diff --git a/Apps/Inc/ReadCarCAN.h b/Apps/Inc/ReadCarCAN.h index a082bf312..a7a592b50 100644 --- a/Apps/Inc/ReadCarCAN.h +++ b/Apps/Inc/ReadCarCAN.h @@ -11,10 +11,10 @@ #ifndef __READ_CAR_CAN_H #define __READ_CAR_CAN_H -#include "os.h" #include "common.h" -#include "Tasks.h" #include "CANbus.h" +#include "Tasks.h" +#include "Minions.h" /** * Error types diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index fdd45efb2..3f6d700e8 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -8,7 +8,6 @@ * @{ */ - #ifndef __TASKS_H #define __TASKS_H @@ -185,4 +184,4 @@ void _assertOSError (OS_ERR err); //TODO: This should be changed to enforce only #endif -/* @} */ \ No newline at end of file +/* @} */ diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 07e7f39dc..f1f8221d6 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -6,12 +6,12 @@ */ #include "ReadCarCAN.h" -#include "UpdateDisplay.h" +//#include "UpdateDisplay.h" #include "Contactors.h" #include "Minions.h" #include "os.h" #include "os_cfg_app.h" -#include "Display.h" +//#include "Display.h" // Length of the array and motor PBC saturation buffers #define SAT_BUF_LENGTH 5 @@ -44,14 +44,14 @@ // State of Charge scalar to scale it to correct fixed point #define SOC_SCALER 1000000 -// CAN watchdog timer variable -static OS_TMR canWatchTimer; +// // CAN watchdog timer variable +// static OS_TMR canWatchTimer; -// Array precharge bypass contactor delay timer variable -static OS_TMR arrayPBCDlyTimer; +// // Array precharge bypass contactor delay timer variable +// static OS_TMR arrayPBCDlyTimer; -// Motor controller precharge bypass contactor delay timer variable -static OS_TMR motorControllerPBCDlyTimer; +// // Motor controller precharge bypass contactor delay timer variable +// static OS_TMR motorControllerPBCDlyTimer; // NOTE: This should not be written to anywhere other than ReadCarCAN. If the need arises, a mutex to protect it must be added. // Indicates whether or not regenerative braking / charging is enabled. @@ -131,19 +131,19 @@ static void disableArrayPrechargeBypassContactor(void){ * @param None */ static void updateArrayPrechargeBypassContactor(void){ - OS_ERR err = OS_ERR_NONE; + // OS_ERR err = OS_ERR_NONE; if((arrIgnStatus || mcIgnStatus) // Ignition is ON && HVArrayMsgSaturation >= ARRAY_SATURATION_THRESHOLD // Saturation Threshold has be met && (Contactors_Get(ARRAY_PRECHARGE_BYPASS_CONTACTOR) == OFF) // Array PBC is OFF - && (OSTmrStateGet(&arrayPBCDlyTimer, &err) != OS_TMR_STATE_RUNNING)){ // and precharge is currently not happening + /*&& (OSTmrStateGet(&arrayPBCDlyTimer, &err) != OS_TMR_STATE_RUNNING)*/){ // and precharge is currently not happening // Asserts error for OS timer state above if conditional was met - assertOSError(err); + // assertOSError(err); // Wait to make sure precharge is finished and then restart array - OSTmrStart(&arrayPBCDlyTimer, &err); + // OSTmrStart(&arrayPBCDlyTimer, &err); } // Asserts error for OS timer state above if conditional was not met - assertOSError(err); + // assertOSError(err); } @@ -153,18 +153,18 @@ static void updateArrayPrechargeBypassContactor(void){ * @param None */ static void updateMCPBC(void){ - OS_ERR err = OS_ERR_NONE; + // OS_ERR err = OS_ERR_NONE; if(mcIgnStatus // Ignition is ON && HVPlusMinusChargeMsgSaturation >= PLUS_MINUS_SATURATION_THRESHOLD // Saturation Threshold has be met &&(Contactors_Get(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR) == OFF) // Motor Controller PBC is OFF - && (OSTmrStateGet(&motorControllerPBCDlyTimer, &err) != OS_TMR_STATE_RUNNING)){ // and precharge is currently not happening + /*&& (OSTmrStateGet(&motorControllerPBCDlyTimer, &err) != OS_TMR_STATE_RUNNING)*/){ // and precharge is currently not happening // Asserts error for OS timer state above if conditional was met - assertOSError(err); + // assertOSError(err); // Wait to make sure precharge is finished and then restart array - OSTmrStart(&motorControllerPBCDlyTimer, &err); + // OSTmrStart(&motorControllerPBCDlyTimer, &err); } // Asserts error for OS timer start above if conditional was not met - assertOSError(err); + // assertOSError(err); } /** @@ -236,7 +236,7 @@ static void updateHVPlusMinusSaturation(int8_t messageState){ void attemptTurnMotorControllerPBCOn(void){ if(mcPBCComplete){ Contactors_Set(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR, ON, true); - UpdateDisplay_SetMotor(true); + // UpdateDisplay_SetMotor(true); } } @@ -285,52 +285,52 @@ static void updateHVPlusMinusSaturation(int8_t messageState){ } void Task_ReadCarCAN(void *p_arg){ - OS_ERR err; + // OS_ERR err; // data struct for CAN message CANDATA_t dataBuf; // Create the CAN Watchdog (periodic) timer, which disconnects the array and disables regenerative braking // if we do not get a CAN message with the ID Charge_Enable within the desired interval. - OSTmrCreate( - &canWatchTimer, - "CAN Watch Timer", - CAN_WATCH_TMR_DLY_TMR_TS, // Initial delay equal to the period since 0 doesn't seem to work - CAN_WATCH_TMR_DLY_TMR_TS, - OS_OPT_TMR_PERIODIC, - callbackCANWatchdog, - NULL, - &err - ); - assertOSError(err); - - OSTmrCreate( - &arrayPBCDlyTimer, - "Array Bypass Precharge Delay Timer", - 0, - ARRAY_PRECHARGE_BYPASS_DLY_TMR_TS, - OS_OPT_TMR_ONE_SHOT, - setArrayBypassPrechargeComplete, - NULL, - &err - ); - assertOSError(err); - - OSTmrCreate( - &motorControllerPBCDlyTimer, - "Motor Controller Bypass Precharge Delay Timer", - 0, - MOTOR_CONTROLLER_PRECHARGE_BYPASS_DLY_TMR_TS, - OS_OPT_TMR_ONE_SHOT, - setMotorControllerBypassPrechargeComplete, - NULL, - &err - ); - assertOSError(err); + // OSTmrCreate( + // &canWatchTimer, + // "CAN Watch Timer", + // CAN_WATCH_TMR_DLY_TMR_TS, // Initial delay equal to the period since 0 doesn't seem to work + // CAN_WATCH_TMR_DLY_TMR_TS, + // OS_OPT_TMR_PERIODIC, + // callbackCANWatchdog, + // NULL, + // &err + // ); + // assertOSError(err); + + // OSTmrCreate( + // &arrayPBCDlyTimer, + // "Array Bypass Precharge Delay Timer", + // 0, + // ARRAY_PRECHARGE_BYPASS_DLY_TMR_TS, + // OS_OPT_TMR_ONE_SHOT, + // setArrayBypassPrechargeComplete, + // NULL, + // &err + // ); + // assertOSError(err); + + // OSTmrCreate( + // &motorControllerPBCDlyTimer, + // "Motor Controller Bypass Precharge Delay Timer", + // 0, + // MOTOR_CONTROLLER_PRECHARGE_BYPASS_DLY_TMR_TS, + // OS_OPT_TMR_ONE_SHOT, + // setMotorControllerBypassPrechargeComplete, + // NULL, + // &err + // ); + // assertOSError(err); // Start CAN Watchdog timer - OSTmrStart(&canWatchTimer, &err); - assertOSError(err); + // OSTmrStart(&canWatchTimer, &err); + // assertOSError(err); // Fills buffers with disable messages // NOTE: If the buffer becomes bigger than of type int8_t, memset will not work and @@ -356,8 +356,8 @@ void Task_ReadCarCAN(void *p_arg){ } case BPS_CONTACTOR: { - OSTmrStart(&canWatchTimer, &err); // Restart CAN Watchdog timer for BPS Contactor msg - assertOSError(err); + // OSTmrStart(&canWatchTimer, &err); // Restart CAN Watchdog timer for BPS Contactor msg + // assertOSError(err); // Retrieving HV contactor statuses using bit mapping // Bitwise to get HV Plus and Minus, and then &&ing to ensure both are on @@ -374,12 +374,12 @@ void Task_ReadCarCAN(void *p_arg){ case SUPPLEMENTAL_VOLTAGE: { SBPV = (*(uint16_t *) &dataBuf.data); - UpdateDisplay_SetSBPV(SBPV); // Receive value in mV + // UpdateDisplay_SetSBPV(SBPV); // Receive value in mV break; } case STATE_OF_CHARGE:{ SOC = (*(uint32_t*) &dataBuf.data)/(SOC_SCALER); // Convert to integer percent - UpdateDisplay_SetSOC(SOC); + // UpdateDisplay_SetSOC(SOC); break; } default: { @@ -407,7 +407,7 @@ static void handler_ReadCarCAN_chargeDisable(void) { bool ret = (bool)Contactors_Get(ARRAY_PRECHARGE_BYPASS_CONTACTOR); if(ret) { // Contactor failed to turn off; display the evac screen and infinite loop - Display_Evac(SOC, SBPV); + // Display_Evac(SOC, SBPV); while(1){;} } } diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 02b71c6e2..222b00b7c 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -1,3 +1,4 @@ + /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file Tasks.c diff --git a/Drivers/Src/Contactors.c b/Drivers/Src/Contactors.c index 6b631a4c9..370eaece5 100644 --- a/Drivers/Src/Contactors.c +++ b/Drivers/Src/Contactors.c @@ -6,11 +6,11 @@ */ #include "Contactors.h" -//#include "stm32f4xx_gpio.h" -//#include "Tasks.h" +#include "Tasks.h" +#include "os.h" -//static OS_MUTEX contactorsMutex; +static OS_MUTEX contactorsMutex; /** * @brief Helper function for setting contactors without mutex. @@ -49,10 +49,10 @@ void Contactors_Init() { setContactor(contactor, OFF); } - // initialize mutex - //OS_ERR err; - //OSMutexCreate(&contactorsMutex, "Contactors lock", &err); - // assertOSError(err); + //initialize mutex + OS_ERR err; + OSMutexCreate(&contactorsMutex, "Contactors lock", &err); + assertOSError(err); } /** @@ -87,26 +87,26 @@ bool Contactors_Get(contactor_t contactor) { * @return Whether or not the contactor was successfully set */ ErrorStatus Contactors_Set(contactor_t contactor, bool state, bool blocking) { - //CPU_TS timestamp; - //OS_ERR err; + CPU_TS timestamp; + OS_ERR err; ErrorStatus result = ERROR; // acquire lock if its available - //OSMutexPend(&contactorsMutex, 0, blocking ? OS_OPT_PEND_BLOCKING : OS_OPT_PEND_NON_BLOCKING, ×tamp, &err); + OSMutexPend(&contactorsMutex, 0, blocking ? OS_OPT_PEND_BLOCKING : OS_OPT_PEND_NON_BLOCKING, ×tamp, &err); - //if(err == OS_ERR_PEND_WOULD_BLOCK){ - // return ERROR; - // } - // assertOSError(err); + if(err == OS_ERR_PEND_WOULD_BLOCK){ + return ERROR; + } + assertOSError(err); // change contactor to match state and make sure it worked setContactor(contactor, state); bool ret = (bool)Contactors_Get(contactor); result = (ret == state) ? SUCCESS: ERROR; - // release lock - // OSMutexPost(&contactorsMutex, OS_OPT_POST_NONE, &err); - // assertOSError(err); + //release lock + OSMutexPost(&contactorsMutex, OS_OPT_POST_NONE, &err); + assertOSError(err); return result; } diff --git a/Tests/Test_ReadCarCANrewrite.c b/Tests/Test_ReadCarCANrewrite.c index 8ce93c952..07d8af11d 100644 --- a/Tests/Test_ReadCarCANrewrite.c +++ b/Tests/Test_ReadCarCANrewrite.c @@ -42,6 +42,7 @@ enum { SEND_UNTIL_MOTOR_CONT_ON }; + /*** Constants ***/ #define SATURATION_THRESHOLD_TEST (((SAT_BUF_LENGTH + 1) * SAT_BUF_LENGTH) / 4) diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index 92e275d36..75941b499 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -22,6 +22,7 @@ C_SOURCES = \ Tests/Test_$(TEST).c \ Unity/unity.c \ $(wildcard ../../*/Src/$(TEST).c) \ +$(wildcard Mocks/RTOS/os.c) \ $(filter-out $(wildcard Mocks/*/Src/$(TEST).c), $(wildcard Mocks/*/Src/*.c)) @@ -75,8 +76,10 @@ SF = st-flash #$(filter-out $(wildcard Mocks/*/$(TEST).h), $(wildcard Mocks/*/Inc/*.h)) *Doesn't work since we can only include directories as search paths, not actual files C_INCLUDES := \ +-I../../Tests/UnitTests/Mocks/Apps/Inc \ -I../../Tests/UnitTests/Mocks/Drivers/Inc \ -I../../Tests/UnitTests/Mocks/BSP/Inc \ +-I../../Tests/UnitTests/Mocks/RTOS/ \ -I../../Apps/Inc \ -I../../Drivers/Inc \ -I../../Config/Inc \ diff --git a/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h b/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h new file mode 100644 index 000000000..f2be9de83 --- /dev/null +++ b/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h @@ -0,0 +1,32 @@ +#ifdef TEST_READCARCAN +#include_next "ReadCarCAN.h" // Include the next instance of the file. +// If the real version is in the include search paths after the mock one, it will include it here +#else // Mocked Contactors.h + +#ifndef __TASKS_H +#define __TASKS_H +#include "fff.h" + +DECLARE_FAKE_VOID_FUNC(Task_Init); + +DECLARE_FAKE_VOID_FUNC(Task_SendTritium); + +DECLARE_FAKE_VOID_FUNC(Task_ReadCarCAN); + +DECLARE_FAKE_VOID_FUNC(Task_UpdateDisplay); + +DECLARE_FAKE_VOID_FUNC(Task_ReadTritium); + +DECLARE_FAKE_VOID_FUNC(Task_SendCarCAN); + +DECLARE_FAKE_VOID_FUNC(Task_DebugDump); + +DECLARE_FAKE_VOID_FUNC(Task_CommandLine); + +DECLARE_FAKE_VOID_FUNC(TaskSwHook_Init); + +DECLARE_FAKE_VOID_FUNC(EmergencyContactorOpen); + +DECLARE_FAKE_VOID_FUNC(_assertOSError); +#endif +#endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Src/Tasks.c b/Tests/UnitTests/Mocks/Apps/Src/Tasks.c new file mode 100644 index 000000000..36ce78330 --- /dev/null +++ b/Tests/UnitTests/Mocks/Apps/Src/Tasks.c @@ -0,0 +1,24 @@ +#include "fff.h" +#include "Tasks.h" + +DEFINE_FAKE_VOID_FUNC(Task_Init); + +DEFINE_FAKE_VOID_FUNC(Task_SendTritium); + +DEFINE_FAKE_VOID_FUNC(Task_ReadCarCAN); + +DEFINE_FAKE_VOID_FUNC(Task_UpdateDisplay); + +DEFINE_FAKE_VOID_FUNC(Task_ReadTritium); + +DEFINE_FAKE_VOID_FUNC(Task_SendCarCAN); + +DEFINE_FAKE_VOID_FUNC(Task_DebugDump); + +DEFINE_FAKE_VOID_FUNC(Task_CommandLine); + +DEFINE_FAKE_VOID_FUNC(TaskSwHook_Init); + +DEFINE_FAKE_VOID_FUNC(EmergencyContactorOpen); + +DEFINE_FAKE_VOID_FUNC(_assertOSError); diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h b/Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h new file mode 100644 index 000000000..03323673f --- /dev/null +++ b/Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h @@ -0,0 +1,90 @@ +// #ifdef TEST_READCARCAN +// #include_next "ReadCarCAN.h" // Include the next instance of the file. +// // If the real version is in the include search paths after the mock one, it will include it here +// #else // Mocked Contactors.h + +#ifndef CAN_H__ +#define CAN_H__ + +#include "fff.h" +#include "BSP_CAN.h" + + +#define CARCAN CAN_1 //convenience aliases for the CANBuses +#define MOTORCAN CAN_3 + +/** + * This enum is used to signify the ID of the message you want to send. + * It is used internally to index our lookup table (CANLUT.C) and get message-specific fields. + * For user purposes, it selects the message to send. + * + * If changing the order of this enum, make sure to mirror that change in the lookup table, or + * else the driver will not work properly. + * + * If adding new types of CAN messages, add the identifier wherever it fits in + * (the enum is sorted in ascending order on purpose), and then add an entry to the lookup table. + */ +typedef enum { + BPS_TRIP = 0x002, + BPS_CONTACTOR = 0x101, + STATE_OF_CHARGE = 0x106, + SUPPLEMENTAL_VOLTAGE = 0x10B, + MOTOR_DRIVE = 0x221, + MOTOR_POWER = 0x222, + MOTOR_RESET = 0x223, + MOTOR_STATUS = 0x241, + MC_BUS = 0x242, + VELOCITY = 0x243, + MC_PHASE_CURRENT = 0x244, + VOLTAGE_VEC = 0x245, + CURRENT_VEC = 0x246, + BACKEMF = 0x247, + TEMPERATURE = 0x24B, + ODOMETER_AMPHOURS = 0x24E, + ARRAY_CONTACTOR_STATE_CHANGE = 0x24F, + CONTROL_MODE = 0x580, + IO_STATE = 0x581, + MAX_CAN_ID +} CANId_t; + +/** + * @brief Struct to use in CAN MSG LUT + * @param idxEn Whether or not this message is part of a sequence of messages. + * @param size Size of message's data. Should be a maximum of eight (in decimal). + */ +typedef struct { + bool idxEn: 1; + unsigned int size: 7; +} CANLUT_T; + +/** + * Standard CAN packet + * @param ID CANId_t value indicating which message we are trying to send + * @param idx If message is part of a sequence of messages (for messages longer than 64 bits), this indicates the index of the message. + * This is not designed to exceed the 8bit unsigned max value. + * @param data data of the message +*/ +typedef struct { + CANId_t ID; + uint8_t idx; + uint8_t data[8]; +} CANDATA_t; + +/** + * Standard identifier for whether or not a CAN transaction is blocking or not + * (DEPRECATED) + */ +// typedef enum {CAN_BLOCKING=0, CAN_NON_BLOCKING} CAN_blocking_t; + +//Compatibility macros for deprecated enum +#define CAN_BLOCKING true +#define CAN_NON_BLOCKING false + +DECLARE_FAKE_VALUE_FUNC(ErrorStatus, CANbus_Init, CAN_t, CANId_t*, uint8_t); + +DECLARE_FAKE_VALUE_FUNC(ErrorStatus, CANbus_Send, CANDATA_t, bool, CAN_t); + +DECLARE_FAKE_VALUE_FUNC(ErrorStatus, CANbus_Read, CANDATA_t*, bool, CAN_t); + +#endif +// #endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h b/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h index e07a6354c..2ab84fe3d 100644 --- a/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h +++ b/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h @@ -7,6 +7,7 @@ #include "fff.h" #include "common.h" #include "stm32f4xx_gpio.h" +#include "os.h" #define CONTACTORS_PORT PORTC #define ARRAY_PRECHARGE_BYPASS_PIN GPIO_Pin_10 @@ -22,7 +23,7 @@ typedef enum contactor_ENUM { }contactor_t; DECLARE_FAKE_VOID_FUNC(Contactors_Init); -DECLARE_FAKE_VALUE_FUNC(bool, Contactors_Get); +DECLARE_FAKE_VALUE_FUNC(bool, Contactors_Get, contactor_t); DECLARE_FAKE_VALUE_FUNC(ErrorStatus, Contactors_Set, contactor_t, bool, bool); #endif diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h b/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h new file mode 100644 index 000000000..3bbc17e8c --- /dev/null +++ b/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h @@ -0,0 +1,41 @@ +#ifdef TEST_READCARCAN +#include_next "ReadCarCAN.h" // Include the next instance of the file. +// If the real version is in the include search paths after the mock one, it will include it here +#else // Mocked Contactors.h +#ifndef MINIONS_H +#define MINIONS_H +#include "fff.h" +#include "common.h" +#include +#include "BSP_GPIO.h" + + +// used to index into lookup table +// if changed, PINS_LOOKARR should be changed in Minions.c +#define FOREACH_PIN(PIN) \ + PIN(IGN_1), \ + PIN(IGN_2), \ + PIN(REGEN_SW), \ + PIN(FOR_SW), \ + PIN(REV_SW), \ + PIN(CRUZ_EN), \ + PIN(CRUZ_ST), \ + PIN(BRAKELIGHT), \ + +typedef enum MINIONPIN_ENUM { + FOREACH_PIN(GENERATE_ENUM) + NUM_PINS, +} pin_t; + +typedef struct { + uint16_t pinMask; + port_t port; + direction_t direction; +} pinInfo_t; + +DECLARE_FAKE_VOID_FUNC(Minions_Init); + +DECLARE_FAKE_VALUE_FUNC(bool, Minions_Read, pin_t); + +#endif +#endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Src/CANbus.c b/Tests/UnitTests/Mocks/Drivers/Src/CANbus.c new file mode 100644 index 000000000..fc2a7c56b --- /dev/null +++ b/Tests/UnitTests/Mocks/Drivers/Src/CANbus.c @@ -0,0 +1,8 @@ +#include "fff.h" +#include "CANbus.h" + +DEFINE_FAKE_VALUE_FUNC(ErrorStatus, CANbus_Init, CAN_t, CANId_t*, uint8_t); + +DEFINE_FAKE_VALUE_FUNC(ErrorStatus, CANbus_Send, CANDATA_t, bool, CAN_t); + +DEFINE_FAKE_VALUE_FUNC(ErrorStatus, CANbus_Read, CANDATA_t*, bool, CAN_t); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c b/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c index 5dd675955..3bad0c4d7 100644 --- a/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c +++ b/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c @@ -2,5 +2,5 @@ #include "Contactors.h" DEFINE_FAKE_VOID_FUNC(Contactors_Init); -DEFINE_FAKE_VALUE_FUNC(bool, Contactors_Get); +DEFINE_FAKE_VALUE_FUNC(bool, Contactors_Get, contactor_t); DEFINE_FAKE_VALUE_FUNC(ErrorStatus, Contactors_Set, contactor_t, bool, bool); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Src/Minions.c b/Tests/UnitTests/Mocks/Drivers/Src/Minions.c new file mode 100644 index 000000000..4c47da5f1 --- /dev/null +++ b/Tests/UnitTests/Mocks/Drivers/Src/Minions.c @@ -0,0 +1,6 @@ +#include "fff.h" +#include "Minions.h" + +DEFINE_FAKE_VOID_FUNC(Minions_Init); + +DEFINE_FAKE_VALUE_FUNC(bool, Minions_Read, pin_t); diff --git a/Tests/UnitTests/Mocks/RTOS/cpu.h b/Tests/UnitTests/Mocks/RTOS/cpu.h new file mode 100644 index 000000000..e09c037ff --- /dev/null +++ b/Tests/UnitTests/Mocks/RTOS/cpu.h @@ -0,0 +1,387 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* (c) Copyright 2004-2015; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/CPU is provided in source form to registered licensees ONLY. It is +* illegal to distribute this source code to any third party unless you receive +* written permission by an authorized Micrium representative. Knowledge of +* the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +* +* You can find our product's user manual, API reference, release notes and +* more information at https://doc.micrium.com. +* You can contact us at www.micrium.com. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU PORT FILE +* +* ARM-Cortex-M4 +* GNU C Compiler +* +* Filename : cpu.h +* Version : V1.30.02.00 +* Programmer(s) : JJL +* BAN +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of +* the CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_MODULE_PRESENT /* See Note #1. */ +#define CPU_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU INCLUDE FILES +* +* Note(s) : (1) The following CPU files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_def.h +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (2) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from +* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. +* +* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric +* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to +* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). +********************************************************************************************************* +*/ + +#include +//#include /* See Note #3. */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +********************************************************************************************************* +* CONFIGURE STANDARD DATA TYPES +* +* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. +* +* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has no arguments. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_VOID FnctName; +* +* FnctName(); +* +* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer +* data type of a pointer to a function which returns void & has a single void +* pointer argument. +* +* (2) Example function pointer usage : +* +* CPU_FNCT_PTR FnctName; +* void *p_obj +* +* FnctName(p_obj); +********************************************************************************************************* +*/ + +typedef void CPU_VOID; +typedef char CPU_CHAR; /* 8-bit character */ +typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ +typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ +typedef signed char CPU_INT08S; /* 8-bit signed integer */ +typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ +typedef signed short CPU_INT16S; /* 16-bit signed integer */ +typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ +typedef signed int CPU_INT32S; /* 32-bit signed integer */ +typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ +typedef signed long long CPU_INT64S; /* 64-bit signed integer */ + +typedef float CPU_FP32; /* 32-bit floating point */ +typedef double CPU_FP64; /* 64-bit floating point */ + + +typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ +typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ +typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ +typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ + + +typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ +typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or +* compiler's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* Define CPU word sizes (see Note #1) : */ +#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ +#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ +#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ + +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ + + +/* +********************************************************************************************************* +* CONFIGURE CPU ADDRESS & DATA TYPES +********************************************************************************************************* +*/ + + /* CPU address type based on address bus size. */ +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_ADDR; +#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_ADDR; +#else +typedef CPU_INT08U CPU_ADDR; +#endif + + /* CPU data type based on data bus size. */ +#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) +typedef CPU_INT32U CPU_DATA; +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_DATA; +#else +typedef CPU_INT08U CPU_DATA; +#endif + + +typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ +typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +* +* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for +* cpu stacks. +* +* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. +********************************************************************************************************* +*/ + +#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ + +#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ + +typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ +typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if +* used, MUST be declared following ALL other local variables. +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + /* Configure CPU critical method (see Note #1) : */ +#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL + +typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ + + /* Allocates CPU status register word (see Note #3a). */ +#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) +#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 +#else +#define CPU_SR_ALLOC() +#endif + + + +#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ +#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + /* Disable interrupts, ... */ + /* & start interrupts disabled time measurement.*/ +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ + CPU_IntDisMeasStart(); } while (0) + /* Stop & measure interrupts disabled time, */ + /* ... & re-enable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ + CPU_INT_EN(); } while (0) + +#else + +#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ +#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ + +#endif + + +/* +********************************************************************************************************* +* MEMORY BARRIERS CONFIGURATION +* +* Note(s) : (1) (a) Configure memory barriers if required by the architecture. +* +* CPU_MB Full memory barrier. +* CPU_RMB Read (Loads) memory barrier. +* CPU_WMB Write (Stores) memory barrier. +* +********************************************************************************************************* +*/ + +#define CPU_MB() __asm__ __volatile__ ("dsb" : : : "memory") +#define CPU_RMB() __asm__ __volatile__ ("dsb" : : : "memory") +#define CPU_WMB() __asm__ __volatile__ ("dsb" : : : "memory") + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + + /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ + + /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ + +#endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/RTOS/cpu_cfg.h b/Tests/UnitTests/Mocks/RTOS/cpu_cfg.h new file mode 100644 index 000000000..90c45ffc9 --- /dev/null +++ b/Tests/UnitTests/Mocks/RTOS/cpu_cfg.h @@ -0,0 +1,215 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* (c) Copyright 2004-2015; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/CPU is provided in source form to registered licensees ONLY. It is +* illegal to distribute this source code to any third party unless you receive +* written permission by an authorized Micrium representative. Knowledge of +* the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +* +* You can find our product's user manual, API reference, release notes and +* more information at https://doc.micrium.com. +* You can contact us at www.micrium.com. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU CONFIGURATION FILE +* +* TEMPLATE +* +* Filename : cpu_cfg.h +* Version : V1.30.02 +* Programmer(s) : SR +* ITJ +* JBL +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +********************************************************************************************************* +*/ + +#ifndef CPU_CFG_MODULE_PRESENT +#define CPU_CFG_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CPU NAME CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_NAME_EN to enable/disable CPU host name feature : +* +* (a) CPU host name storage +* (b) CPU host name API functions +* +* (2) Configure CPU_CFG_NAME_SIZE with the desired ASCII string size of the CPU host name, +* including the terminating NULL character. +* +* See also 'cpu_core.h GLOBAL VARIABLES Note #1'. +********************************************************************************************************* +*/ + + /* Configure CPU host name feature (see Note #1) : */ +#define CPU_CFG_NAME_EN DEF_ENABLED + /* DEF_DISABLED CPU host name DISABLED */ + /* DEF_ENABLED CPU host name ENABLED */ + + /* Configure CPU host name ASCII string size ... */ +#define CPU_CFG_NAME_SIZE 16 /* ... (see Note #2). */ + + +/* +********************************************************************************************************* +* CPU TIMESTAMP CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_TS_xx_EN to enable/disable CPU timestamp features : +* +* (a) CPU_CFG_TS_32_EN enable/disable 32-bit CPU timestamp feature +* (b) CPU_CFG_TS_64_EN enable/disable 64-bit CPU timestamp feature +* +* (2) (a) Configure CPU_CFG_TS_TMR_SIZE with the CPU timestamp timer's word size : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (b) If the size of the CPU timestamp timer is not a binary multiple of 8-bit octets +* (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple octet word +* size SHOULD be configured (e.g. to 16-bits). However, the minimum supported word +* size for CPU timestamp timers is 8-bits. +* +* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2a'. +********************************************************************************************************* +*/ + + /* Configure CPU timestamp features (see Note #1) : */ +#define CPU_CFG_TS_32_EN DEF_ENABLED +#define CPU_CFG_TS_64_EN DEF_DISABLED + /* DEF_DISABLED CPU timestamps DISABLED */ + /* DEF_ENABLED CPU timestamps ENABLED */ + + /* Configure CPU timestamp timer word size ... */ + /* ... (see Note #2) : */ +#define CPU_CFG_TS_TMR_SIZE CPU_WORD_SIZE_32 + + +/* +********************************************************************************************************* +* CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_INT_DIS_MEAS_EN to enable/disable measuring CPU's interrupts +* disabled time : +* +* (a) Enabled, if CPU_CFG_INT_DIS_MEAS_EN #define'd in 'cpu_cfg.h' +* +* (b) Disabled, if CPU_CFG_INT_DIS_MEAS_EN NOT #define'd in 'cpu_cfg.h' +* +* See also 'cpu_core.h FUNCTION PROTOTYPES Note #1'. +* +* (b) Configure CPU_CFG_INT_DIS_MEAS_OVRHD_NBR with the number of times to measure & +* average the interrupts disabled time measurements overhead. +* +* See also 'cpu_core.c CPU_IntDisMeasInit() Note #3a'. +********************************************************************************************************* +*/ + +#if 1 /* Configure CPU interrupts disabled time ... */ +#define CPU_CFG_INT_DIS_MEAS_EN /* ... measurements feature (see Note #1a). */ +#endif + + /* Configure number of interrupts disabled overhead ... */ +#define CPU_CFG_INT_DIS_MEAS_OVRHD_NBR 1u /* ... time measurements (see Note #1b). */ + + +/* +********************************************************************************************************* +* CPU COUNT ZEROS CONFIGURATION +* +* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +* +* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits +* function(s) in : +* +* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable assembly-optimized function(s) +* +* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ +* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise +********************************************************************************************************* +*/ + +#if 1 /* Configure CPU count leading zeros bits ... */ +#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ +#endif + +#if 0 /* Configure CPU count trailing zeros bits ... */ +#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ +#endif + + +/* +********************************************************************************************************* +* CPU ENDIAN TYPE OVERRIDE +* +* Note(s) : (1) Configure CPU_CFG_ENDIAN_TYPE to override the default CPU endian type defined in cpu.h. +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +* +* (2) Defining CPU_CFG_ENDIAN_TYPE here is only valid for supported bi-endian architectures. +* See 'cpu.h CPU WORD CONFIGURATION Note #3' for details +********************************************************************************************************* +*/ + +#if 0 +#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ +#endif + + +/* +********************************************************************************************************* +* CACHE MANAGEMENT +* +* Note(s) : (1) Configure CPU_CFG_CACHE_MGMT_EN to enable the cache managment API. + +* +* (2) Defining CPU_CFG_CACHE_MGMT_EN to DEF_ENABLED only enable the cache management function. +* Cache are assumed to be configured and enabled by the time CPU_init() is called. +********************************************************************************************************* +*/ + +#define CPU_CFG_CACHE_MGMT_EN DEF_DISABLED /* Defines CPU data word-memory order (see Note #1). */ + + +/* +********************************************************************************************************* +* MODULE END +********************************************************************************************************* +*/ + +#endif /* End of CPU cfg module include. */ + diff --git a/Tests/UnitTests/Mocks/RTOS/cpu_core.h b/Tests/UnitTests/Mocks/RTOS/cpu_core.h new file mode 100644 index 000000000..471d136c0 --- /dev/null +++ b/Tests/UnitTests/Mocks/RTOS/cpu_core.h @@ -0,0 +1,491 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* (c) Copyright 2004-2015; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/CPU is provided in source form to registered licensees ONLY. It is +* illegal to distribute this source code to any third party unless you receive +* written permission by an authorized Micrium representative. Knowledge of +* the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +* +* You can find our product's user manual, API reference, release notes and +* more information at https://doc.micrium.com. +* You can contact us at www.micrium.com. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CORE CPU MODULE +* +* Filename : cpu_core.h +* Version : V1.30.02 +* Programmer(s) : SR +* ITJ +********************************************************************************************************* +* Note(s) : (1) Assumes the following versions (or more recent) of software modules are included in +* the project build : +* +* (a) uC/LIB V1.35.00 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This core CPU header file is protected from multiple pre-processor inclusion through use of +* the core CPU module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_CORE_MODULE_PRESENT /* See Note #1. */ +#define CPU_CORE_MODULE_PRESENT + + +/* +********************************************************************************************************* +* EXTERNS +********************************************************************************************************* +*/ + +#ifdef CPU_CORE_MODULE +#define CPU_CORE_EXT +#else +#define CPU_CORE_EXT extern +#endif + + +/* +********************************************************************************************************* +* INCLUDE FILES +* +* Note(s) : (1) CPU-configuration software files are located in the following directories : +* +* (a) \\cpu_cfg.h +* +* (b) (1) \\cpu_*.* +* (2) \\\\cpu*.* +* +* where +* directory path for Your Product's Application +* directory path for common CPU-compiler software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (2) NO compiler-supplied standard library functions SHOULD be used. +* +* (a) Standard library functions are implemented in the custom library module(s) : +* +* \\lib_*.* +* +* where +* directory path for custom library software +* +* (3) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #1b1 +* (2) '\\\\' directory See Note #1b2 +* +* (c) '\\' directory See Note #2a +********************************************************************************************************* +*/ + +#include +//#include +#include + +#if (CPU_CFG_NAME_EN == DEF_ENABLED) +// #include +// #include +#endif + + +/* +********************************************************************************************************* +* CPU CONFIGURATION +* +* Note(s) : (1) The following pre-processor directives correctly configure CPU parameters. DO NOT MODIFY. +* +* (2) CPU timestamp timer feature is required for : +* +* (a) CPU timestamps +* (b) CPU interrupts disabled time measurement +* +* See also 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1' +* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1'. +********************************************************************************************************* +*/ + +#ifdef CPU_CFG_TS_EN +#undef CPU_CFG_TS_EN +#endif + + +#if ((CPU_CFG_TS_32_EN == DEF_ENABLED) || \ + (CPU_CFG_TS_64_EN == DEF_ENABLED)) +#define CPU_CFG_TS_EN DEF_ENABLED +#else +#define CPU_CFG_TS_EN DEF_DISABLED +#endif + +#if ((CPU_CFG_TS_EN == DEF_ENABLED) || \ +(defined(CPU_CFG_INT_DIS_MEAS_EN))) +#define CPU_CFG_TS_TMR_EN DEF_ENABLED +#else +#define CPU_CFG_TS_TMR_EN DEF_DISABLED +#endif + +/* +********************************************************************************************************* +* CACHE CONFIGURATION +* +* Note(s) : (1) The following pre-processor directives correctly configure CACHE parameters. DO NOT MODIFY. +* +********************************************************************************************************** +*/ + +#ifndef CPU_CFG_CACHE_MGMT_EN +#define CPU_CFG_CACHE_MGMT_EN DEF_DISABLED +#endif + + +/* +********************************************************************************************************* +* DEFINES +********************************************************************************************************* +*/ + +#define CPU_TIME_MEAS_NBR_MIN 1u +#define CPU_TIME_MEAS_NBR_MAX 128u + + +/* +********************************************************************************************************* +* DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CPU ERROR CODES +********************************************************************************************************* +*/ + +typedef enum cpu_err { + + CPU_ERR_NONE = 0u, + CPU_ERR_NULL_PTR = 10u, + + CPU_ERR_NAME_SIZE = 1000u, + + CPU_ERR_TS_FREQ_INVALID = 2000u + +} CPU_ERR; + + +/* +********************************************************************************************************* +* CPU TIMESTAMP DATA TYPES +* +* Note(s) : (1) CPU timestamp timer data type defined to the binary-multiple of 8-bit octets as configured +* by 'CPU_CFG_TS_TMR_SIZE' (see 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #2'). +********************************************************************************************************* +*/ + +typedef CPU_INT32U CPU_TS32; +typedef CPU_INT64U CPU_TS64; + +typedef CPU_TS32 CPU_TS; /* Req'd for backwards-compatibility. */ + + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) /* CPU ts tmr defined to cfg'd word size (see Note #1). */ +#if (CPU_CFG_TS_TMR_SIZE == CPU_WORD_SIZE_08) +typedef CPU_INT08U CPU_TS_TMR; +#elif (CPU_CFG_TS_TMR_SIZE == CPU_WORD_SIZE_16) +typedef CPU_INT16U CPU_TS_TMR; +#elif (CPU_CFG_TS_TMR_SIZE == CPU_WORD_SIZE_64) +typedef CPU_INT64U CPU_TS_TMR; +#else /* CPU ts tmr dflt size = 32-bits. */ +typedef CPU_INT32U CPU_TS_TMR; +#endif +#endif + + +/* +********************************************************************************************************* +* CPU TIMESTAMP TIMER FREQUENCY DATA TYPE +********************************************************************************************************* +*/ + +typedef CPU_INT32U CPU_TS_TMR_FREQ; + + +/* +********************************************************************************************************* +* GLOBAL VARIABLES +********************************************************************************************************* +*/ + +#if (CPU_CFG_NAME_EN == DEF_ENABLED) +CPU_CORE_EXT CPU_CHAR CPU_Name[CPU_CFG_NAME_SIZE]; /* CPU host name. */ +#endif + + +#if ((CPU_CFG_TS_32_EN == DEF_ENABLED) && \ + (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)) +CPU_CORE_EXT CPU_TS32 CPU_TS_32_Accum; /* 32-bit accum'd ts (in ts tmr cnts). */ +CPU_CORE_EXT CPU_TS_TMR CPU_TS_32_TmrPrev; /* 32-bit ts prev tmr (in ts tmr cnts). */ +#endif + +#if ((CPU_CFG_TS_64_EN == DEF_ENABLED) && \ + (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64)) +CPU_CORE_EXT CPU_TS64 CPU_TS_64_Accum; /* 64-bit accum'd ts (in ts tmr cnts). */ +CPU_CORE_EXT CPU_TS_TMR CPU_TS_64_TmrPrev; /* 64-bit ts prev tmr (in ts tmr cnts). */ +#endif + +#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) +CPU_CORE_EXT CPU_TS_TMR_FREQ CPU_TS_TmrFreq_Hz; /* CPU ts tmr freq (in Hz). */ +#endif + + +#ifdef CPU_CFG_INT_DIS_MEAS_EN +CPU_CORE_EXT CPU_INT16U CPU_IntDisMeasCtr; /* Nbr tot ints dis'd ctr. */ +CPU_CORE_EXT CPU_INT16U CPU_IntDisNestCtr; /* Nbr nested ints dis'd ctr. */ + /* Ints dis'd time (in ts tmr cnts) : ... */ +CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasStart_cnts; /* ... start time. */ +CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasStop_cnts; /* ... stop time. */ +CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasOvrhd_cnts; /* ... time meas ovrhd. */ +CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasMaxCur_cnts; /* ... resetable max time dis'd. */ +CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasMax_cnts; /* ... non-resetable max time dis'd. */ +#endif + + +/* +********************************************************************************************************* +* MACRO'S +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* CPU_SW_EXCEPTION() +* +* Description : Trap unrecoverable software exception. +* +* Argument(s) : err_rtn_val Error type &/or value of the calling function to return (see Note #2b). +* +* Return(s) : none. +* +* Caller(s) : various. +* +* Note(s) : (1) CPU_SW_EXCEPTION() deadlocks the current code execution -- whether multi-tasked/ +* -processed/-threaded or single-threaded -- when the current code execution cannot +* gracefully recover or report a fault or exception condition. +* +* Example CPU_SW_EXCEPTION() call : +* +* void Fnct (CPU_ERR *p_err) +* { +* : +* +* if (p_err == (CPU_ERR *)0) { If 'p_err' NULL, cannot return error ... +* CPU_SW_EXCEPTION(;); ... so trap invalid argument exception. +* } +* +* : +* } +* +* See also 'cpu_core.c CPU_SW_Exception() Note #1'. +* +* (2) (a) CPU_SW_EXCEPTION() MAY be developer-implemented to output &/or handle any error or +* exception conditions; but since CPU_SW_EXCEPTION() is intended to trap unrecoverable +* software conditions, it is recommended that developer-implemented versions prevent +* execution of any code following calls to CPU_SW_EXCEPTION() by deadlocking the code +* (see Note #1). +* +* Example CPU_SW_EXCEPTION() : +* +* #define CPU_SW_EXCEPTION(err_rtn_val) do { \ +* Log(__FILE__, __LINE__); \ +* CPU_SW_Exception(); \ +* } while (0) +* +* (b) (1) However, if execution of code following calls to CPU_SW_EXCEPTION() is required +* (e.g. for automated testing); it is recommended that the last statement in +* developer-implemented versions be to return from the current function to prevent +* possible software exception(s) in the current function from triggering CPU &/or +* hardware exception(s). +* +* Example CPU_SW_EXCEPTION() : +* +* #define CPU_SW_EXCEPTION(err_rtn_val) do { \ +* Log(__FILE__, __LINE__); \ +* return err_rtn_val; \ +* } while (0) +* +* (A) Note that 'err_rtn_val' in the return statement MUST NOT be enclosed in +* parentheses. This allows CPU_SW_EXCEPTION() to return from functions that +* return 'void', i.e. NO return type or value (see also Note #2b2A). +* +* (2) In order for CPU_SW_EXCEPTION() to return from functions with various return +* types/values, each caller function MUST pass an appropriate error return type +* & value to CPU_SW_EXCEPTION(). +* +* (A) Note that CPU_SW_EXCEPTION() MUST NOT be passed any return type or value +* for functions that return 'void', i.e. NO return type or value; but SHOULD +* instead be passed a single semicolon. This prevents possible compiler +* warnings that CPU_SW_EXCEPTION() is passed too few arguments. However, +* the compiler may warn that CPU_SW_EXCEPTION() does NOT prevent creating +* null statements on lines with NO other code statements. +* +* Example CPU_SW_EXCEPTION() calls : +* +* void Fnct (CPU_ERR *p_err) +* { +* : +* +* if (p_err == (CPU_ERR *)0) { +* CPU_SW_EXCEPTION(;); Exception macro returns NO value +* } (see Note #2b2A) +* +* : +* } +* +* CPU_BOOLEAN Fnct (CPU_ERR *p_err) +* { +* : +* +* if (p_err == (CPU_ERR *)0) { +* CPU_SW_EXCEPTION(DEF_FAIL); Exception macro returns 'DEF_FAIL' +* } +* +* : +* } +* +* OBJ *Fnct (CPU_ERR *p_err) +* { +* : +* +* if (p_err == (CPU_ERR *)0) { +* CPU_SW_EXCEPTION((OBJ *)0); Exception macro returns NULL 'OBJ *' +* } +* +* : +* } +* +********************************************************************************************************* +*/ + +#ifndef CPU_SW_EXCEPTION /* See Note #2. */ +#define CPU_SW_EXCEPTION(err_rtn_val) do { \ + CPU_SW_Exception(); \ + } while (0) +#endif + + +/* +********************************************************************************************************* +* CPU_VAL_UNUSED() +* +* Description : +* +* Argument(s) : none. +* +* Return(s) : none. +* +* Caller(s) : #### various. +* +* Note(s) : none. +********************************************************************************************************* +*/ + + +#define CPU_VAL_UNUSED(val) ((void)&(val)); + + +#define CPU_VAL_IGNORED(val) CPU_VAL_UNUSED(val) + + +/* +********************************************************************************************************* +* CPU_TYPE_CREATE() +* +* Description : Creates a generic type value. +* +* Argument(s) : char_1 1st ASCII character to create generic type value. +* +* char_2 2nd ASCII character to create generic type value. +* +* char_3 3rd ASCII character to create generic type value. +* +* char_4 4th ASCII character to create generic type value. +* +* Return(s) : 32-bit generic type value. +* +* Caller(s) : various. +* +* Note(s) : (1) (a) Generic type values should be #define'd with large, non-trivial values to trap +* & discard invalid/corrupted objects based on type value. +* +* In other words, by assigning large, non-trivial values to valid objects' type +* fields; the likelihood that an object with an unassigned &/or corrupted type +* field will contain a value is highly improbable & therefore the object itself +* will be trapped as invalid. +* +* (b) (1) CPU_TYPE_CREATE() creates a 32-bit type value from four values. +* +* (2) Ideally, generic type values SHOULD be created from 'CPU_CHAR' characters to +* represent ASCII string abbreviations of the specific object types. Memory +* displays of object type values will display the specific object types with +* their chosen ASCII names. +* +* Examples : +* +* #define FILE_TYPE CPU_TYPE_CREATE('F', 'I', 'L', 'E') +* #define BUF_TYPE CPU_TYPE_CREATE('B', 'U', 'F', ' ') +********************************************************************************************************* +*/ + +#if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG) +#define CPU_TYPE_CREATE(char_1, char_2, char_3, char_4) (((CPU_INT32U)((CPU_INT08U)(char_1)) << (3u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_2)) << (2u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_3)) << (1u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_4)))) + +#else + +#if ((CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_64) || \ + (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32)) +#define CPU_TYPE_CREATE(char_1, char_2, char_3, char_4) (((CPU_INT32U)((CPU_INT08U)(char_1))) | \ + ((CPU_INT32U)((CPU_INT08U)(char_2)) << (1u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_3)) << (2u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_4)) << (3u * DEF_OCTET_NBR_BITS))) + + +#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) +#define CPU_TYPE_CREATE(char_1, char_2, char_3, char_4) (((CPU_INT32U)((CPU_INT08U)(char_1)) << (2u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_2)) << (3u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_3))) | \ + ((CPU_INT32U)((CPU_INT08U)(char_4)) << (1u * DEF_OCTET_NBR_BITS))) + +#else /* Dflt CPU_WORD_SIZE_08. */ +#define CPU_TYPE_CREATE(char_1, char_2, char_3, char_4) (((CPU_INT32U)((CPU_INT08U)(char_1)) << (3u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_2)) << (2u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_3)) << (1u * DEF_OCTET_NBR_BITS)) | \ + ((CPU_INT32U)((CPU_INT08U)(char_4)))) +#endif +#endif +#endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/RTOS/cpu_def.h b/Tests/UnitTests/Mocks/RTOS/cpu_def.h new file mode 100644 index 000000000..c22fa41d0 --- /dev/null +++ b/Tests/UnitTests/Mocks/RTOS/cpu_def.h @@ -0,0 +1,220 @@ +/* +********************************************************************************************************* +* uC/CPU +* CPU CONFIGURATION & PORT LAYER +* +* (c) Copyright 2004-2015; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/CPU is provided in source form to registered licensees ONLY. It is +* illegal to distribute this source code to any third party unless you receive +* written permission by an authorized Micrium representative. Knowledge of +* the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +* +* You can find our product's user manual, API reference, release notes and +* more information at https://doc.micrium.com. +* You can contact us at www.micrium.com. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CPU CONFIGURATION DEFINES +* +* Filename : cpu_def.h +* Version : V1.30.02 +* Programmer(s) : ITJ +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This CPU definition header file is protected from multiple pre-processor inclusion +* through use of the CPU definition module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef CPU_DEF_MODULE_PRESENT +#define CPU_DEF_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CORE CPU MODULE VERSION NUMBER +* +* Note(s) : (1) (a) The core CPU module software version is denoted as follows : +* +* Vx.yy.zz +* +* where +* V denotes 'Version' label +* x denotes major software version revision number +* yy denotes minor software version revision number +* zz denotes sub-minor software version revision number +* +* (b) The software version label #define is formatted as follows : +* +* ver = x.yyzz * 100 * 100 +* +* where +* ver denotes software version number scaled as an integer value +* x.yyzz denotes software version number, where the unscaled integer +* portion denotes the major version number & the unscaled +* fractional portion denotes the (concatenated) minor +* version numbers +********************************************************************************************************* +*/ + +#define CPU_CORE_VERSION 13002u /* See Note #1. */ + + +/* +********************************************************************************************************* +* CPU WORD CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE & CPU_CFG_DATA_SIZE in 'cpu.h' with CPU's word sizes : +* +* CPU_WORD_SIZE_08 8-bit word size +* CPU_WORD_SIZE_16 16-bit word size +* CPU_WORD_SIZE_32 32-bit word size +* CPU_WORD_SIZE_64 64-bit word size +* +* (2) Configure CPU_CFG_ENDIAN_TYPE in 'cpu.h' with CPU's data-word-memory order : +* +* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant +* octet @ lowest memory address) +* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant +* octet @ lowest memory address) +********************************************************************************************************* +*/ + + /* ---------------------- CPU WORD SIZE ----------------------- */ +#define CPU_WORD_SIZE_08 1u /* 8-bit word size (in octets). */ +#define CPU_WORD_SIZE_16 2u /* 16-bit word size (in octets). */ +#define CPU_WORD_SIZE_32 4u /* 32-bit word size (in octets). */ +#define CPU_WORD_SIZE_64 8u /* 64-bit word size (in octets). */ + + + /* ------------------ CPU WORD-ENDIAN ORDER ------------------- */ +#define CPU_ENDIAN_TYPE_NONE 0u +#define CPU_ENDIAN_TYPE_BIG 1u /* Big- endian word order (see Note #1a). */ +#define CPU_ENDIAN_TYPE_LITTLE 2u /* Little-endian word order (see Note #1b). */ + + +/* +********************************************************************************************************* +* CPU STACK CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : +* +* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack +* memory address after data is pushed onto the stack +* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack +* memory address after data is pushed onto the stack +********************************************************************************************************* +*/ + + /* ------------------ CPU STACK GROWTH ORDER ------------------ */ +#define CPU_STK_GROWTH_NONE 0u +#define CPU_STK_GROWTH_LO_TO_HI 1u /* CPU stk incs towards higher mem addrs (see Note #1a). */ +#define CPU_STK_GROWTH_HI_TO_LO 2u /* CPU stk decs towards lower mem addrs (see Note #1b). */ + + +/* +********************************************************************************************************* +* CRITICAL SECTION CONFIGURATION +* +* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : +* +* Enter/Exit critical sections by ... +* +* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts +* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack +* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable +* +* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support +* multiple levels of interrupts. However, with some CPUs/compilers, this is the only +* available method. +* +* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Push/save interrupt status onto a local stack +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Pop/restore interrupt status from a local stack +* +* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple +* levels of interrupts. However, this method assumes that the compiler provides C-level +* &/or assembly-level functionality for the following : +* +* ENTER CRITICAL SECTION : +* (1) Save interrupt status into a local variable +* (2) Disable interrupts +* +* EXIT CRITICAL SECTION : +* (3) Restore interrupt status from a local variable +* +* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT +* allow inline assembly in C source files, critical section macro's MUST call an assembly +* subroutine defined in a 'cpu_a.asm' file located in the following software directory : +* +* \\\\ +* +* where +* directory path for common CPU-compiler software +* directory name for specific CPU +* directory name for specific compiler +* +* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need +* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). +* +* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, +* if used, MUST be declared following ALL other local variables (see any 'cpu.h +* CRITICAL SECTION CONFIGURATION Note #3a1'). +* +* Example : +* +* void Fnct (void) +* { +* CPU_INT08U val_08; +* CPU_INT16U val_16; +* CPU_INT32U val_32; +* CPU_SR_ALLOC(); MUST be declared after ALL other local variables +* : +* : +* } +* +* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to +* completely store the CPU's/compiler's status word. +********************************************************************************************************* +*/ + + /* --------------- CPU CRITICAL SECTION METHODS --------------- */ +#define CPU_CRITICAL_METHOD_NONE 0u /* */ +#define CPU_CRITICAL_METHOD_INT_DIS_EN 1u /* DIS/EN ints (see Note #1a). */ +#define CPU_CRITICAL_METHOD_STATUS_STK 2u /* Push/Pop int status onto stk (see Note #1b). */ +#define CPU_CRITICAL_METHOD_STATUS_LOCAL 3u /* Save/Restore int status to local var (see Note #1c). */ + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'cpu_def.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of CPU def module include. */ + diff --git a/Tests/UnitTests/Mocks/RTOS/lib_def.h b/Tests/UnitTests/Mocks/RTOS/lib_def.h new file mode 100644 index 000000000..9b920dec1 --- /dev/null +++ b/Tests/UnitTests/Mocks/RTOS/lib_def.h @@ -0,0 +1,1344 @@ +/* +********************************************************************************************************* +* uC/LIB +* CUSTOM LIBRARY MODULES +* +* (c) Copyright 2004-2014; Micrium, Inc.; Weston, FL +* +* All rights reserved. Protected by international copyright laws. +* +* uC/LIB is provided in source form to registered licensees ONLY. It is +* illegal to distribute this source code to any third party unless you receive +* written permission by an authorized Micrium representative. Knowledge of +* the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the Embedded community with the finest +* software available. Your honesty is greatly appreciated. +* +* You can find our product's user manual, API reference, release notes and +* more information at: https://doc.micrium.com +* +* You can contact us at: http://www.micrium.com +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* +* CORE CUSTOM LIBRARY MODULE +* +* Filename : lib_def.h +* Version : V1.38.01 +* Programmer(s) : ITJ +* FBJ +* JFD +********************************************************************************************************* +* Note(s) : (1) Assumes the following versions (or more recent) of software modules are included in +* the project build : +* +* (a) uC/CPU V1.29.00 +* +* +* (2) NO compiler-supplied standard library functions are used in library or product software. +* +* (a) ALL standard library functions are implemented in the custom library modules : +* +* (1) \\lib_*.* +* +* (2) \\Ports\\\lib*_a.* +* +* where +* directory path for custom library software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (b) Product-specific library functions are implemented in individual products. +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* MODULE +* +* Note(s) : (1) This library definition header file is protected from multiple pre-processor inclusion +* through use of the library definition module present pre-processor macro definition. +********************************************************************************************************* +*/ + +#ifndef LIB_DEF_MODULE_PRESENT +#define LIB_DEF_MODULE_PRESENT + + +/* +********************************************************************************************************* +* CUSTOM LIBRARY MODULE VERSION NUMBER +* +* Note(s) : (1) (a) The custom library module software version is denoted as follows : +* +* Vx.yy.zz +* +* where +* V denotes 'Version' label +* x denotes major software version revision number +* yy denotes minor software version revision number +* zz denotes sub-minor software version revision number +* +* (b) The software version label #define is formatted as follows : +* +* ver = x.yyzz * 100 * 100 +* +* where +* ver denotes software version number scaled as an integer value +* x.yyzz denotes software version number, where the unscaled integer +* portion denotes the major version number & the unscaled +* fractional portion denotes the (concatenated) minor +* version numbers +********************************************************************************************************* +*/ + +#define LIB_VERSION 13801u /* See Note #1. */ + + +/* +********************************************************************************************************* +* INCLUDE FILES +* +* Note(s) : (1) The custom library software files are located in the following directories : +* +* (a) \\lib_*.* +* +* where +* directory path for custom library software +* +* (2) CPU-configuration software files are located in the following directories : +* +* (a) \\cpu_*.* +* (b) \\\\cpu*.* +* +* where +* directory path for common CPU-compiler software +* directory name for specific processor (CPU) +* directory name for specific compiler +* +* (3) Compiler MUST be configured to include as additional include path directories : +* +* (a) '\\' directory See Note #1a +* +* (b) (1) '\\' directory See Note #2a +* (2) '\\\\' directory See Note #2b +********************************************************************************************************* +*/ + +//#include +#include + + +/* +********************************************************************************************************* +* STANDARD DEFINES +********************************************************************************************************* +*/ + +#define DEF_NULL 0 + + + /* ----------------- BOOLEAN DEFINES ------------------ */ +#define DEF_FALSE 0u +#define DEF_TRUE 1u + +#define DEF_NO 0u +#define DEF_YES 1u + +#define DEF_DISABLED 0u +#define DEF_ENABLED 1u + +#define DEF_INACTIVE 0u +#define DEF_ACTIVE 1u + +#define DEF_INVALID 0u +#define DEF_VALID 1u + +#define DEF_OFF 0u +#define DEF_ON 1u + +#define DEF_CLR 0u +#define DEF_SET 1u + +#define DEF_FAIL 0u +#define DEF_OK 1u + + + /* ------------------- BIT DEFINES -------------------- */ +#define DEF_BIT_NONE 0x00u + +#define DEF_BIT_00 0x01u +#define DEF_BIT_01 0x02u +#define DEF_BIT_02 0x04u +#define DEF_BIT_03 0x08u +#define DEF_BIT_04 0x10u +#define DEF_BIT_05 0x20u +#define DEF_BIT_06 0x40u +#define DEF_BIT_07 0x80u + +#define DEF_BIT_08 0x0100u +#define DEF_BIT_09 0x0200u +#define DEF_BIT_10 0x0400u +#define DEF_BIT_11 0x0800u +#define DEF_BIT_12 0x1000u +#define DEF_BIT_13 0x2000u +#define DEF_BIT_14 0x4000u +#define DEF_BIT_15 0x8000u + +#define DEF_BIT_16 0x00010000u +#define DEF_BIT_17 0x00020000u +#define DEF_BIT_18 0x00040000u +#define DEF_BIT_19 0x00080000u +#define DEF_BIT_20 0x00100000u +#define DEF_BIT_21 0x00200000u +#define DEF_BIT_22 0x00400000u +#define DEF_BIT_23 0x00800000u + +#define DEF_BIT_24 0x01000000u +#define DEF_BIT_25 0x02000000u +#define DEF_BIT_26 0x04000000u +#define DEF_BIT_27 0x08000000u +#define DEF_BIT_28 0x10000000u +#define DEF_BIT_29 0x20000000u +#define DEF_BIT_30 0x40000000u +#define DEF_BIT_31 0x80000000u +#define DEF_BIT_32 0x0000000100000000u +#define DEF_BIT_33 0x0000000200000000u +#define DEF_BIT_34 0x0000000400000000u +#define DEF_BIT_35 0x0000000800000000u +#define DEF_BIT_36 0x0000001000000000u +#define DEF_BIT_37 0x0000002000000000u +#define DEF_BIT_38 0x0000004000000000u +#define DEF_BIT_39 0x0000008000000000u + +#define DEF_BIT_40 0x0000010000000000u +#define DEF_BIT_41 0x0000020000000000u +#define DEF_BIT_42 0x0000040000000000u +#define DEF_BIT_43 0x0000080000000000u +#define DEF_BIT_44 0x0000100000000000u +#define DEF_BIT_45 0x0000200000000000u +#define DEF_BIT_46 0x0000400000000000u +#define DEF_BIT_47 0x0000800000000000u + +#define DEF_BIT_48 0x0001000000000000u +#define DEF_BIT_49 0x0002000000000000u +#define DEF_BIT_50 0x0004000000000000u +#define DEF_BIT_51 0x0008000000000000u +#define DEF_BIT_52 0x0010000000000000u +#define DEF_BIT_53 0x0020000000000000u +#define DEF_BIT_54 0x0040000000000000u +#define DEF_BIT_55 0x0080000000000000u + +#define DEF_BIT_56 0x0100000000000000u +#define DEF_BIT_57 0x0200000000000000u +#define DEF_BIT_58 0x0400000000000000u +#define DEF_BIT_59 0x0800000000000000u +#define DEF_BIT_60 0x1000000000000000u +#define DEF_BIT_61 0x2000000000000000u +#define DEF_BIT_62 0x4000000000000000u +#define DEF_BIT_63 0x8000000000000000u + + + /* ------------------ ALIGN DEFINES ------------------- */ +#define DEF_ALIGN_MAX_NBR_OCTETS 4096u + + + /* ------------------ OCTET DEFINES ------------------- */ +#define DEF_OCTET_NBR_BITS 8u +#define DEF_OCTET_MASK 0xFFu + +#define DEF_OCTET_TO_BIT_NBR_BITS 3u +#define DEF_OCTET_TO_BIT_SHIFT DEF_OCTET_TO_BIT_NBR_BITS +#define DEF_OCTET_TO_BIT_MASK 0x07u + + +#define DEF_NIBBLE_NBR_BITS 4u +#define DEF_NIBBLE_MASK 0x0Fu + + + /* --------------- NUMBER BASE DEFINES ---------------- */ +#define DEF_NBR_BASE_BIN 2u +#define DEF_NBR_BASE_OCT 8u +#define DEF_NBR_BASE_DEC 10u +#define DEF_NBR_BASE_HEX 16u + + + /* ----------------- INTEGER DEFINES ------------------ */ +#define DEF_INT_08_NBR_BITS 8u +#define DEF_INT_08_MASK 0xFFu + +#define DEF_INT_08U_MIN_VAL 0u +#define DEF_INT_08U_MAX_VAL 255u + +#define DEF_INT_08S_MIN_VAL_ONES_CPL (-127) +#define DEF_INT_08S_MAX_VAL_ONES_CPL 127 + +#define DEF_INT_08S_MIN_VAL (DEF_INT_08S_MIN_VAL_ONES_CPL - 1) +#define DEF_INT_08S_MAX_VAL DEF_INT_08S_MAX_VAL_ONES_CPL + +#define DEF_INT_08U_NBR_DIG_MIN 1u +#define DEF_INT_08U_NBR_DIG_MAX 3u + +#define DEF_INT_08S_NBR_DIG_MIN 3u +#define DEF_INT_08S_NBR_DIG_MAX 3u + + + +#define DEF_INT_16_NBR_BITS 16u +#define DEF_INT_16_MASK 0xFFFFu + +#define DEF_INT_16U_MIN_VAL 0u +#define DEF_INT_16U_MAX_VAL 65535u + +#define DEF_INT_16S_MIN_VAL_ONES_CPL (-32767) +#define DEF_INT_16S_MAX_VAL_ONES_CPL 32767 + +#define DEF_INT_16S_MIN_VAL (DEF_INT_16S_MIN_VAL_ONES_CPL - 1) +#define DEF_INT_16S_MAX_VAL DEF_INT_16S_MAX_VAL_ONES_CPL + +#define DEF_INT_16U_NBR_DIG_MIN 1u +#define DEF_INT_16U_NBR_DIG_MAX 5u + +#define DEF_INT_16S_NBR_DIG_MIN 5u +#define DEF_INT_16S_NBR_DIG_MAX 5u + + + +#define DEF_INT_32_NBR_BITS 32u +#define DEF_INT_32_MASK 0xFFFFFFFFu + +#define DEF_INT_32U_MIN_VAL 0u +#define DEF_INT_32U_MAX_VAL 4294967295u + +#define DEF_INT_32S_MIN_VAL_ONES_CPL (-2147483647) +#define DEF_INT_32S_MAX_VAL_ONES_CPL 2147483647 + +#define DEF_INT_32S_MIN_VAL (DEF_INT_32S_MIN_VAL_ONES_CPL - 1) +#define DEF_INT_32S_MAX_VAL DEF_INT_32S_MAX_VAL_ONES_CPL + +#define DEF_INT_32U_NBR_DIG_MIN 1u +#define DEF_INT_32U_NBR_DIG_MAX 10u + +#define DEF_INT_32S_NBR_DIG_MIN 10u +#define DEF_INT_32S_NBR_DIG_MAX 10u + + + +#define DEF_INT_64_NBR_BITS 64u +#define DEF_INT_64_MASK 0xFFFFFFFFFFFFFFFFu + +#define DEF_INT_64U_MIN_VAL 0u +#define DEF_INT_64U_MAX_VAL 18446744073709551615u + +#define DEF_INT_64S_MIN_VAL_ONES_CPL (-9223372036854775807) +#define DEF_INT_64S_MAX_VAL_ONES_CPL 9223372036854775807 + +#define DEF_INT_64S_MIN_VAL (DEF_INT_64S_MIN_VAL_ONES_CPL - 1) +#define DEF_INT_64S_MAX_VAL DEF_INT_64S_MAX_VAL_ONES_CPL + +#define DEF_INT_64U_NBR_DIG_MIN 1u +#define DEF_INT_64U_NBR_DIG_MAX 20u + +#define DEF_INT_64S_NBR_DIG_MIN 19u +#define DEF_INT_64S_NBR_DIG_MAX 19u + + + /* --------------- CPU INTEGER DEFINES ---------------- */ +#define DEF_INT_CPU_NBR_BITS (CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS) +#define DEF_INT_CPU_NBR_BITS_MAX (CPU_CFG_DATA_SIZE_MAX * DEF_OCTET_NBR_BITS) + + + +#if (DEF_INT_CPU_NBR_BITS == DEF_INT_08_NBR_BITS) + + +#define DEF_INT_CPU_MASK DEF_INT_08_MASK + +#define DEF_INT_CPU_U_MIN_VAL DEF_INT_08U_MIN_VAL +#define DEF_INT_CPU_U_MAX_VAL DEF_INT_08U_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL DEF_INT_08S_MIN_VAL +#define DEF_INT_CPU_S_MAX_VAL DEF_INT_08S_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_08S_MIN_VAL_ONES_CPL +#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_08S_MAX_VAL_ONES_CPL + + + +#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_16_NBR_BITS) + + +#define DEF_INT_CPU_MASK DEF_INT_16_MASK + +#define DEF_INT_CPU_U_MIN_VAL DEF_INT_16U_MIN_VAL +#define DEF_INT_CPU_U_MAX_VAL DEF_INT_16U_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL DEF_INT_16S_MIN_VAL +#define DEF_INT_CPU_S_MAX_VAL DEF_INT_16S_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_16S_MIN_VAL_ONES_CPL +#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_16S_MAX_VAL_ONES_CPL + + + +#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_32_NBR_BITS) + + +#define DEF_INT_CPU_MASK DEF_INT_32_MASK + +#define DEF_INT_CPU_U_MIN_VAL DEF_INT_32U_MIN_VAL +#define DEF_INT_CPU_U_MAX_VAL DEF_INT_32U_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL DEF_INT_32S_MIN_VAL +#define DEF_INT_CPU_S_MAX_VAL DEF_INT_32S_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_32S_MIN_VAL_ONES_CPL +#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_32S_MAX_VAL_ONES_CPL + + + +#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_64_NBR_BITS) + + +#define DEF_INT_CPU_MASK DEF_INT_64_MASK + +#define DEF_INT_CPU_U_MIN_VAL DEF_INT_64U_MIN_VAL +#define DEF_INT_CPU_U_MAX_VAL DEF_INT_64U_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL DEF_INT_64S_MIN_VAL +#define DEF_INT_CPU_S_MAX_VAL DEF_INT_64S_MAX_VAL + +#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_64S_MIN_VAL_ONES_CPL +#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_64S_MAX_VAL_ONES_CPL + + + +#else + +// #error "CPU_CFG_DATA_SIZE illegally #defined in 'cpu.h' " +// #error " [See 'cpu.h CONFIGURATION ERRORS']" + +#endif + + + /* ------------------- TIME DEFINES ------------------- */ +#define DEF_TIME_NBR_DAY_PER_WK 7u +#define DEF_TIME_NBR_DAY_PER_YR 365u +#define DEF_TIME_NBR_DAY_PER_YR_LEAP 366u + +#define DEF_TIME_NBR_HR_PER_DAY 24u +#define DEF_TIME_NBR_HR_PER_WK (DEF_TIME_NBR_HR_PER_DAY * DEF_TIME_NBR_DAY_PER_WK ) +#define DEF_TIME_NBR_HR_PER_YR (DEF_TIME_NBR_HR_PER_DAY * DEF_TIME_NBR_DAY_PER_YR ) +#define DEF_TIME_NBR_HR_PER_YR_LEAP (DEF_TIME_NBR_HR_PER_DAY * DEF_TIME_NBR_DAY_PER_YR_LEAP) + +#define DEF_TIME_NBR_MIN_PER_HR 60u +#define DEF_TIME_NBR_MIN_PER_DAY (DEF_TIME_NBR_MIN_PER_HR * DEF_TIME_NBR_HR_PER_DAY ) +#define DEF_TIME_NBR_MIN_PER_WK (DEF_TIME_NBR_MIN_PER_DAY * DEF_TIME_NBR_DAY_PER_WK ) +#define DEF_TIME_NBR_MIN_PER_YR (DEF_TIME_NBR_MIN_PER_DAY * DEF_TIME_NBR_DAY_PER_YR ) +#define DEF_TIME_NBR_MIN_PER_YR_LEAP (DEF_TIME_NBR_MIN_PER_DAY * DEF_TIME_NBR_DAY_PER_YR_LEAP) + +#define DEF_TIME_NBR_SEC_PER_MIN 60u +#define DEF_TIME_NBR_SEC_PER_HR (DEF_TIME_NBR_SEC_PER_MIN * DEF_TIME_NBR_MIN_PER_HR ) +#define DEF_TIME_NBR_SEC_PER_DAY (DEF_TIME_NBR_SEC_PER_HR * DEF_TIME_NBR_HR_PER_DAY ) +#define DEF_TIME_NBR_SEC_PER_WK (DEF_TIME_NBR_SEC_PER_DAY * DEF_TIME_NBR_DAY_PER_WK ) +#define DEF_TIME_NBR_SEC_PER_YR (DEF_TIME_NBR_SEC_PER_DAY * DEF_TIME_NBR_DAY_PER_YR ) +#define DEF_TIME_NBR_SEC_PER_YR_LEAP (DEF_TIME_NBR_SEC_PER_DAY * DEF_TIME_NBR_DAY_PER_YR_LEAP) + +#define DEF_TIME_NBR_mS_PER_SEC 1000u +#define DEF_TIME_NBR_uS_PER_SEC 1000000u +#define DEF_TIME_NBR_nS_PER_SEC 1000000000u + + +/* +********************************************************************************************************* +* ERROR CODES +* +* Note(s) : (1) All library error codes are #define'd in 'lib_def.h'; +********************************************************************************************************* +*/ + +typedef enum lib_err { + + LIB_ERR_NONE = 0u, + + LIB_MEM_ERR_NONE = 10000u, + LIB_MEM_ERR_NULL_PTR = 10001u, /* Ptr arg(s) passed NULL ptr(s). */ + + LIB_MEM_ERR_INVALID_MEM_SIZE = 10100u, /* Invalid mem size. */ + LIB_MEM_ERR_INVALID_MEM_ALIGN = 10101u, /* Invalid mem align. */ + LIB_MEM_ERR_INVALID_SEG_SIZE = 10110u, /* Invalid mem seg size. */ + LIB_MEM_ERR_INVALID_SEG_OVERLAP = 10111u, /* Invalid mem seg overlaps other mem seg(s). */ + LIB_MEM_ERR_INVALID_SEG_EXISTS = 10112u, /* Invalid mem seg already exists. */ + LIB_MEM_ERR_INVALID_POOL = 10120u, /* Invalid mem pool. */ + LIB_MEM_ERR_INVALID_BLK_NBR = 10130u, /* Invalid mem pool blk nbr. */ + LIB_MEM_ERR_INVALID_BLK_SIZE = 10131u, /* Invalid mem pool blk size. */ + LIB_MEM_ERR_INVALID_BLK_ALIGN = 10132u, /* Invalid mem pool blk align. */ + LIB_MEM_ERR_INVALID_BLK_IX = 10133u, /* Invalid mem pool ix. */ + LIB_MEM_ERR_INVALID_BLK_ADDR = 10135u, /* Invalid mem pool blk addr. */ + LIB_MEM_ERR_INVALID_BLK_ADDR_IN_POOL = 10136u, /* Mem pool blk addr already in mem pool. */ + + LIB_MEM_ERR_SEG_EMPTY = 10200u, /* Mem seg empty; i.e. NO avail mem in seg. */ + LIB_MEM_ERR_SEG_OVF = 10201u, /* Mem seg ovf; i.e. req'd mem ovfs rem mem in seg. */ + LIB_MEM_ERR_POOL_FULL = 10205u, /* Mem pool full; i.e. all mem blks avail in mem pool. */ + LIB_MEM_ERR_POOL_EMPTY = 10206u, /* Mem pool empty; i.e. NO mem blks avail in mem pool. */ + LIB_MEM_ERR_POOL_UNLIMITED = 10207u, /* Mem pool is unlimited. */ + + LIB_MEM_ERR_HEAP_EMPTY = 10210u, /* Heap seg empty; i.e. NO avail mem in heap. */ + LIB_MEM_ERR_HEAP_OVF = 10211u, /* Heap seg ovf; i.e. req'd mem ovfs rem mem in heap. */ + LIB_MEM_ERR_HEAP_NOT_FOUND = 10215u /* Heap seg NOT found. */ + +} LIB_ERR; + + +/* +********************************************************************************************************* +* DATA TYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* GLOBAL VARIABLES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* TRACING +********************************************************************************************************* +*/ + + /* Trace level, default to TRACE_LEVEL_OFF. */ +#ifndef TRACE_LEVEL_OFF +#define TRACE_LEVEL_OFF 0u +#endif + +#ifndef TRACE_LEVEL_INFO +#define TRACE_LEVEL_INFO 1u +#endif + +#ifndef TRACE_LEVEL_DBG +#define TRACE_LEVEL_DBG 2u +#endif + +#ifndef TRACE_LEVEL_LOG +#define TRACE_LEVEL_LOG 3u +#endif + + +/* +********************************************************************************************************* +* BIT MACRO'S +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* DEF_BIT() +* +* Description : Create bit mask with single, specified bit set. +* +* Argument(s) : bit Bit number of bit to set. +* +* Return(s) : Bit mask with single, specified bit set. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'bit' SHOULD be a non-negative integer. +* +* (2) (a) 'bit' values that overflow the target CPU &/or compiler environment (e.g. negative +* or greater-than-CPU-data-size values) MAY generate compiler warnings &/or errors. +********************************************************************************************************* +*/ + +#define DEF_BIT(bit) (1u << (bit)) + + +/* +********************************************************************************************************* +* DEF_BITxx() +* +* Description : Create bit mask of specified bit size with single, specified bit set. +* +* Argument(s) : bit Bit number of bit to set. +* +* Return(s) : Bit mask with single, specified bit set. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'bit' SHOULD be a non-negative integer. +* +* (2) (a) 'bit' values that overflow the target CPU &/or compiler environment (e.g. negative +* or greater-than-CPU-data-size values) MAY generate compiler warnings &/or errors. +* +* (b) To avoid overflowing any target CPU &/or compiler's integer data type, unsigned +* bit constant '1' is cast to specified integer data type size. +* +* (3) Ideally, DEF_BITxx() macro's should be named DEF_BIT_xx(); however, these names already +* previously-released for bit constant #define's (see 'STANDARD DEFINES BIT DEFINES'). +********************************************************************************************************* +*/ + +#define DEF_BIT08(bit) ((CPU_INT08U)((CPU_INT08U)1u << (bit))) + +#define DEF_BIT16(bit) ((CPU_INT16U)((CPU_INT16U)1u << (bit))) + +#define DEF_BIT32(bit) ((CPU_INT32U)((CPU_INT32U)1u << (bit))) + +#define DEF_BIT64(bit) ((CPU_INT64U)((CPU_INT64U)1u << (bit))) + + +/* +********************************************************************************************************* +* DEF_BIT_MASK() +* +* Description : Shift a bit mask. +* +* Argument(s) : bit_mask Bit mask to shift. +* +* bit_shift Number of bit positions to left-shift bit mask. +* +* Return(s) : Shifted bit mask. +* +* Caller(s) : Application. +* +* Note(s) : (1) (a) 'bit_mask' SHOULD be an unsigned integer. +* +* (b) 'bit_shift' SHOULD be a non-negative integer. +* +* (2) 'bit_shift' values that overflow the target CPU &/or compiler environment (e.g. negative +* or greater-than-CPU-data-size values) MAY generate compiler warnings &/or errors. +********************************************************************************************************* +*/ + +#define DEF_BIT_MASK(bit_mask, bit_shift) ((bit_mask) << (bit_shift)) + + +/* +********************************************************************************************************* +* DEF_BIT_MASK_xx() +* +* Description : Shift a bit mask of specified bit size. +* +* Argument(s) : bit_mask Bit mask to shift. +* +* bit_shift Number of bit positions to left-shift bit mask. +* +* Return(s) : Shifted bit mask. +* +* Caller(s) : Application. +* +* Note(s) : (1) (a) 'bit_mask' SHOULD be an unsigned integer. +* +* (b) 'bit_shift' SHOULD be a non-negative integer. +* +* (2) 'bit_shift' values that overflow the target CPU &/or compiler environment (e.g. negative +* or greater-than-CPU-data-size values) MAY generate compiler warnings &/or errors. +********************************************************************************************************* +*/ + +#define DEF_BIT_MASK_08(bit_mask, bit_shift) ((CPU_INT08U)((CPU_INT08U)(bit_mask) << (bit_shift))) + +#define DEF_BIT_MASK_16(bit_mask, bit_shift) ((CPU_INT16U)((CPU_INT16U)(bit_mask) << (bit_shift))) + +#define DEF_BIT_MASK_32(bit_mask, bit_shift) ((CPU_INT32U)((CPU_INT32U)(bit_mask) << (bit_shift))) + +#define DEF_BIT_MASK_64(bit_mask, bit_shift) ((CPU_INT64U)((CPU_INT64U)(bit_mask) << (bit_shift))) + + +/* +********************************************************************************************************* +* DEF_BIT_FIELD() +* +* Description : Create & shift a contiguous bit field. +* +* Argument(s) : bit_field Number of contiguous bits to set in the bit field. +* +* bit_shift Number of bit positions to left-shift bit field. +* +* Return(s) : Shifted bit field. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'bit_field' & 'bit_shift' SHOULD be non-negative integers. +* +* (2) (a) 'bit_field'/'bit_shift' values that overflow the target CPU &/or compiler +* environment (e.g. negative or greater-than-CPU-data-size values) MAY generate +* compiler warnings &/or errors. +* +* (b) To avoid overflowing any target CPU &/or compiler's integer data type, unsigned +* bit constant '1' is suffixed with 'L'ong integer modifier. +* +* This may still be insufficient for CPUs &/or compilers that support 'long long' +* integer data types, in which case 'LL' integer modifier should be suffixed. +* However, since almost all 16- & 32-bit CPUs & compilers support 'long' integer +* data types but many may NOT support 'long long' integer data types, only 'long' +* integer data types & modifiers are supported. +* +* See also 'DEF_BIT_FIELD_xx() Note #1b'. +********************************************************************************************************* +*/ + +#define DEF_BIT_FIELD(bit_field, bit_shift) ((((bit_field) >= DEF_INT_CPU_NBR_BITS) ? (DEF_INT_CPU_U_MAX_VAL) \ + : (DEF_BIT(bit_field) - 1uL)) \ + << (bit_shift)) + +/* +********************************************************************************************************* +* DEF_BIT_FIELD_xx() +* +* Description : Create & shift a contiguous bit field of specified bit size. +* +* Argument(s) : bit_field Number of contiguous bits to set in the bit field. +* +* bit_shift Number of bit positions to left-shift bit field. +* +* Return(s) : Shifted bit field. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'bit_field' & 'bit_shift' SHOULD be non-negative integers. +* +* (2) (a) 'bit_field'/'bit_shift' values that overflow the target CPU &/or compiler +* environment (e.g. negative or greater-than-CPU-data-size values) MAY generate +* compiler warnings &/or errors. +* +* (b) To avoid overflowing any target CPU &/or compiler's integer data type, unsigned +* bit constant '1' is cast to specified integer data type size. +********************************************************************************************************* +*/ + +#define DEF_BIT_FIELD_08(bit_field, bit_shift) ((CPU_INT08U)((((CPU_INT08U)(bit_field) >= (CPU_INT08U)DEF_INT_08_NBR_BITS) ? (CPU_INT08U)(DEF_INT_08U_MAX_VAL) \ + : (CPU_INT08U)(DEF_BIT08(bit_field) - (CPU_INT08U)1u)) \ + << (bit_shift))) + +#define DEF_BIT_FIELD_16(bit_field, bit_shift) ((CPU_INT16U)((((CPU_INT16U)(bit_field) >= (CPU_INT16U)DEF_INT_16_NBR_BITS) ? (CPU_INT16U)(DEF_INT_16U_MAX_VAL) \ + : (CPU_INT16U)(DEF_BIT16(bit_field) - (CPU_INT16U)1u)) \ + << (bit_shift))) + +#define DEF_BIT_FIELD_32(bit_field, bit_shift) ((CPU_INT32U)((((CPU_INT32U)(bit_field) >= (CPU_INT32U)DEF_INT_32_NBR_BITS) ? (CPU_INT32U)(DEF_INT_32U_MAX_VAL) \ + : (CPU_INT32U)(DEF_BIT32(bit_field) - (CPU_INT32U)1u)) \ + << (bit_shift))) + +#define DEF_BIT_FIELD_64(bit_field, bit_shift) ((CPU_INT64U)((((CPU_INT64U)(bit_field) >= (CPU_INT64U)DEF_INT_64_NBR_BITS) ? (CPU_INT64U)(DEF_INT_64U_MAX_VAL) \ + : (CPU_INT64U)(DEF_BIT64(bit_field) - (CPU_INT64U)1u)) \ + << (bit_shift))) + + +/* +********************************************************************************************************* +* DEF_BIT_SET() +* +* Description : Set specified bit(s) in a value. +* +* Argument(s) : val Value to modify by setting specified bit(s). +* +* mask Mask of bits to set. +* +* Return(s) : Modified value with specified bit(s) set. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. +********************************************************************************************************* +*/ + +#define DEF_BIT_SET(val, mask) ((val) = ((val) | (mask))) + + +/* +********************************************************************************************************* +* DEF_BIT_SET_xx() +* +* Description : Set specified bit(s) in a value of specified bit size. +* +* Argument(s) : val Value to modify by setting specified bit(s). +* +* mask Mask of bits to set. +* +* Return(s) : Modified value with specified bit(s) set. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. +* +* (2) These macros are deprecated and should be replaced by the DEF_BIT_SET macro. +********************************************************************************************************* +*/ + +#define DEF_BIT_SET_08(val, mask) DEF_BIT_SET((val), (mask)) + +#define DEF_BIT_SET_16(val, mask) DEF_BIT_SET((val), (mask)) + +#define DEF_BIT_SET_32(val, mask) DEF_BIT_SET((val), (mask)) + +#define DEF_BIT_SET_64(val, mask) DEF_BIT_SET((val), (mask)) + + +/* +********************************************************************************************************* +* DEF_BIT_CLR() +* +* Description : Clear specified bit(s) in a value. +* +* Argument(s) : val Value to modify by clearing specified bit(s). +* +* mask Mask of bits to clear. +* +* Return(s) : Modified value with specified bit(s) clear. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. +********************************************************************************************************* +*/ + +#define DEF_BIT_CLR(val, mask) ((val) = ((val) & ~(mask))) + + +/* +********************************************************************************************************* +* DEF_BIT_CLR_xx() +* +* Description : Clear specified bit(s) in a value of specified bit size. +* +* Argument(s) : val Value to modify by clearing specified bit(s). +* +* mask Mask of bits to clear. +* +* Return(s) : Modified value with specified bit(s) clear. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. +* +* (2) These macros are deprecated and should be replaced by the DEF_BIT_CLR macro. +********************************************************************************************************* +*/ + +#define DEF_BIT_CLR_08(val, mask) DEF_BIT_CLR((val), (mask)) + +#define DEF_BIT_CLR_16(val, mask) DEF_BIT_CLR((val), (mask)) + +#define DEF_BIT_CLR_32(val, mask) DEF_BIT_CLR((val), (mask)) + +#define DEF_BIT_CLR_64(val, mask) DEF_BIT_CLR((val), (mask)) + + +/* +********************************************************************************************************* +* DEF_BIT_TOGGLE() +* +* Description : Toggles specified bit(s) in a value. +* +* Argument(s) : val Value to modify by toggling specified bit(s). +* +* mask Mask of bits to toggle. +* +* Return(s) : Modified value with specified bit(s) toggled. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. +********************************************************************************************************* +*/ + +#define DEF_BIT_TOGGLE(val, mask) ((val) ^= (mask)) + + +/* +********************************************************************************************************* +* DEF_BIT_FIELD_RD() +* +* Description : Reads a 'val' field, masked and shifted, given by mask 'field_mask'. +* +* Argument(s) : val Value to read from. +* +* field_mask Mask of field to read. See note #1, #2 and #3. +* +* Return(s) : Field value, masked and right-shifted to bit position 0. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'field_mask' argument must NOT be 0. +* +* (2) 'field_mask' argument must contain a mask with contiguous set bits. +* +* (3) 'val' & 'field_mask' SHOULD be unsigned integers. +********************************************************************************************************* +*/ + +#define DEF_BIT_FIELD_RD(val, field_mask) (((val) & (field_mask)) / ((field_mask) & ~((field_mask) << 1u))) + + +/* +********************************************************************************************************* +* DEF_BIT_FIELD_ENC() +* +* Description : Encodes given 'field_val' at position given by mask 'field_mask'. +* +* Argument(s) : field_val Value to encode. +* +* field_mask Mask of field to read. See note #1 and #2. +* +* Return(s) : Field value, masked and left-shifted to field position. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'field_mask' argument must contain a mask with contiguous set bits. +* +* (2) 'field_val' & 'field_mask' SHOULD be unsigned integers. +********************************************************************************************************* +*/ + +#define DEF_BIT_FIELD_ENC(field_val, field_mask) (((field_val) * ((field_mask) & ~((field_mask) << 1u))) & (field_mask)) + + +/* +********************************************************************************************************* +* DEF_BIT_FIELD_WR() +* +* Description : Writes 'field_val' field at position given by mask 'field_mask' in variable 'var'. +* +* Argument(s) : var Variable to write field to. See note #2. +* +* field_val Desired value for field. See note #2. +* +* field_mask Mask of field to write to. See note #1 and #2. +* +* Return(s) : None. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'field_mask' argument must contain a mask with contiguous set bits. +* +* (2) 'var', 'field_val' & 'field_mask' SHOULD be unsigned integers. +********************************************************************************************************* +*/ + +#define DEF_BIT_FIELD_WR(var, field_val, field_mask) (var) = (((var) & ~(field_mask)) | DEF_BIT_FIELD_ENC((field_val), (field_mask))) + + +/* +********************************************************************************************************* +* DEF_BIT_IS_SET() +* +* Description : Determine if specified bit(s) in a value are set. +* +* Argument(s) : val Value to check for specified bit(s) set. +* +* mask Mask of bits to check if set (see Note #2). +* +* Return(s) : DEF_YES, if ALL specified bit(s) are set in value. +* +* DEF_NO, if ALL specified bit(s) are NOT set in value. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. +* +* (2) NULL 'mask' allowed; returns 'DEF_NO' since NO mask bits specified. +********************************************************************************************************* +*/ + +#define DEF_BIT_IS_SET(val, mask) (((((val) & (mask)) == (mask)) && \ + ((mask) != 0u)) ? (DEF_YES) : (DEF_NO)) + + +/* +********************************************************************************************************* +* DEF_BIT_IS_CLR() +* +* Description : Determine if specified bit(s) in a value are clear. +* +* Argument(s) : val Value to check for specified bit(s) clear. +* +* mask Mask of bits to check if clear (see Note #2). +* +* Return(s) : DEF_YES, if ALL specified bit(s) are clear in value. +* +* DEF_NO, if ALL specified bit(s) are NOT clear in value. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. +* +* (2) NULL 'mask' allowed; returns 'DEF_NO' since NO mask bits specified. +********************************************************************************************************* +*/ + +#define DEF_BIT_IS_CLR(val, mask) (((((val) & (mask)) == 0u) && \ + ((mask) != 0u)) ? (DEF_YES) : (DEF_NO)) + + +/* +********************************************************************************************************* +* DEF_BIT_IS_SET_ANY() +* +* Description : Determine if any specified bit(s) in a value are set. +* +* Argument(s) : val Value to check for specified bit(s) set. +* +* mask Mask of bits to check if set (see Note #2). +* +* Return(s) : DEF_YES, if ANY specified bit(s) are set in value. +* +* DEF_NO, if ALL specified bit(s) are NOT set in value. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. +* +* (2) NULL 'mask' allowed; returns 'DEF_NO' since NO mask bits specified. +********************************************************************************************************* +*/ + +#define DEF_BIT_IS_SET_ANY(val, mask) ((((val) & (mask)) == 0u) ? (DEF_NO ) : (DEF_YES)) + + +/* +********************************************************************************************************* +* DEF_BIT_IS_CLR_ANY() +* +* Description : Determine if any specified bit(s) in a value are clear. +* +* Argument(s) : val Value to check for specified bit(s) clear. +* +* mask Mask of bits to check if clear (see Note #2). +* +* Return(s) : DEF_YES, if ANY specified bit(s) are clear in value. +* +* DEF_NO, if ALL specified bit(s) are NOT clear in value. +* +* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. +* +* (2) NULL 'mask' allowed; returns 'DEF_NO' since NO mask bits specified. +********************************************************************************************************* +*/ + +#define DEF_BIT_IS_CLR_ANY(val, mask) ((((val) & (mask)) == (mask)) ? (DEF_NO ) : (DEF_YES)) + + +/* +********************************************************************************************************* +* VALUE MACRO'S +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* DEF_CHK_VAL_MIN() +* +* Description : Validate a value as greater than or equal to a specified minimum value. +* +* Argument(s) : val Value to validate. +* +* val_min Minimum value to test. +* +* Return(s) : DEF_OK, Value is greater than or equal to minimum value. +* +* DEF_FAIL, otherwise. +* +* Caller(s) : Application. +* +* Note(s) : (1) DEF_CHK_VAL_MIN() avoids directly comparing any two values if only one of the values +* is negative since the negative value might be incorrectly promoted to an arbitrary +* unsigned value if the other value to compare is unsigned. +* +* (2) Validation of values is limited to the range supported by the compiler &/or target +* environment. All other values that underflow/overflow the supported range will +* modulo/wrap into the supported range as arbitrary signed or unsigned values. +* +* Therefore, any values that underflow the most negative signed value or overflow +* the most positive unsigned value supported by the compiler &/or target environment +* cannot be validated : +* +* ( N-1 N ] +* ( -(2 ) , 2 - 1 ] +* ( ] +* +* where +* N Number of data word bits supported by the compiler +* &/or target environment +* +* (a) Note that the most negative value, -2^(N-1), is NOT included in the supported +* range since many compilers do NOT always correctly handle this value. +* +* (3) 'val' and 'val_min' are compared to 1 instead of 0 to avoid warning generated for +* unsigned numbers. +********************************************************************************************************* +*/ + +#define DEF_CHK_VAL_MIN(val, val_min) (((!(((val) >= 1) && ((val_min) < 1))) && \ + ((((val_min) >= 1) && ((val) < 1)) || \ + ((val) < (val_min)))) ? DEF_FAIL : DEF_OK) + + +/* +********************************************************************************************************* +* DEF_CHK_VAL_MAX() +* +* Description : Validate a value as less than or equal to a specified maximum value. +* +* Argument(s) : val Value to validate. +* +* val_max Maximum value to test. +* +* Return(s) : DEF_OK, Value is less than or equal to maximum value. +* +* DEF_FAIL, otherwise. +* +* Caller(s) : Application. +* +* Note(s) : (1) DEF_CHK_VAL_MAX() avoids directly comparing any two values if only one of the values +* is negative since the negative value might be incorrectly promoted to an arbitrary +* unsigned value if the other value to compare is unsigned. +* +* (2) Validation of values is limited to the range supported by the compiler &/or target +* environment. All other values that underflow/overflow the supported range will +* modulo/wrap into the supported range as arbitrary signed or unsigned values. +* +* Therefore, any values that underflow the most negative signed value or overflow +* the most positive unsigned value supported by the compiler &/or target environment +* cannot be validated : +* +* ( N-1 N ] +* ( -(2 ) , 2 - 1 ] +* ( ] +* +* where +* N Number of data word bits supported by the compiler +* &/or target environment +* +* (a) Note that the most negative value, -2^(N-1), is NOT included in the supported +* range since many compilers do NOT always correctly handle this value. +* +* (3) 'val' and 'val_max' are compared to 1 instead of 0 to avoid warning generated for +* unsigned numbers. +********************************************************************************************************* +*/ + +#define DEF_CHK_VAL_MAX(val, val_max) (((!(((val_max) >= 1) && ((val) < 1))) && \ + ((((val) >= 1) && ((val_max) < 1)) || \ + ((val) > (val_max)))) ? DEF_FAIL : DEF_OK) + + +/* +********************************************************************************************************* +* DEF_CHK_VAL() +* +* Description : Validate a value as greater than or equal to a specified minimum value & less than or +* equal to a specified maximum value. +* +* Argument(s) : val Value to validate. +* +* val_min Minimum value to test. +* +* val_max Maximum value to test. +* +* Return(s) : DEF_OK, Value is greater than or equal to minimum value AND +* less than or equal to maximum value. +* +* DEF_FAIL, otherwise. +* +* Caller(s) : Application. +* +* Note(s) : (1) DEF_CHK_VAL() avoids directly comparing any two values if only one of the values +* is negative since the negative value might be incorrectly promoted to an arbitrary +* unsigned value if the other value to compare is unsigned. +* +* (2) Validation of values is limited to the range supported by the compiler &/or target +* environment. All other values that underflow/overflow the supported range will +* modulo/wrap into the supported range as arbitrary signed or unsigned values. +* +* Therefore, any values that underflow the most negative signed value or overflow +* the most positive unsigned value supported by the compiler &/or target environment +* cannot be validated : +* +* ( N-1 N ] +* ( -(2 ) , 2 - 1 ] +* ( ] +* +* where +* N Number of data word bits supported by the compiler +* &/or target environment +* +* (a) Note that the most negative value, -2^(N-1), is NOT included in the supported +* range since many compilers do NOT always correctly handle this value. +* +* (3) DEF_CHK_VAL() does NOT validate that the maximum value ('val_max') is greater than +* or equal to the minimum value ('val_min'). +********************************************************************************************************* +*/ + +#define DEF_CHK_VAL(val, val_min, val_max) (((DEF_CHK_VAL_MIN((val), (val_min)) == DEF_FAIL) || \ + (DEF_CHK_VAL_MAX((val), (val_max)) == DEF_FAIL)) ? DEF_FAIL : DEF_OK) + + +/* +********************************************************************************************************* +* DEF_GET_U_MAX_VAL() +* +* Description : Get the maximum unsigned value that can be represented in an unsigned integer variable +* of the same data type size as an object. +* +* Argument(s) : obj Object or data type to return maximum unsigned value (see Note #1). +* +* Return(s) : Maximum unsigned integer value that can be represented by the object, if NO error(s). +* +* 0, otherwise. +* +* Caller(s) : Application. +* +* Note(s) : (1) 'obj' SHOULD be an integer object or data type but COULD also be a character or +* pointer object or data type. +********************************************************************************************************* +*/ + +#if (CPU_CFG_DATA_SIZE_MAX == CPU_WORD_SIZE_08) + +#define DEF_GET_U_MAX_VAL(obj) ((sizeof(obj) == CPU_WORD_SIZE_08) ? DEF_INT_08U_MAX_VAL : 0) + + +#elif (CPU_CFG_DATA_SIZE_MAX == CPU_WORD_SIZE_16) + +#define DEF_GET_U_MAX_VAL(obj) ((sizeof(obj) == CPU_WORD_SIZE_08) ? DEF_INT_08U_MAX_VAL : \ + ((sizeof(obj) == CPU_WORD_SIZE_16) ? DEF_INT_16U_MAX_VAL : 0)) + + +#elif (CPU_CFG_DATA_SIZE_MAX == CPU_WORD_SIZE_32) + +#define DEF_GET_U_MAX_VAL(obj) ((sizeof(obj) == CPU_WORD_SIZE_08) ? DEF_INT_08U_MAX_VAL : \ + ((sizeof(obj) == CPU_WORD_SIZE_16) ? DEF_INT_16U_MAX_VAL : \ + ((sizeof(obj) == CPU_WORD_SIZE_32) ? DEF_INT_32U_MAX_VAL : 0))) + + +#elif (CPU_CFG_DATA_SIZE_MAX == CPU_WORD_SIZE_64) + +#define DEF_GET_U_MAX_VAL(obj) ((sizeof(obj) == CPU_WORD_SIZE_08) ? DEF_INT_08U_MAX_VAL : \ + ((sizeof(obj) == CPU_WORD_SIZE_16) ? DEF_INT_16U_MAX_VAL : \ + ((sizeof(obj) == CPU_WORD_SIZE_32) ? DEF_INT_32U_MAX_VAL : \ + ((sizeof(obj) == CPU_WORD_SIZE_64) ? DEF_INT_64U_MAX_VAL : 0)))) + +#else + +#error "CPU_CFG_DATA_SIZE_MAX illegally #defined in 'cpu.h' " +#error " [See 'cpu.h CONFIGURATION ERRORS']" + +#endif + + +/* +********************************************************************************************************* +* MATH MACRO'S +* +* Note(s) : (1) Ideally, ALL mathematical macro's & functions SHOULD be defined in the custom mathematics +* library ('lib_math.*'). #### However, to maintain backwards compatibility with previously- +* released modules, mathematical macro & function definitions should only be moved to the +* custom mathematics library once all previously-released modules are updated to include the +* custom mathematics library. +********************************************************************************************************* +*/ + +/* +********************************************************************************************************* +* DEF_MIN() +* +* Description : Determine the minimum of two values. +* +* Argument(s) : a First value. +* +* b Second value. +* +* Return(s) : Minimum of the two values. +* +* Caller(s) : Application. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_MIN(a, b) (((a) < (b)) ? (a) : (b)) + + +/* +********************************************************************************************************* +* DEF_MAX() +* +* Description : Determine the maximum of two values. +* +* Argument(s) : a First value. +* +* b Second value. +* +* Return(s) : Maximum of the two values. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_MAX(a, b) (((a) > (b)) ? (a) : (b)) + + +/* +********************************************************************************************************* +* DEF_ABS() +* +* Description : Determine the absolute value of a value. +* +* Argument(s) : a Value to calculate absolute value. +* +* Return(s) : Absolute value of the value. +* +* Caller(s) : Application. +* +* Note(s) : none. +********************************************************************************************************* +*/ + +#define DEF_ABS(a) (((a) < 0) ? (-(a)) : (a)) + + +/* +********************************************************************************************************* +* FUNCTION PROTOTYPES +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* LIBRARY CONFIGURATION ERRORS +********************************************************************************************************* +*/ + + /* See 'lib_def.h Note #1a'. */ +#if (CPU_CORE_VERSION < 12900u) +// #error "CPU_CORE_VERSION [SHOULD be >= V1.29.00]" +#endif + + +/* +********************************************************************************************************* +* MODULE END +* +* Note(s) : (1) See 'lib_def.h MODULE'. +********************************************************************************************************* +*/ + +#endif /* End of lib def module include. */ + diff --git a/Tests/UnitTests/Mocks/RTOS/os.c b/Tests/UnitTests/Mocks/RTOS/os.c new file mode 100644 index 000000000..2b63f2c0d --- /dev/null +++ b/Tests/UnitTests/Mocks/RTOS/os.c @@ -0,0 +1,29 @@ +#include "fff.h" +#include "os.h" + + +DEFINE_FAKE_VOID_FUNC(OSMutexCreate, OS_MUTEX*, char* , OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSMutexPend, OS_MUTEX*, OS_TICK, OS_OPT, CPU_TS*, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSMutexPost, OS_MUTEX*, OS_OPT, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSSemCreate, OS_SEM*, CPU_CHAR*, OS_SEM_CTR, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSSemPend, OS_SEM*, OS_TICK, OS_OPT, CPU_TS*, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSSemPendAbort, OS_SEM*, OS_OPT, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSSemPost, OS_SEM*, OS_OPT, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSSemSet, OS_SEM*, OS_SEM_CTR, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSTaskCreate, OS_TCB*, CPU_CHAR*, OS_TASK_PTR, void*, OS_PRIO, CPU_STK*, CPU_STK_SIZE, CPU_STK_SIZE, OS_MSG_QTY, OS_TICK, void*, OS_OPT, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSTaskDel, OS_TCB*, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSTimeDly, OS_TICK, OS_OPT, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSTimeDlyHMSM, CPU_INT16U, CPU_INT16U, CPU_INT16U, CPU_INT32U, OS_OPT, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSTmrCreate, OS_TMR*, CPU_CHAR*, OS_TICK, OS_TICK, OS_OPT, OS_TMR_CALLBACK_PTR, void*, OS_ERR*); diff --git a/Tests/UnitTests/Mocks/RTOS/os.h b/Tests/UnitTests/Mocks/RTOS/os.h new file mode 100644 index 000000000..523dbb438 --- /dev/null +++ b/Tests/UnitTests/Mocks/RTOS/os.h @@ -0,0 +1,1400 @@ +// #ifdef TEST_READCARCAN +// #include_next "ReadCarCAN.h" // Include the next instance of the file. +// // If the real version is in the include search paths after the mock one, it will include it here +// #else // Mocked Contactors.h +#ifndef OS_H +#define OS_H +#include "os_type.h" + + +/* +************************************************************************************************************************ +* uC/OS-III VERSION NUMBER +************************************************************************************************************************ +*/ + +#define OS_VERSION 30405u /* Version of uC/OS-III (Vx.yy.zz mult. by 10000) */ + +/* + +/* +************************************************************************************************************************ +* INCLUDE HEADER FILES +************************************************************************************************************************ +*/ +#include "fff.h" +#include +//#include +#include +#include +#include "os_type.h" +//#include +#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN == DEF_ENABLED)) +//#include +#endif + + +/* +************************************************************************************************************************ +* CRITICAL SECTION HANDLING +************************************************************************************************************************ +*/ + + +#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u && defined(CPU_CFG_INT_DIS_MEAS_EN) +#define OS_SCHED_LOCK_TIME_MEAS_START() OS_SchedLockTimeMeasStart() +#else +#define OS_SCHED_LOCK_TIME_MEAS_START() +#endif + + +#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u && defined(CPU_CFG_INT_DIS_MEAS_EN) +#define OS_SCHED_LOCK_TIME_MEAS_STOP() OS_SchedLockTimeMeasStop() +#else +#define OS_SCHED_LOCK_TIME_MEAS_STOP() +#endif + +#if OS_CFG_ISR_POST_DEFERRED_EN > 0u /* Deferred ISR Posts ------------------------------ */ + /* Lock the scheduler */ +#define OS_CRITICAL_ENTER() \ + do { \ + CPU_CRITICAL_ENTER(); \ + OSSchedLockNestingCtr++; \ + if (OSSchedLockNestingCtr == 1u) { \ + OS_SCHED_LOCK_TIME_MEAS_START(); \ + } \ + CPU_CRITICAL_EXIT(); \ + } while (0) + /* Lock the scheduler but re-enable interrupts */ +#define OS_CRITICAL_ENTER_CPU_EXIT() \ + do { \ + OSSchedLockNestingCtr++; \ + \ + if (OSSchedLockNestingCtr == 1u) { \ + OS_SCHED_LOCK_TIME_MEAS_START(); \ + } \ + CPU_CRITICAL_EXIT(); \ + } while (0) + + /* Scheduling occurs only if an interrupt occurs */ +#define OS_CRITICAL_EXIT() \ + do { \ + CPU_CRITICAL_ENTER(); \ + OSSchedLockNestingCtr--; \ + if (OSSchedLockNestingCtr == (OS_NESTING_CTR)0) { \ + OS_SCHED_LOCK_TIME_MEAS_STOP(); \ + if (OSIntQNbrEntries > (OS_OBJ_QTY)0) { \ + CPU_CRITICAL_EXIT(); \ + OS_Sched0(); \ + } else { \ + CPU_CRITICAL_EXIT(); \ + } \ + } else { \ + CPU_CRITICAL_EXIT(); \ + } \ + } while (0) + +#define OS_CRITICAL_EXIT_NO_SCHED() \ + do { \ + CPU_CRITICAL_ENTER(); \ + OSSchedLockNestingCtr--; \ + if (OSSchedLockNestingCtr == (OS_NESTING_CTR)0) { \ + OS_SCHED_LOCK_TIME_MEAS_STOP(); \ + } \ + CPU_CRITICAL_EXIT(); \ + } while (0) + + +#else /* Direct ISR Posts -------------------------------- */ + + +#define OS_CRITICAL_ENTER() CPU_CRITICAL_ENTER() + +#define OS_CRITICAL_ENTER_CPU_EXIT() + +#define OS_CRITICAL_EXIT() CPU_CRITICAL_EXIT() + +#define OS_CRITICAL_EXIT_NO_SCHED() CPU_CRITICAL_EXIT() + +#endif + +/* +************************************************************************************************************************ +* MISCELLANEOUS +************************************************************************************************************************ +*/ + +#ifdef OS_GLOBALS +#define OS_EXT +#else +#define OS_EXT extern +#endif + + +#define OS_PRIO_TBL_SIZE ((OS_CFG_PRIO_MAX - 1u) / (DEF_INT_CPU_NBR_BITS) + 1u) + +#define OS_MSG_EN (((OS_CFG_TASK_Q_EN > 0u) || (OS_CFG_Q_EN > 0u)) ? 1u : 0u) + +#define OS_OBJ_TYPE_REQ (((OS_CFG_DBG_EN > 0u) || (OS_CFG_OBJ_TYPE_CHK_EN > 0u) || (OS_CFG_PEND_MULTI_EN > 0u) \ + || (OS_CFG_ISR_POST_DEFERRED_EN > 0u)) ? 1u : 0u) + + +/* +************************************************************************************************************************ +************************************************************************************************************************ +* # D E F I N E S +************************************************************************************************************************ +************************************************************************************************************************ +*/ + +/* +======================================================================================================================== +* TASK STATUS +======================================================================================================================== +*/ + +#define OS_STATE_OS_STOPPED (OS_STATE)(0u) +#define OS_STATE_OS_RUNNING (OS_STATE)(1u) + +#define OS_STATE_NOT_RDY (CPU_BOOLEAN)(0u) +#define OS_STATE_RDY (CPU_BOOLEAN)(1u) + + + /* ------------------- TASK STATES ------------------ */ +#define OS_TASK_STATE_BIT_DLY (OS_STATE)(0x01u) /* /-------- SUSPENDED bit */ + /* | */ +#define OS_TASK_STATE_BIT_PEND (OS_STATE)(0x02u) /* | /----- PEND bit */ + /* | | */ +#define OS_TASK_STATE_BIT_SUSPENDED (OS_STATE)(0x04u) /* | | /--- Delayed/Timeout bit */ + /* | | | */ + /* V V V */ + +#define OS_TASK_STATE_RDY (OS_STATE)( 0u) /* 0 0 0 Ready */ +#define OS_TASK_STATE_DLY (OS_STATE)( 1u) /* 0 0 1 Delayed or Timeout */ +#define OS_TASK_STATE_PEND (OS_STATE)( 2u) /* 0 1 0 Pend */ +#define OS_TASK_STATE_PEND_TIMEOUT (OS_STATE)( 3u) /* 0 1 1 Pend + Timeout */ +#define OS_TASK_STATE_SUSPENDED (OS_STATE)( 4u) /* 1 0 0 Suspended */ +#define OS_TASK_STATE_DLY_SUSPENDED (OS_STATE)( 5u) /* 1 0 1 Suspended + Delayed or Timeout */ +#define OS_TASK_STATE_PEND_SUSPENDED (OS_STATE)( 6u) /* 1 1 0 Suspended + Pend */ +#define OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED (OS_STATE)( 7u) /* 1 1 1 Suspended + Pend + Timeout */ +#define OS_TASK_STATE_DEL (OS_STATE)(255u) + + /* ----------------- PENDING ON ... ----------------- */ +#define OS_TASK_PEND_ON_NOTHING (OS_STATE)( 0u) /* Pending on nothing */ +#define OS_TASK_PEND_ON_FLAG (OS_STATE)( 1u) /* Pending on event flag group */ +#define OS_TASK_PEND_ON_TASK_Q (OS_STATE)( 2u) /* Pending on message to be sent to task */ +#define OS_TASK_PEND_ON_MULTI (OS_STATE)( 3u) /* Pending on multiple semaphores and/or queues */ +#define OS_TASK_PEND_ON_MUTEX (OS_STATE)( 4u) /* Pending on mutual exclusion semaphore */ +#define OS_TASK_PEND_ON_Q (OS_STATE)( 5u) /* Pending on queue */ +#define OS_TASK_PEND_ON_SEM (OS_STATE)( 6u) /* Pending on semaphore */ +#define OS_TASK_PEND_ON_TASK_SEM (OS_STATE)( 7u) /* Pending on signal to be sent to task */ + +/* +------------------------------------------------------------------------------------------------------------------------ +* TASK PEND STATUS +* (Status codes for OS_TCBs field .PendStatus) +------------------------------------------------------------------------------------------------------------------------ +*/ + +#define OS_STATUS_PEND_OK (OS_STATUS)( 0u) /* Pending status OK, !pending, or pending complete */ +#define OS_STATUS_PEND_ABORT (OS_STATUS)( 1u) /* Pending aborted */ +#define OS_STATUS_PEND_DEL (OS_STATUS)( 2u) /* Pending object deleted */ +#define OS_STATUS_PEND_TIMEOUT (OS_STATUS)( 3u) /* Pending timed out */ + +/* +======================================================================================================================== +* OS OBJECT TYPES +* +* Note(s) : (1) OS_OBJ_TYPE_&&& #define values specifically chosen as ASCII representations of the kernel +* object types. Memory displays of kernel objects will display the kernel object TYPEs with +* their chosen ASCII names. +======================================================================================================================== +*/ + +#define OS_OBJ_TYPE_NONE (OS_OBJ_TYPE)CPU_TYPE_CREATE('N', 'O', 'N', 'E') +#define OS_OBJ_TYPE_FLAG (OS_OBJ_TYPE)CPU_TYPE_CREATE('F', 'L', 'A', 'G') +#define OS_OBJ_TYPE_MEM (OS_OBJ_TYPE)CPU_TYPE_CREATE('M', 'E', 'M', ' ') +#define OS_OBJ_TYPE_MUTEX (OS_OBJ_TYPE)CPU_TYPE_CREATE('M', 'U', 'T', 'X') +#define OS_OBJ_TYPE_Q (OS_OBJ_TYPE)CPU_TYPE_CREATE('Q', 'U', 'E', 'U') +#define OS_OBJ_TYPE_SEM (OS_OBJ_TYPE)CPU_TYPE_CREATE('S', 'E', 'M', 'A') +#define OS_OBJ_TYPE_TASK_MSG (OS_OBJ_TYPE)CPU_TYPE_CREATE('T', 'M', 'S', 'G') +#define OS_OBJ_TYPE_TASK_RESUME (OS_OBJ_TYPE)CPU_TYPE_CREATE('T', 'R', 'E', 'S') +#define OS_OBJ_TYPE_TASK_SIGNAL (OS_OBJ_TYPE)CPU_TYPE_CREATE('T', 'S', 'I', 'G') +#define OS_OBJ_TYPE_TASK_SUSPEND (OS_OBJ_TYPE)CPU_TYPE_CREATE('T', 'S', 'U', 'S') +#define OS_OBJ_TYPE_TICK (OS_OBJ_TYPE)CPU_TYPE_CREATE('T', 'I', 'C', 'K') +#define OS_OBJ_TYPE_TMR (OS_OBJ_TYPE)CPU_TYPE_CREATE('T', 'M', 'R', ' ') + +/* +======================================================================================================================== +* Possible values for 'opt' argument +======================================================================================================================== +*/ + +#define OS_OPT_NONE (OS_OPT)(0x0000u) + +/* +------------------------------------------------------------------------------------------------------------------------ +* DELETE OPTIONS +------------------------------------------------------------------------------------------------------------------------ +*/ + +#define OS_OPT_DEL_NO_PEND (OS_OPT)(0x0000u) +#define OS_OPT_DEL_ALWAYS (OS_OPT)(0x0001u) + +/* +------------------------------------------------------------------------------------------------------------------------ +* PEND OPTIONS +------------------------------------------------------------------------------------------------------------------------ +*/ + +#define OS_OPT_PEND_FLAG_MASK (OS_OPT)(0x000Fu) +#define OS_OPT_PEND_FLAG_CLR_ALL (OS_OPT)(0x0001u) /* Wait for ALL the bits specified to be CLR */ +#define OS_OPT_PEND_FLAG_CLR_AND (OS_OPT)(0x0001u) + +#define OS_OPT_PEND_FLAG_CLR_ANY (OS_OPT)(0x0002u) /* Wait for ANY of the bits specified to be CLR */ +#define OS_OPT_PEND_FLAG_CLR_OR (OS_OPT)(0x0002u) + +#define OS_OPT_PEND_FLAG_SET_ALL (OS_OPT)(0x0004u) /* Wait for ALL the bits specified to be SET */ +#define OS_OPT_PEND_FLAG_SET_AND (OS_OPT)(0x0004u) + +#define OS_OPT_PEND_FLAG_SET_ANY (OS_OPT)(0x0008u) /* Wait for ANY of the bits specified to be SET */ +#define OS_OPT_PEND_FLAG_SET_OR (OS_OPT)(0x0008u) + +#define OS_OPT_PEND_FLAG_CONSUME (OS_OPT)(0x0100u) /* Consume the flags if condition(s) satisfied */ + + +#define OS_OPT_PEND_BLOCKING (OS_OPT)(0x0000u) +#define OS_OPT_PEND_NON_BLOCKING (OS_OPT)(0x8000u) + +/* +------------------------------------------------------------------------------------------------------------------------ +* PEND ABORT OPTIONS +------------------------------------------------------------------------------------------------------------------------ +*/ + +#define OS_OPT_PEND_ABORT_1 (OS_OPT)(0x0000u) /* Pend abort a single waiting task */ +#define OS_OPT_PEND_ABORT_ALL (OS_OPT)(0x0100u) /* Pend abort ALL tasks waiting */ + +/* +------------------------------------------------------------------------------------------------------------------------ +* POST OPTIONS +------------------------------------------------------------------------------------------------------------------------ +*/ + + +#define OS_OPT_POST_NONE (OS_OPT)(0x0000u) + +#define OS_OPT_POST_FLAG_SET (OS_OPT)(0x0000u) +#define OS_OPT_POST_FLAG_CLR (OS_OPT)(0x0001u) + +#define OS_OPT_POST_FIFO (OS_OPT)(0x0000u) /* Default is to post FIFO */ +#define OS_OPT_POST_LIFO (OS_OPT)(0x0010u) /* Post to highest priority task waiting */ +#define OS_OPT_POST_1 (OS_OPT)(0x0000u) /* Post message to highest priority task waiting */ +#define OS_OPT_POST_ALL (OS_OPT)(0x0200u) /* Broadcast message to ALL tasks waiting */ + +#define OS_OPT_POST_NO_SCHED (OS_OPT)(0x8000u) /* Do not call the scheduler if this is selected */ + +/* +------------------------------------------------------------------------------------------------------------------------ +* PEND ABORT OPTIONS +------------------------------------------------------------------------------------------------------------------------ +*/ + +#define OS_OPT_PEND_ABORT_1 (OS_OPT)(0x0000u) /* Pend abort a single waiting task */ +#define OS_OPT_PEND_ABORT_ALL (OS_OPT)(0x0100u) /* Pend abort ALL tasks waiting */ + +/* +------------------------------------------------------------------------------------------------------------------------ +* POST OPTIONS +------------------------------------------------------------------------------------------------------------------------ +*/ + + +#define OS_OPT_POST_NONE (OS_OPT)(0x0000u) + +#define OS_OPT_POST_FLAG_SET (OS_OPT)(0x0000u) +#define OS_OPT_POST_FLAG_CLR (OS_OPT)(0x0001u) + +#define OS_OPT_POST_FIFO (OS_OPT)(0x0000u) /* Default is to post FIFO */ +#define OS_OPT_POST_LIFO (OS_OPT)(0x0010u) /* Post to highest priority task waiting */ +#define OS_OPT_POST_1 (OS_OPT)(0x0000u) /* Post message to highest priority task waiting */ +#define OS_OPT_POST_ALL (OS_OPT)(0x0200u) /* Broadcast message to ALL tasks waiting */ + +#define OS_OPT_POST_NO_SCHED (OS_OPT)(0x8000u) /* Do not call the scheduler if this is selected */ + +/* +------------------------------------------------------------------------------------------------------------------------ +* TIMER OPTIONS +------------------------------------------------------------------------------------------------------------------------ +*/ + +#define OS_OPT_TMR_NONE (OS_OPT)(0u) /* No option selected */ + +#define OS_OPT_TMR_ONE_SHOT (OS_OPT)(1u) /* Timer will not auto restart when it expires */ +#define OS_OPT_TMR_PERIODIC (OS_OPT)(2u) /* Timer will auto restart when it expires */ + +#define OS_OPT_TMR_CALLBACK (OS_OPT)(3u) /* OSTmrStop() option to call 'callback' w/ timer arg */ +#define OS_OPT_TMR_CALLBACK_ARG (OS_OPT)(4u) /* OSTmrStop() option to call 'callback' w/ new arg */ + +/* +------------------------------------------------------------------------------------------------------------------------ +* TIMER STATES +------------------------------------------------------------------------------------------------------------------------ +*/ + +#define OS_TMR_STATE_UNUSED (OS_STATE)(0u) +#define OS_TMR_STATE_STOPPED (OS_STATE)(1u) +#define OS_TMR_STATE_RUNNING (OS_STATE)(2u) +#define OS_TMR_STATE_COMPLETED (OS_STATE)(3u) + +/* +------------------------------------------------------------------------------------------------------------------------ +* PRIORITY +------------------------------------------------------------------------------------------------------------------------ +*/ + /* Dflt prio to init task TCB */ +#define OS_PRIO_INIT (OS_PRIO)(OS_CFG_PRIO_MAX) + +/* +------------------------------------------------------------------------------------------------------------------------ +* TIMER TICK THRESHOLDS +------------------------------------------------------------------------------------------------------------------------ +*/ + /* Threshold to init previous tick time */ +#define OS_TICK_TH_INIT (OS_TICK)(DEF_BIT ((sizeof(OS_TICK) * DEF_OCTET_NBR_BITS) - 1u)) + + /* Threshold to check if tick time already ready */ +#define OS_TICK_TH_RDY (OS_TICK)(DEF_BIT_FIELD(((sizeof(OS_TICK) * DEF_OCTET_NBR_BITS) / 2u), \ + ((sizeof(OS_TICK) * DEF_OCTET_NBR_BITS) / 2u))) + + +/* +************************************************************************************************************************ +************************************************************************************************************************ +* E N U M E R A T I O N S +************************************************************************************************************************ +************************************************************************************************************************ +*/ + +/* +------------------------------------------------------------------------------------------------------------------------ +* ERROR CODES +------------------------------------------------------------------------------------------------------------------------ +*/ + +typedef enum os_err { + OS_ERR_NONE = 0u, + + OS_ERR_A = 10000u, + OS_ERR_ACCEPT_ISR = 10001u, + + OS_ERR_B = 11000u, + + OS_ERR_C = 12000u, + OS_ERR_CREATE_ISR = 12001u, + + OS_ERR_D = 13000u, + OS_ERR_DEL_ISR = 13001u, + + OS_ERR_E = 14000u, + + OS_ERR_F = 15000u, + OS_ERR_FATAL_RETURN = 15001u, + + OS_ERR_FLAG_GRP_DEPLETED = 15101u, + OS_ERR_FLAG_NOT_RDY = 15102u, + OS_ERR_FLAG_PEND_OPT = 15103u, + OS_ERR_FLUSH_ISR = 15104u, + + OS_ERR_G = 16000u, + + OS_ERR_H = 17000u, + + OS_ERR_I = 18000u, + OS_ERR_ILLEGAL_CREATE_RUN_TIME = 18001u, + OS_ERR_INT_Q = 18002u, + OS_ERR_INT_Q_FULL = 18003u, + OS_ERR_INT_Q_SIZE = 18004u, + OS_ERR_INT_Q_STK_INVALID = 18005u, + OS_ERR_INT_Q_STK_SIZE_INVALID = 18006u, + + OS_ERR_J = 19000u, + + OS_ERR_K = 20000u, + + OS_ERR_L = 21000u, + OS_ERR_LOCK_NESTING_OVF = 21001u, + + OS_ERR_M = 22000u, + + OS_ERR_MEM_CREATE_ISR = 22201u, + OS_ERR_MEM_FULL = 22202u, + OS_ERR_MEM_INVALID_P_ADDR = 22203u, + OS_ERR_MEM_INVALID_BLKS = 22204u, + OS_ERR_MEM_INVALID_PART = 22205u, + OS_ERR_MEM_INVALID_P_BLK = 22206u, + OS_ERR_MEM_INVALID_P_MEM = 22207u, + OS_ERR_MEM_INVALID_P_DATA = 22208u, + OS_ERR_MEM_INVALID_SIZE = 22209u, + OS_ERR_MEM_NO_FREE_BLKS = 22210u, + + OS_ERR_MSG_POOL_EMPTY = 22301u, + OS_ERR_MSG_POOL_NULL_PTR = 22302u, + + OS_ERR_MUTEX_NOT_OWNER = 22401u, + OS_ERR_MUTEX_OWNER = 22402u, + OS_ERR_MUTEX_NESTING = 22403u, + OS_ERR_MUTEX_OVF = 22404u, + + OS_ERR_N = 23000u, + OS_ERR_NAME = 23001u, + OS_ERR_NO_MORE_ID_AVAIL = 23002u, + + OS_ERR_O = 24000u, + OS_ERR_OBJ_CREATED = 24001u, + OS_ERR_OBJ_DEL = 24002u, + OS_ERR_OBJ_PTR_NULL = 24003u, + OS_ERR_OBJ_TYPE = 24004u, + + OS_ERR_OPT_INVALID = 24101u, + + OS_ERR_OS_NOT_RUNNING = 24201u, + OS_ERR_OS_RUNNING = 24202u, + + OS_ERR_P = 25000u, + OS_ERR_PEND_ABORT = 25001u, + OS_ERR_PEND_ABORT_ISR = 25002u, + OS_ERR_PEND_ABORT_NONE = 25003u, + OS_ERR_PEND_ABORT_SELF = 25004u, + OS_ERR_PEND_DEL = 25005u, + OS_ERR_PEND_ISR = 25006u, + OS_ERR_PEND_LOCKED = 25007u, + OS_ERR_PEND_WOULD_BLOCK = 25008u, + + OS_ERR_POST_NULL_PTR = 25101u, + OS_ERR_POST_ISR = 25102u, + + OS_ERR_PRIO_EXIST = 25201u, + OS_ERR_PRIO = 25202u, + OS_ERR_PRIO_INVALID = 25203u, + + OS_ERR_PTR_INVALID = 25301u, + + OS_ERR_Q = 26000u, + OS_ERR_Q_FULL = 26001u, + OS_ERR_Q_EMPTY = 26002u, + OS_ERR_Q_MAX = 26003u, + OS_ERR_Q_SIZE = 26004u, + + OS_ERR_R = 27000u, + OS_ERR_REG_ID_INVALID = 27001u, + OS_ERR_ROUND_ROBIN_1 = 27002u, + OS_ERR_ROUND_ROBIN_DISABLED = 27003u, + + OS_ERR_S = 28000u, + OS_ERR_SCHED_INVALID_TIME_SLICE = 28001u, + OS_ERR_SCHED_LOCK_ISR = 28002u, + OS_ERR_SCHED_LOCKED = 28003u, + OS_ERR_SCHED_NOT_LOCKED = 28004u, + OS_ERR_SCHED_UNLOCK_ISR = 28005u, + + OS_ERR_SEM_OVF = 28101u, + OS_ERR_SET_ISR = 28102u, + + OS_ERR_STAT_RESET_ISR = 28201u, + OS_ERR_STAT_PRIO_INVALID = 28202u, + OS_ERR_STAT_STK_INVALID = 28203u, + OS_ERR_STAT_STK_SIZE_INVALID = 28204u, + OS_ERR_STATE_INVALID = 28205u, + OS_ERR_STATUS_INVALID = 28206u, + OS_ERR_STK_INVALID = 28207u, + OS_ERR_STK_SIZE_INVALID = 28208u, + OS_ERR_STK_LIMIT_INVALID = 28209u, + + OS_ERR_T = 29000u, + OS_ERR_TASK_CHANGE_PRIO_ISR = 29001u, + OS_ERR_TASK_CREATE_ISR = 29002u, + OS_ERR_TASK_DEL = 29003u, + OS_ERR_TASK_DEL_IDLE = 29004u, + OS_ERR_TASK_DEL_INVALID = 29005u, + OS_ERR_TASK_DEL_ISR = 29006u, + OS_ERR_TASK_INVALID = 29007u, + OS_ERR_TASK_NO_MORE_TCB = 29008u, + OS_ERR_TASK_NOT_DLY = 29009u, + OS_ERR_TASK_NOT_EXIST = 29010u, + OS_ERR_TASK_NOT_SUSPENDED = 29011u, + OS_ERR_TASK_OPT = 29012u, + OS_ERR_TASK_RESUME_ISR = 29013u, + OS_ERR_TASK_RESUME_PRIO = 29014u, + OS_ERR_TASK_RESUME_SELF = 29015u, + OS_ERR_TASK_RUNNING = 29016u, + OS_ERR_TASK_STK_CHK_ISR = 29017u, + OS_ERR_TASK_SUSPENDED = 29018u, + OS_ERR_TASK_SUSPEND_IDLE = 29019u, + OS_ERR_TASK_SUSPEND_INT_HANDLER = 29020u, + OS_ERR_TASK_SUSPEND_ISR = 29021u, + OS_ERR_TASK_SUSPEND_PRIO = 29022u, + OS_ERR_TASK_WAITING = 29023u, + + OS_ERR_TCB_INVALID = 29101u, + + OS_ERR_TLS_ID_INVALID = 29120u, + OS_ERR_TLS_ISR = 29121u, + OS_ERR_TLS_NO_MORE_AVAIL = 29122u, + OS_ERR_TLS_NOT_EN = 29123u, + OS_ERR_TLS_DESTRUCT_ASSIGNED = 29124u, + + OS_ERR_TICK_PRIO_INVALID = 29201u, + OS_ERR_TICK_STK_INVALID = 29202u, + OS_ERR_TICK_STK_SIZE_INVALID = 29203u, + OS_ERR_TICK_WHEEL_SIZE = 29204u, + + OS_ERR_TIME_DLY_ISR = 29301u, + OS_ERR_TIME_DLY_RESUME_ISR = 29302u, + OS_ERR_TIME_GET_ISR = 29303u, + OS_ERR_TIME_INVALID_HOURS = 29304u, + OS_ERR_TIME_INVALID_MINUTES = 29305u, + OS_ERR_TIME_INVALID_SECONDS = 29306u, + OS_ERR_TIME_INVALID_MILLISECONDS = 29307u, + OS_ERR_TIME_NOT_DLY = 29308u, + OS_ERR_TIME_SET_ISR = 29309u, + OS_ERR_TIME_ZERO_DLY = 29310u, + + OS_ERR_TIMEOUT = 29401u, + + OS_ERR_TMR_INACTIVE = 29501u, + OS_ERR_TMR_INVALID_DEST = 29502u, + OS_ERR_TMR_INVALID_DLY = 29503u, + OS_ERR_TMR_INVALID_PERIOD = 29504u, + OS_ERR_TMR_INVALID_STATE = 29505u, + OS_ERR_TMR_INVALID = 29506u, + OS_ERR_TMR_ISR = 29507u, + OS_ERR_TMR_NO_CALLBACK = 29508u, + OS_ERR_TMR_NON_AVAIL = 29509u, + OS_ERR_TMR_PRIO_INVALID = 29510u, + OS_ERR_TMR_STK_INVALID = 29511u, + OS_ERR_TMR_STK_SIZE_INVALID = 29512u, + OS_ERR_TMR_STOPPED = 29513u, + + OS_ERR_U = 30000u, + + OS_ERR_V = 31000u, + + OS_ERR_W = 32000u, + + OS_ERR_X = 33000u, + + OS_ERR_Y = 34000u, + OS_ERR_YIELD_ISR = 34001u, + + OS_ERR_Z = 35000u +} OS_ERR; + + + +/* +************************************************************************************************************************ +************************************************************************************************************************ +* D A T A T Y P E S +************************************************************************************************************************ +************************************************************************************************************************ +*/ + +typedef struct os_flag_grp OS_FLAG_GRP; + +typedef struct os_mem OS_MEM; + +typedef struct os_msg OS_MSG; +typedef struct os_msg_pool OS_MSG_POOL; +typedef struct os_msg_q OS_MSG_Q; + +typedef struct os_mutex OS_MUTEX; + +typedef struct os_int_q OS_INT_Q; + +typedef struct os_q OS_Q; + +typedef struct os_sem OS_SEM; + +typedef void (*OS_TASK_PTR)(void *p_arg); + +typedef struct os_tcb OS_TCB; + +#if defined(OS_CFG_TLS_TBL_SIZE) && (OS_CFG_TLS_TBL_SIZE > 0u) +typedef void *OS_TLS; + +typedef CPU_DATA OS_TLS_ID; + +typedef void (*OS_TLS_DESTRUCT_PTR)(OS_TCB *p_tcb, + OS_TLS_ID id, + OS_TLS value); +#endif + +typedef struct os_rdy_list OS_RDY_LIST; + +typedef struct os_tick_list OS_TICK_LIST; + +typedef void (*OS_TMR_CALLBACK_PTR)(void *p_tmr, void *p_arg); +typedef struct os_tmr OS_TMR; + +typedef struct os_pend_data OS_PEND_DATA; +typedef struct os_pend_list OS_PEND_LIST; +typedef struct os_pend_obj OS_PEND_OBJ; + +#if OS_CFG_APP_HOOKS_EN > 0u +typedef void (*OS_APP_HOOK_VOID)(void); +typedef void (*OS_APP_HOOK_TCB)(OS_TCB *p_tcb); +#endif + + +/* +************************************************************************************************************************ +************************************************************************************************************************ +* D A T A S T R U C T U R E S +************************************************************************************************************************ +************************************************************************************************************************ +*/ + +/* +------------------------------------------------------------------------------------------------------------------------ +* ISR POST DATA +------------------------------------------------------------------------------------------------------------------------ +*/ + +#if OS_CFG_ISR_POST_DEFERRED_EN > 0u +struct os_int_q { + OS_OBJ_TYPE Type; /* Type of object placed in the circular list */ + OS_INT_Q *NextPtr; /* Pointer to next OS_INT_Q in circular list */ + void *ObjPtr; /* Pointer to object placed in the queue */ + void *MsgPtr; /* Pointer to message if posting to a message queue */ + OS_MSG_SIZE MsgSize; /* Message Size if posting to a message queue */ + OS_FLAGS Flags; /* Value of flags if posting to an event flag group */ + OS_OPT Opt; /* Post Options */ + CPU_TS TS; /* Timestamp */ +}; +#endif + +/* +------------------------------------------------------------------------------------------------------------------------ +* READY LIST +------------------------------------------------------------------------------------------------------------------------ +*/ + +struct os_rdy_list { + OS_TCB *HeadPtr; /* Pointer to task that will run at selected priority */ + OS_TCB *TailPtr; /* Pointer to last task at selected priority */ + OS_OBJ_QTY NbrEntries; /* Number of entries at selected priority */ +}; + + +/* +------------------------------------------------------------------------------------------------------------------------ +* PEND DATA and PEND LIST +------------------------------------------------------------------------------------------------------------------------ +*/ + +struct os_pend_data { + OS_PEND_DATA *PrevPtr; + OS_PEND_DATA *NextPtr; + OS_TCB *TCBPtr; + OS_PEND_OBJ *PendObjPtr; + OS_PEND_OBJ *RdyObjPtr; + void *RdyMsgPtr; + OS_MSG_SIZE RdyMsgSize; + CPU_TS RdyTS; +}; + + +struct os_pend_list { + OS_PEND_DATA *HeadPtr; + OS_PEND_DATA *TailPtr; + OS_OBJ_QTY NbrEntries; +}; + + +/* +------------------------------------------------------------------------------------------------------------------------ +* PEND OBJ +* +* Note(s) : (1) The 'os_pend_obj' structure data type is a template/subset for specific kernel objects' data types: +* 'os_flag_grp', 'os_mutex', 'os_q', and 'os_sem'. Each specific kernel object data type MUST define +* ALL generic OS pend object parameters, synchronized in both the sequential order & data type of each +* parameter. +* +* Thus, ANY modification to the sequential order or data types of OS pend object parameters MUST be +* appropriately synchronized between the generic OS pend object data type & ALL specific kernel objects' +* data types. +------------------------------------------------------------------------------------------------------------------------ +*/ + +struct os_pend_obj { +#if OS_OBJ_TYPE_REQ > 0u + OS_OBJ_TYPE Type; +#endif +#if OS_CFG_DBG_EN > 0u + CPU_CHAR *NamePtr; +#endif + OS_PEND_LIST PendList; /* List of tasks pending on object */ +#if OS_CFG_DBG_EN > 0u + void *DbgPrevPtr; + void *DbgNextPtr; + CPU_CHAR *DbgNamePtr; +#endif +}; + + +/* +------------------------------------------------------------------------------------------------------------------------ +* EVENT FLAGS +* +* Note(s) : See PEND OBJ Note #1'. +------------------------------------------------------------------------------------------------------------------------ +*/ + + +struct os_flag_grp { /* Event Flag Group */ + /* ------------------ GENERIC MEMBERS ------------------ */ +#if OS_OBJ_TYPE_REQ > 0u + OS_OBJ_TYPE Type; /* Should be set to OS_OBJ_TYPE_FLAG */ +#endif +#if OS_CFG_DBG_EN > 0u + CPU_CHAR *NamePtr; /* Pointer to Event Flag Name (NUL terminated ASCII) */ +#endif + OS_PEND_LIST PendList; /* List of tasks waiting on event flag group */ +#if OS_CFG_DBG_EN > 0u + OS_FLAG_GRP *DbgPrevPtr; + OS_FLAG_GRP *DbgNextPtr; + CPU_CHAR *DbgNamePtr; +#endif + /* ------------------ SPECIFIC MEMBERS ------------------ */ + OS_FLAGS Flags; /* 8, 16 or 32 bit flags */ + CPU_TS TS; /* Timestamp of when last post occurred */ +#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) + CPU_INT32U FlagID; /* Unique ID for third-party debuggers and tracers. */ +#endif +}; + + +/* +------------------------------------------------------------------------------------------------------------------------ +* MEMORY PARTITIONS +------------------------------------------------------------------------------------------------------------------------ +*/ + + +struct os_mem { /* MEMORY CONTROL BLOCK */ +#if OS_OBJ_TYPE_REQ > 0u + OS_OBJ_TYPE Type; /* Should be set to OS_OBJ_TYPE_MEM */ +#endif + void *AddrPtr; /* Pointer to beginning of memory partition */ +#if OS_CFG_DBG_EN > 0u + CPU_CHAR *NamePtr; +#endif + void *FreeListPtr; /* Pointer to list of free memory blocks */ + OS_MEM_SIZE BlkSize; /* Size (in bytes) of each block of memory */ + OS_MEM_QTY NbrMax; /* Total number of blocks in this partition */ + OS_MEM_QTY NbrFree; /* Number of memory blocks remaining in this partition */ +#if OS_CFG_DBG_EN > 0u + OS_MEM *DbgPrevPtr; + OS_MEM *DbgNextPtr; +#endif +#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) + CPU_INT32U MemID; /* Unique ID for third-party debuggers and tracers. */ +#endif +}; + + +/* +------------------------------------------------------------------------------------------------------------------------ +* MESSAGES +------------------------------------------------------------------------------------------------------------------------ +*/ + +struct os_msg { /* MESSAGE CONTROL BLOCK */ + OS_MSG *NextPtr; /* Pointer to next message */ + void *MsgPtr; /* Actual message */ + OS_MSG_SIZE MsgSize; /* Size of the message (in # bytes) */ + CPU_TS MsgTS; /* Time stamp of when message was sent */ +}; + + + + +struct os_msg_pool { /* OS_MSG POOL */ + OS_MSG *NextPtr; /* Pointer to next message */ + OS_MSG_QTY NbrFree; /* Number of messages available from this pool */ + OS_MSG_QTY NbrUsed; /* Current number of messages used */ +#if OS_CFG_DBG_EN > 0u + OS_MSG_QTY NbrUsedMax; /* Peak number of messages used */ +#endif +}; + + + +struct os_msg_q { /* OS_MSG_Q */ + OS_MSG *InPtr; /* Pointer to next OS_MSG to be inserted in the queue */ + OS_MSG *OutPtr; /* Pointer to next OS_MSG to be extracted from the queue */ + OS_MSG_QTY NbrEntriesSize; /* Maximum allowable number of entries in the queue */ + OS_MSG_QTY NbrEntries; /* Current number of entries in the queue */ +#if OS_CFG_DBG_EN > 0u + OS_MSG_QTY NbrEntriesMax; /* Peak number of entries in the queue */ +#endif +#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) + CPU_INT32U MsgQID; /* Unique ID for third-party debuggers and tracers. */ +#endif +}; + + +/* +------------------------------------------------------------------------------------------------------------------------ +* MUTUAL EXCLUSION SEMAPHORES +* +* Note(s) : See PEND OBJ Note #1'. +------------------------------------------------------------------------------------------------------------------------ +*/ + +struct os_mutex { /* Mutual Exclusion Semaphore */ + /* ------------------ GENERIC MEMBERS ------------------ */ +#if OS_OBJ_TYPE_REQ > 0u + OS_OBJ_TYPE Type; /* Should be set to OS_OBJ_TYPE_MUTEX */ +#endif +#if OS_CFG_DBG_EN > 0u + CPU_CHAR *NamePtr; /* Pointer to Mutex Name (NUL terminated ASCII) */ +#endif + OS_PEND_LIST PendList; /* List of tasks waiting on mutex */ +#if OS_CFG_DBG_EN > 0u + OS_MUTEX *DbgPrevPtr; + OS_MUTEX *DbgNextPtr; + CPU_CHAR *DbgNamePtr; +#endif + /* ------------------ SPECIFIC MEMBERS ------------------ */ + OS_MUTEX *MutexGrpNextPtr; + OS_TCB *OwnerTCBPtr; + OS_NESTING_CTR OwnerNestingCtr; /* Mutex is available when the counter is 0 */ + CPU_TS TS; +#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) + CPU_INT08U MutexID; /* Unique ID for third-party debuggers and tracers. */ +#endif +}; + + +/* +------------------------------------------------------------------------------------------------------------------------ +* MESSAGE QUEUES +* +* Note(s) : See PEND OBJ Note #1'. +------------------------------------------------------------------------------------------------------------------------ +*/ + +struct os_q { /* Message Queue */ + /* ------------------ GENERIC MEMBERS ------------------ */ +#if OS_OBJ_TYPE_REQ > 0u + OS_OBJ_TYPE Type; /* Should be set to OS_OBJ_TYPE_Q */ +#endif +#if OS_CFG_DBG_EN > 0u + CPU_CHAR *NamePtr; /* Pointer to Message Queue Name (NUL terminated ASCII) */ +#endif + OS_PEND_LIST PendList; /* List of tasks waiting on message queue */ +#if OS_CFG_DBG_EN > 0u + OS_Q *DbgPrevPtr; + OS_Q *DbgNextPtr; + CPU_CHAR *DbgNamePtr; +#endif + /* ------------------ SPECIFIC MEMBERS ------------------ */ + OS_MSG_Q MsgQ; /* List of messages */ +#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) + CPU_INT08U MsgQID; /* Unique ID for third-party debuggers and tracers. */ +#endif +}; + + +/* +------------------------------------------------------------------------------------------------------------------------ +* SEMAPHORES +* +* Note(s) : See PEND OBJ Note #1'. +------------------------------------------------------------------------------------------------------------------------ +*/ + +struct os_sem { /* Semaphore */ + /* ------------------ GENERIC MEMBERS ------------------ */ +#if OS_OBJ_TYPE_REQ > 0u + OS_OBJ_TYPE Type; /* Should be set to OS_OBJ_TYPE_SEM */ +#endif +#if OS_CFG_DBG_EN > 0u + CPU_CHAR *NamePtr; /* Pointer to Semaphore Name (NUL terminated ASCII) */ +#endif + OS_PEND_LIST PendList; /* List of tasks waiting on semaphore */ +#if OS_CFG_DBG_EN > 0u + OS_SEM *DbgPrevPtr; + OS_SEM *DbgNextPtr; + CPU_CHAR *DbgNamePtr; +#endif + /* ------------------ SPECIFIC MEMBERS ------------------ */ + OS_SEM_CTR Ctr; + CPU_TS TS; +#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) + CPU_INT08U SemID; /* Unique ID for third-party debuggers and tracers. */ +#endif +}; + + +/* +------------------------------------------------------------------------------------------------------------------------ +* TASK CONTROL BLOCK +------------------------------------------------------------------------------------------------------------------------ +*/ + +struct os_tcb { + CPU_STK *StkPtr; /* Pointer to current top of stack */ + + void *ExtPtr; /* Pointer to user definable data for TCB extension */ + +#if ((OS_CFG_DBG_EN > 0u) || (OS_CFG_STAT_TASK_STK_CHK_EN > 0u)) + CPU_STK *StkLimitPtr; /* Pointer used to set stack 'watermark' limit */ +#endif + + OS_TCB *NextPtr; /* Pointer to next TCB in the TCB list */ + OS_TCB *PrevPtr; /* Pointer to previous TCB in the TCB list */ + + OS_TCB *TickNextPtr; + OS_TCB *TickPrevPtr; + + OS_TICK_LIST *TickListPtr; /* Pointer to tick list if task is in a tick list */ + +#if OS_CFG_DBG_EN > 0u + CPU_CHAR *NamePtr; /* Pointer to task name */ +#endif + +#if ((OS_CFG_DBG_EN > 0u) || (OS_CFG_STAT_TASK_STK_CHK_EN > 0u)) + CPU_STK *StkBasePtr; /* Pointer to base address of stack */ +#endif + +#if defined(OS_CFG_TLS_TBL_SIZE) && (OS_CFG_TLS_TBL_SIZE > 0u) + OS_TLS TLS_Tbl[OS_CFG_TLS_TBL_SIZE]; +#endif + +#if OS_CFG_DBG_EN > 0u + OS_TASK_PTR TaskEntryAddr; /* Pointer to task entry point address */ + void *TaskEntryArg; /* Argument passed to task when it was created */ +#endif + + OS_PEND_DATA *PendDataTblPtr; /* Pointer to list containing objects pended on */ + OS_STATE PendOn; /* Indicates what task is pending on */ + OS_STATUS PendStatus; /* Pend status */ + + OS_STATE TaskState; /* See OS_TASK_STATE_xxx */ + OS_PRIO Prio; /* Task priority (0 == highest) */ +#if OS_CFG_MUTEX_EN > 0u + OS_PRIO BasePrio; /* Base priority (Not inherited) */ + OS_MUTEX *MutexGrpHeadPtr; /* Owned mutex group head pointer */ +#endif + +#if ((OS_CFG_DBG_EN > 0u) || (OS_CFG_STAT_TASK_STK_CHK_EN > 0u)) + CPU_STK_SIZE StkSize; /* Size of task stack (in number of stack elements) */ +#endif + OS_OPT Opt; /* Task options as passed by OSTaskCreate() */ + + OS_OBJ_QTY PendDataTblEntries; /* Size of array of objects to pend on */ + + CPU_TS TS; /* Timestamp */ +#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) + CPU_INT08U SemID; /* Unique ID for third-party debuggers and tracers. */ +#endif + OS_SEM_CTR SemCtr; /* Task specific semaphore counter */ + + /* DELAY / TIMEOUT */ + OS_TICK TickRemain; /* Number of ticks remaining (updated at by OS_TickTask() */ + OS_TICK TickCtrPrev; /* Used by OSTimeDlyXX() in PERIODIC mode */ + +#if OS_CFG_SCHED_ROUND_ROBIN_EN > 0u + OS_TICK TimeQuanta; + OS_TICK TimeQuantaCtr; +#endif + +#if OS_MSG_EN > 0u + void *MsgPtr; /* Message received */ + OS_MSG_SIZE MsgSize; +#endif + +#if OS_CFG_TASK_Q_EN > 0u + OS_MSG_Q MsgQ; /* Message queue associated with task */ +#if OS_CFG_TASK_PROFILE_EN > 0u + CPU_TS MsgQPendTime; /* Time it took for signal to be received */ + CPU_TS MsgQPendTimeMax; /* Max amount of time it took for signal to be received */ +#endif +#endif + +#if OS_CFG_TASK_REG_TBL_SIZE > 0u + OS_REG RegTbl[OS_CFG_TASK_REG_TBL_SIZE]; /* Task specific registers */ +#endif + +#if OS_CFG_FLAG_EN > 0u + OS_FLAGS FlagsPend; /* Event flag(s) to wait on */ + OS_FLAGS FlagsRdy; /* Event flags that made task ready to run */ + OS_OPT FlagsOpt; /* Options (See OS_OPT_FLAG_xxx) */ +#endif + +#if OS_CFG_TASK_SUSPEND_EN > 0u + OS_NESTING_CTR SuspendCtr; /* Nesting counter for OSTaskSuspend() */ +#endif + +#if OS_CFG_TASK_PROFILE_EN > 0u + OS_CPU_USAGE CPUUsage; /* CPU Usage of task (0.00-100.00%) */ + OS_CPU_USAGE CPUUsageMax; /* CPU Usage of task (0.00-100.00%) - Peak */ + OS_CTX_SW_CTR CtxSwCtr; /* Number of time the task was switched in */ + CPU_TS CyclesDelta; /* value of OS_TS_GET() - .CyclesStart */ + CPU_TS CyclesStart; /* Snapshot of cycle counter at start of task resumption */ + OS_CYCLES CyclesTotal; /* Total number of # of cycles the task has been running */ + OS_CYCLES CyclesTotalPrev; /* Snapshot of previous # of cycles */ + + CPU_TS SemPendTime; /* Time it took for signal to be received */ + CPU_TS SemPendTimeMax; /* Max amount of time it took for signal to be received */ +#endif + +#if OS_CFG_STAT_TASK_STK_CHK_EN > 0u + CPU_STK_SIZE StkUsed; /* Number of stack elements used from the stack */ + CPU_STK_SIZE StkFree; /* Number of stack elements free on the stack */ +#endif + +#ifdef CPU_CFG_INT_DIS_MEAS_EN + CPU_TS IntDisTimeMax; /* Maximum interrupt disable time */ +#endif +#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u + CPU_TS SchedLockTimeMax; /* Maximum scheduler lock time */ +#endif + +#if OS_CFG_DBG_EN > 0u + OS_TCB *DbgPrevPtr; + OS_TCB *DbgNextPtr; + CPU_CHAR *DbgNamePtr; +#endif +#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) + CPU_INT08U TaskID; /* Unique ID for third-party debuggers and tracers. */ +#endif +}; + + +/* +------------------------------------------------------------------------------------------------------------------------ +* TICK DATA TYPE +------------------------------------------------------------------------------------------------------------------------ +*/ + +struct os_tick_list { + OS_TCB *TCB_Ptr; /* Pointer to list of tasks in tick list */ +#if OS_CFG_DBG_EN > 0u + OS_OBJ_QTY NbrEntries; /* Current number of entries in the tick list */ + OS_OBJ_QTY NbrUpdated; /* Number of entries updated */ +#endif +}; + + +/* +------------------------------------------------------------------------------------------------------------------------ +* TIMER DATA TYPES +------------------------------------------------------------------------------------------------------------------------ +*/ + +struct os_tmr { +#if OS_OBJ_TYPE_REQ > 0u + OS_OBJ_TYPE Type; +#endif +#if OS_CFG_DBG_EN > 0u + CPU_CHAR *NamePtr; /* Name to give the timer */ +#endif + OS_TMR_CALLBACK_PTR CallbackPtr; /* Function to call when timer expires */ + void *CallbackPtrArg; /* Argument to pass to function when timer expires */ + OS_TMR *NextPtr; /* Double link list pointers */ + OS_TMR *PrevPtr; + OS_TICK Remain; /* Amount of time remaining before timer expires */ + OS_TICK Dly; /* Delay before start of repeat */ + OS_TICK Period; /* Period to repeat timer */ + OS_OPT Opt; /* Options (see OS_OPT_TMR_xxx) */ + OS_STATE State; +#if OS_CFG_DBG_EN > 0u + OS_TMR *DbgPrevPtr; + OS_TMR *DbgNextPtr; +#endif +}; + + +/* +************************************************************************************************************************ +************************************************************************************************************************ +* G L O B A L V A R I A B L E S +************************************************************************************************************************ +************************************************************************************************************************ +*/ + +#if OS_CFG_APP_HOOKS_EN > 0u +OS_EXT OS_APP_HOOK_TCB OS_AppTaskCreateHookPtr; /* Application hooks */ +OS_EXT OS_APP_HOOK_TCB OS_AppTaskDelHookPtr; +OS_EXT OS_APP_HOOK_TCB OS_AppTaskReturnHookPtr; + +OS_EXT OS_APP_HOOK_VOID OS_AppIdleTaskHookPtr; +OS_EXT OS_APP_HOOK_VOID OS_AppStatTaskHookPtr; +OS_EXT OS_APP_HOOK_VOID OS_AppTaskSwHookPtr; +OS_EXT OS_APP_HOOK_VOID OS_AppTimeTickHookPtr; +#endif + + /* IDLE TASK -------------------------------- */ +OS_EXT OS_IDLE_CTR OSIdleTaskCtr; +OS_EXT OS_TCB OSIdleTaskTCB; + + /* MISCELLANEOUS ---------------------------- */ +OS_EXT OS_NESTING_CTR OSIntNestingCtr; /* Interrupt nesting level */ +#ifdef CPU_CFG_INT_DIS_MEAS_EN +OS_EXT CPU_TS OSIntDisTimeMax; /* Overall interrupt disable time */ +#endif + +OS_EXT OS_STATE OSRunning; /* Flag indicating that kernel is running */ + + + /* ISR HANDLER TASK ------------------------- */ +#if OS_CFG_ISR_POST_DEFERRED_EN > 0u +OS_EXT OS_INT_Q *OSIntQInPtr; +OS_EXT OS_INT_Q *OSIntQOutPtr; +OS_EXT OS_OBJ_QTY OSIntQNbrEntries; +OS_EXT OS_OBJ_QTY OSIntQNbrEntriesMax; +OS_EXT OS_OBJ_QTY OSIntQOvfCtr; +OS_EXT OS_TCB OSIntQTaskTCB; +OS_EXT CPU_TS OSIntQTaskTimeMax; +#endif + + /* FLAGS ------------------------------------ */ +#if OS_CFG_FLAG_EN > 0u +#if OS_CFG_DBG_EN > 0u +OS_EXT OS_FLAG_GRP *OSFlagDbgListPtr; +#endif +OS_EXT OS_OBJ_QTY OSFlagQty; +#endif + + /* MEMORY MANAGEMENT ------------------------ */ +#if OS_CFG_MEM_EN > 0u +#if OS_CFG_DBG_EN > 0u +OS_EXT OS_MEM *OSMemDbgListPtr; +#endif +OS_EXT OS_OBJ_QTY OSMemQty; /* Number of memory partitions created */ +#endif + + /* OS_MSG POOL ------------------------------ */ +#if OS_MSG_EN > 0u +OS_EXT OS_MSG_POOL OSMsgPool; /* Pool of OS_MSG */ +#endif + + /* MUTEX MANAGEMENT ------------------------- */ +#if OS_CFG_MUTEX_EN > 0u +#if OS_CFG_DBG_EN > 0u +OS_EXT OS_MUTEX *OSMutexDbgListPtr; +#endif +OS_EXT OS_OBJ_QTY OSMutexQty; /* Number of mutexes created */ +#endif + + /* PRIORITIES ------------------------------- */ +OS_EXT OS_PRIO OSPrioCur; /* Priority of current task */ +OS_EXT OS_PRIO OSPrioHighRdy; /* Priority of highest priority task */ +OS_EXT OS_PRIO OSPrioSaved; /* Saved priority level when Post Deferred */ +extern CPU_DATA OSPrioTbl[OS_PRIO_TBL_SIZE]; + + /* QUEUES ----------------------------------- */ +#if OS_CFG_Q_EN > 0u +#if OS_CFG_DBG_EN > 0u +OS_EXT OS_Q *OSQDbgListPtr; +#endif +OS_EXT OS_OBJ_QTY OSQQty; /* Number of message queues created */ +#endif + + + + /* READY LIST ------------------------------- */ +OS_EXT OS_RDY_LIST OSRdyList[OS_CFG_PRIO_MAX]; /* Table of tasks ready to run */ + + +#ifdef OS_SAFETY_CRITICAL_IEC61508 +OS_EXT CPU_BOOLEAN OSSafetyCriticalStartFlag; /* Flag indicating that all init. done */ +#endif + /* SCHEDULER -------------------------------- */ +#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u +OS_EXT CPU_TS_TMR OSSchedLockTimeBegin; /* Scheduler lock time measurement */ +OS_EXT CPU_TS_TMR OSSchedLockTimeMax; +OS_EXT CPU_TS_TMR OSSchedLockTimeMaxCur; +#endif + +OS_EXT OS_NESTING_CTR OSSchedLockNestingCtr; /* Lock nesting level */ +#if OS_CFG_SCHED_ROUND_ROBIN_EN > 0u +OS_EXT OS_TICK OSSchedRoundRobinDfltTimeQuanta; +OS_EXT CPU_BOOLEAN OSSchedRoundRobinEn; /* Enable/Disable round-robin scheduling */ +#endif + /* SEMAPHORES ------------------------------- */ +#if OS_CFG_SEM_EN > 0u +#if OS_CFG_DBG_EN > 0u +OS_EXT OS_SEM *OSSemDbgListPtr; +#endif +OS_EXT OS_OBJ_QTY OSSemQty; /* Number of semaphores created */ +#endif + + /* STATISTICS ------------------------------- */ +#if OS_CFG_STAT_TASK_EN > 0u +OS_EXT CPU_BOOLEAN OSStatResetFlag; /* Force the reset of the computed statistics */ +OS_EXT OS_CPU_USAGE OSStatTaskCPUUsage; /* CPU Usage in % */ +OS_EXT OS_CPU_USAGE OSStatTaskCPUUsageMax; /* CPU Usage in % (Peak) */ +OS_EXT OS_TICK OSStatTaskCtr; +OS_EXT OS_TICK OSStatTaskCtrMax; +OS_EXT OS_TICK OSStatTaskCtrRun; +OS_EXT CPU_BOOLEAN OSStatTaskRdy; +OS_EXT OS_TCB OSStatTaskTCB; +OS_EXT CPU_TS OSStatTaskTimeMax; +#endif + + /* TASKS ------------------------------------ */ +OS_EXT OS_CTX_SW_CTR OSTaskCtxSwCtr; /* Number of context switches */ +#if OS_CFG_DBG_EN > 0u +OS_EXT OS_TCB *OSTaskDbgListPtr; +#endif +OS_EXT OS_OBJ_QTY OSTaskQty; /* Number of tasks created */ + +#if OS_CFG_TASK_REG_TBL_SIZE > 0u +OS_EXT OS_REG_ID OSTaskRegNextAvailID; /* Next available Task Register ID */ +#endif + + /* TICK TASK -------------------------------- */ +OS_EXT OS_TICK OSTickCtr; /* Cnts the #ticks since startup or last set */ +OS_EXT OS_TCB OSTickTaskTCB; +OS_EXT CPU_TS OSTickTaskTimeMax; +OS_EXT OS_TICK_LIST OSTickListDly; +OS_EXT OS_TICK_LIST OSTickListTimeout; + + + +#if OS_CFG_TMR_EN > 0u /* TIMERS ----------------------------------- */ +#if OS_CFG_DBG_EN > 0u +OS_EXT OS_TMR *OSTmrDbgListPtr; +#endif +OS_EXT OS_OBJ_QTY OSTmrListEntries; /* Doubly-linked list of timers */ +OS_EXT OS_TMR *OSTmrListPtr; +#if OS_CFG_MUTEX_EN > 0u /* Use a Mutex (if available) to protect tmrs */ +OS_EXT OS_MUTEX OSTmrMutex; +#endif +OS_EXT OS_OBJ_QTY OSTmrQty; /* Number of timers created */ +OS_EXT OS_TCB OSTmrTaskTCB; /* TCB of timer task */ +OS_EXT CPU_TS OSTmrTaskTimeMax; +OS_EXT OS_TICK OSTmrTickCtr; /* Current time for the timers */ +OS_EXT OS_CTR OSTmrUpdateCnt; /* Counter for updating timers */ +OS_EXT OS_CTR OSTmrUpdateCtr; +#endif + + + + + /* TCBs ------------------------------------- */ +OS_EXT OS_TCB *OSTCBCurPtr; /* Pointer to currently running TCB */ +OS_EXT OS_TCB *OSTCBHighRdyPtr; /* Pointer to highest priority TCB */ + + +/* +************************************************************************************************************************ +************************************************************************************************************************ +* E X T E R N A L S +************************************************************************************************************************ +************************************************************************************************************************ +*/ + +extern CPU_STK * const OSCfg_IdleTaskStkBasePtr; +extern CPU_STK_SIZE const OSCfg_IdleTaskStkLimit; +extern CPU_STK_SIZE const OSCfg_IdleTaskStkSize; +extern CPU_INT32U const OSCfg_IdleTaskStkSizeRAM; + +extern OS_INT_Q * const OSCfg_IntQBasePtr; +extern OS_OBJ_QTY const OSCfg_IntQSize; +extern CPU_INT32U const OSCfg_IntQSizeRAM; +extern CPU_STK * const OSCfg_IntQTaskStkBasePtr; +extern CPU_STK_SIZE const OSCfg_IntQTaskStkLimit; +extern CPU_STK_SIZE const OSCfg_IntQTaskStkSize; +extern CPU_INT32U const OSCfg_IntQTaskStkSizeRAM; + +extern CPU_STK * const OSCfg_ISRStkBasePtr; +extern CPU_STK_SIZE const OSCfg_ISRStkSize; +extern CPU_INT32U const OSCfg_ISRStkSizeRAM; + +extern OS_MSG_SIZE const OSCfg_MsgPoolSize; +extern CPU_INT32U const OSCfg_MsgPoolSizeRAM; +extern OS_MSG * const OSCfg_MsgPoolBasePtr; + +extern OS_PRIO const OSCfg_StatTaskPrio; +extern OS_RATE_HZ const OSCfg_StatTaskRate_Hz; +extern CPU_STK * const OSCfg_StatTaskStkBasePtr; +extern CPU_STK_SIZE const OSCfg_StatTaskStkLimit; +extern CPU_STK_SIZE const OSCfg_StatTaskStkSize; +extern CPU_INT32U const OSCfg_StatTaskStkSizeRAM; + +extern CPU_STK_SIZE const OSCfg_StkSizeMin; + +extern OS_RATE_HZ const OSCfg_TickRate_Hz; +extern OS_PRIO const OSCfg_TickTaskPrio; +extern CPU_STK * const OSCfg_TickTaskStkBasePtr; +extern CPU_STK_SIZE const OSCfg_TickTaskStkLimit; +extern CPU_STK_SIZE const OSCfg_TickTaskStkSize; +extern CPU_INT32U const OSCfg_TickTaskStkSizeRAM; + +extern OS_PRIO const OSCfg_TmrTaskPrio; +extern OS_RATE_HZ const OSCfg_TmrTaskRate_Hz; +extern CPU_STK * const OSCfg_TmrTaskStkBasePtr; +extern CPU_STK_SIZE const OSCfg_TmrTaskStkLimit; +extern CPU_STK_SIZE const OSCfg_TmrTaskStkSize; +extern CPU_INT32U const OSCfg_TmrTaskStkSizeRAM; + + +extern CPU_STK OSCfg_IdleTaskStk[]; + +#if (OS_CFG_ISR_POST_DEFERRED_EN > 0u) +extern CPU_STK OSCfg_IntQTaskStk[]; +extern OS_INT_Q OSCfg_IntQ[]; +#endif + +extern CPU_STK OSCfg_ISRStk[]; + +#if (OS_MSG_EN > 0u) +extern OS_MSG OSCfg_MsgPool[]; +#endif + +#if (OS_CFG_STAT_TASK_EN > 0u) +extern CPU_STK OSCfg_StatTaskStk[]; +#endif + +extern CPU_STK OSCfg_TickTaskStk[]; + +#if (OS_CFG_TMR_EN > 0u) +extern CPU_STK OSCfg_TmrTaskStk[]; +#endif + + + +DECLARE_FAKE_VOID_FUNC(OSMutexCreate, OS_MUTEX*, char* , OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSMutexPend, OS_MUTEX*, OS_TICK, OS_OPT, CPU_TS*, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSMutexPost, OS_MUTEX*, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSSemCreate, OS_SEM*, CPU_CHAR*, OS_SEM_CTR, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSSemPend, OS_SEM*, OS_TICK, OS_OPT, CPU_TS*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSSemPendAbort, OS_SEM*, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSSemPost, OS_SEM*, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSSemSet, OS_SEM*, OS_SEM_CTR, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskCreate, OS_TCB*, CPU_CHAR*, OS_TASK_PTR, void*, OS_PRIO, CPU_STK*, CPU_STK_SIZE, CPU_STK_SIZE, OS_MSG_QTY, OS_TICK, void*, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskDel, OS_TCB*, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTimeDly, OS_TICK, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTimeDlyHMSM, CPU_INT16U, CPU_INT16U, CPU_INT16U, CPU_INT32U, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTmrCreate, OS_TMR*, CPU_CHAR*, OS_TICK, OS_TICK, OS_OPT, OS_TMR_CALLBACK_PTR, void*, OS_ERR*); + +#endif +// #endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/RTOS/os_cfg.h b/Tests/UnitTests/Mocks/RTOS/os_cfg.h new file mode 100644 index 000000000..7de686f52 --- /dev/null +++ b/Tests/UnitTests/Mocks/RTOS/os_cfg.h @@ -0,0 +1,117 @@ +/* +************************************************************************************************************************ +* uC/OS-III +* The Real-Time Kernel +* +* (c) Copyright 2009-2015; Micrium, Inc.; Weston, FL +* All rights reserved. Protected by international copyright laws. +* +* CONFIGURATION FILE +* +* File : OS_CFG.H +* By : JJL +* Version : V3.04.05 +* +* LICENSING TERMS: +* --------------- +* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or +* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/ +* product then, you need to contact Micrium to properly license uC/OS-III for its use in your +* application/product. We provide ALL the source code for your convenience and to help you +* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use +* it commercially without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the embedded community with the finest software available. +* Your honesty is greatly appreciated. +* +* You can find our product's user manual, API reference, release notes and +* more information at https://doc.micrium.com. +* You can contact us at www.micrium.com. +************************************************************************************************************************ +*/ + +#ifndef OS_CFG_H +#define OS_CFG_H + + /* ---------------------------- MISCELLANEOUS -------------------------- */ +#define OS_CFG_APP_HOOKS_EN 1u /* Enable (1) or Disable (0) application specific hooks */ +#define OS_CFG_ARG_CHK_EN 0u /* Enable (1) or Disable (0) argument checking */ +#define OS_CFG_CALLED_FROM_ISR_CHK_EN 0u /* Enable (1) or Disable (0) check for called from ISR */ +#define OS_CFG_DBG_EN 1u /* Enable (1) debug code/variables */ +#define OS_CFG_ISR_POST_DEFERRED_EN 0u /* Enable (1) or Disable (0) Deferred ISR posts */ +#define OS_CFG_OBJ_TYPE_CHK_EN 1u /* Enable (1) or Disable (0) object type checking */ +#define OS_CFG_TS_EN 1u /* Enable (1) or Disable (0) time stamping */ + +#define OS_CFG_PEND_MULTI_EN 1u /* Enable (1) or Disable (0) code generation for multi-pend feature */ + +#define OS_CFG_PRIO_MAX 32u /* Defines the maximum number of task priorities (see OS_PRIO data type) */ + +#define OS_CFG_SCHED_LOCK_TIME_MEAS_EN 0u /* Include code to measure scheduler lock time */ +#define OS_CFG_SCHED_ROUND_ROBIN_EN 0u /* Include code for Round-Robin scheduling */ +#define OS_CFG_STK_SIZE_MIN 64u /* Minimum allowable task stack size */ + + + /* ----------------------------- EVENT FLAGS --------------------------- */ +#define OS_CFG_FLAG_EN 1u /* Enable (1) or Disable (0) code generation for EVENT FLAGS */ +#define OS_CFG_FLAG_DEL_EN 0u /* Include code for OSFlagDel() */ +#define OS_CFG_FLAG_MODE_CLR_EN 0u /* Include code for Wait on Clear EVENT FLAGS */ +#define OS_CFG_FLAG_PEND_ABORT_EN 0u /* Include code for OSFlagPendAbort() */ + + + /* -------------------------- MEMORY MANAGEMENT ------------------------ */ +#define OS_CFG_MEM_EN 1u /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */ + + + /* --------------------- MUTUAL EXCLUSION SEMAPHORES ------------------- */ +#define OS_CFG_MUTEX_EN 1u /* Enable (1) or Disable (0) code generation for MUTEX */ +#define OS_CFG_MUTEX_DEL_EN 0u /* Include code for OSMutexDel() */ +#define OS_CFG_MUTEX_PEND_ABORT_EN 0u /* Include code for OSMutexPendAbort() */ + + + /* --------------------------- MESSAGE QUEUES -------------------------- */ +#define OS_CFG_Q_EN 1u /* Enable (1) or Disable (0) code generation for QUEUES */ +#define OS_CFG_Q_DEL_EN 0u /* Include code for OSQDel() */ +#define OS_CFG_Q_FLUSH_EN 0u /* Include code for OSQFlush() */ +#define OS_CFG_Q_PEND_ABORT_EN 1u /* Include code for OSQPendAbort() */ + + + /* ----------------------------- SEMAPHORES ---------------------------- */ +#define OS_CFG_SEM_EN 1u /* Enable (1) or Disable (0) code generation for SEMAPHORES */ +#define OS_CFG_SEM_DEL_EN 1u /* Include code for OSSemDel() */ +#define OS_CFG_SEM_PEND_ABORT_EN 1u /* Include code for OSSemPendAbort() */ +#define OS_CFG_SEM_SET_EN 1u /* Include code for OSSemSet() */ + + + /* -------------------------- TASK MANAGEMENT -------------------------- */ +#define OS_CFG_STAT_TASK_EN 1u /* Enable (1) or Disable(0) the statistics task */ +#define OS_CFG_STAT_TASK_STK_CHK_EN 1u /* Check task stacks from statistic task */ + +#define OS_CFG_TASK_CHANGE_PRIO_EN 1u /* Include code for OSTaskChangePrio() */ +#define OS_CFG_TASK_DEL_EN 1u /* Include code for OSTaskDel() */ +#define OS_CFG_TASK_Q_EN 1u /* Include code for OSTaskQXXXX() */ +#define OS_CFG_TASK_Q_PEND_ABORT_EN 0u /* Include code for OSTaskQPendAbort() */ +#define OS_CFG_TASK_PROFILE_EN 1u /* Include variables in OS_TCB for profiling */ +#define OS_CFG_TASK_REG_TBL_SIZE 1u /* Number of task specific registers */ +#define OS_CFG_TASK_SEM_PEND_ABORT_EN 1u /* Include code for OSTaskSemPendAbort() */ +#define OS_CFG_TASK_SUSPEND_EN 1u /* Include code for OSTaskSuspend() and OSTaskResume() */ + + + /* -------------------------- TIME MANAGEMENT -------------------------- */ +#define OS_CFG_TIME_DLY_HMSM_EN 1u /* Include code for OSTimeDlyHMSM() */ +#define OS_CFG_TIME_DLY_RESUME_EN 0u /* Include code for OSTimeDlyResume() */ + + + /* ------------------- TASK LOCAL STORAGE MANAGEMENT ------------------- */ +#define OS_CFG_TLS_TBL_SIZE 0u /* Include code for Task Local Storage (TLS) registers */ + + + /* ------------------------- TIMER MANAGEMENT -------------------------- */ +#define OS_CFG_TMR_EN 1u /* Enable (1) or Disable (0) code generation for TIMERS */ +#define OS_CFG_TMR_DEL_EN 0u /* Enable (1) or Disable (0) code generation for OSTmrDel() */ + + /* ------------------------------ uC/TRACE ----------------------------- */ +#define TRACE_CFG_EN 0u /* Enable (1) or Disable (0) uC/Trace instrumentation */ + +#endif diff --git a/Tests/UnitTests/Mocks/RTOS/os_type.h b/Tests/UnitTests/Mocks/RTOS/os_type.h new file mode 100644 index 000000000..22bd2f8d0 --- /dev/null +++ b/Tests/UnitTests/Mocks/RTOS/os_type.h @@ -0,0 +1,98 @@ +/* +************************************************************************************************************************ +* uC/OS-III +* The Real-Time Kernel +* +* (c) Copyright 2009-2015; Micrium, Inc.; Weston, FL +* All rights reserved. Protected by international copyright laws. +* +* File : OS_TYPE.H +* By : JJL +* Version : V3.05.01 +* +* LICENSING TERMS: +* --------------- +* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or +* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/ +* product then, you need to contact Micrium to properly license uC/OS-III for its use in your +* application/product. We provide ALL the source code for your convenience and to help you +* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use +* it commercially without paying a licensing fee. +* +* Knowledge of the source code may NOT be used to develop a similar product. +* +* Please help us continue to provide the embedded community with the finest software available. +* Your honesty is greatly appreciated. +* +* You can find our product's user manual, API reference, release notes and +* more information at https://doc.micrium.com. +* You can contact us at www.micrium.com. +************************************************************************************************************************ +*/ + +#ifndef OS_TYPE_H +#define OS_TYPE_H +#include "cpu.h" +#ifdef VSC_INCLUDE_H_FILE_NAMES +const CPU_CHAR *os_type__h = "$Id: $"; +#endif + +/* +************************************************************************************************************************ +* INCLUDE HEADER FILES +************************************************************************************************************************ +*/ + + /* Description # Bits */ + /* */ + /* ----------------------------------------------------------- */ + +typedef CPU_INT16U OS_CPU_USAGE; /* CPU Usage 0..10000 <16>/32 */ + +typedef CPU_INT32U OS_CTR; /* Counter, 32 */ + +typedef CPU_INT32U OS_CTX_SW_CTR; /* Counter of context switches, 32 */ + +typedef CPU_INT32U OS_CYCLES; /* CPU clock cycles, <32>/64 */ + +typedef CPU_INT32U OS_FLAGS; /* Event flags, 8/16/<32> */ + +typedef CPU_INT32U OS_IDLE_CTR; /* Holds the number of times the idle task runs, <32>/64 */ + +typedef CPU_INT16U OS_MEM_QTY; /* Number of memory blocks, <16>/32 */ +typedef CPU_INT16U OS_MEM_SIZE; /* Size in bytes of a memory block, <16>/32 */ + +typedef CPU_INT16U OS_MSG_QTY; /* Number of OS_MSGs in the msg pool, <16>/32 */ +typedef CPU_INT16U OS_MSG_SIZE; /* Size of messages in number of bytes, <16>/32 */ + +typedef CPU_INT08U OS_NESTING_CTR; /* Interrupt and scheduler nesting, <8>/16/32 */ + +typedef CPU_INT16U OS_OBJ_QTY; /* Number of kernel objects counter, <16>/32 */ +typedef CPU_INT32U OS_OBJ_TYPE; /* Special flag to determine object type, 32 */ + +typedef CPU_INT16U OS_OPT; /* Holds function options, <16>/32 */ + +typedef CPU_INT32U OS_MON_RES; /* Monitor result flags, */ + +typedef CPU_INT08U OS_PRIO; /* Priority of a task, <8>/16/32 */ + +typedef CPU_INT16U OS_QTY; /* Quantity <16>/32 */ + +typedef CPU_INT32U OS_RATE_HZ; /* Rate in Hertz 32 */ + +#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_64) /* Task register 8/16/<32/64> */ +typedef CPU_INT64U OS_REG; +#else +typedef CPU_INT32U OS_REG; +#endif +typedef CPU_INT08U OS_REG_ID; /* Index to task register <8>/16/32 */ + +typedef CPU_INT32U OS_SEM_CTR; /* Semaphore value 16/<32> */ + +typedef CPU_INT08U OS_STATE; /* State variable <8>/16/32 */ + +typedef CPU_INT08U OS_STATUS; /* Status <8>/16/32 */ + +typedef CPU_INT32U OS_TICK; /* Clock tick counter <32>/64 */ + +#endif diff --git a/Tests/UnitTests/Tests/Test_ReadCarCAN.c b/Tests/UnitTests/Tests/Test_ReadCarCAN.c new file mode 100644 index 000000000..5825d72b6 --- /dev/null +++ b/Tests/UnitTests/Tests/Test_ReadCarCAN.c @@ -0,0 +1,44 @@ +////////////////////////////////////////// +////////////////////////////////////////// +// Unity required for this testing format +#include "unity.h" +////////////////////////////////////////// +////////////////////////////////////////// +// The header file we are unit testing: +#include "ReadCarCAN.h" +////////////////////////////////////////// +// fff header so we can DEFINE_FFF_GLOBALS +// (can only happen once per test) +#include "fff.h" + +DEFINE_FFF_GLOBALS; + + +/*** CAN Messages ***/ +// static CANDATA_t bps_trip_msg = {.ID=BPS_TRIP, .idx=0, .data={1}}; +// static CANDATA_t supp_voltage_msg = {.ID=SUPPLEMENTAL_VOLTAGE, .idx=0, .data={100}}; +// static CANDATA_t state_of_charge_msg = {.ID=STATE_OF_CHARGE, .idx=0, .data={0}}; +// static CANDATA_t HV_Array_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b001}}; +// static CANDATA_t HV_Disable_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b000}}; +// static CANDATA_t HV_MC_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b110}}; +// static CANDATA_t HV_Enabled_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b111}}; + +void setUp(void) {} + +void tearDown(void) {} + +void test_UnitTest_bsptrip(void){ + CANbus_Read_fake.return_val = SUCCESS; + // CANbus_Read_fake.arg0_val = bps_trip_msg; + +} + + + +/*=======MAIN=====*/ +int main(void) +{ + UNITY_BEGIN(); + RUN_TEST(test_UnitTest_bsptrip); + return UNITY_END(); +} \ No newline at end of file From 41a6a189579fee6cefea632b06488af91afad947 Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Wed, 10 Jan 2024 05:39:34 +0000 Subject: [PATCH 15/57] Continued working on ReadCarCAN unit test, currently not working with tasks as the task mocks are not being referenced --- .vscode/LHR.code-workspace | 3 +- Apps/Src/ReadCarCAN.c | 25 +-- Tests/UnitTests/Mocks/Apps/Inc/Tasks.h | 174 ++++++++++++++++++-- Tests/UnitTests/Mocks/Apps/Src/Tasks.c | 59 +++++-- Tests/UnitTests/Mocks/Drivers/Inc/Minions.h | 10 +- Tests/UnitTests/Tests/Test_ReadCarCAN.c | 23 ++- 6 files changed, 243 insertions(+), 51 deletions(-) diff --git a/.vscode/LHR.code-workspace b/.vscode/LHR.code-workspace index bf60f6eb5..d09f12fea 100644 --- a/.vscode/LHR.code-workspace +++ b/.vscode/LHR.code-workspace @@ -32,7 +32,8 @@ "os.h": "c", "tasks.h": "c", "canbus.h": "c", - "readcarcan.h": "c" + "readcarcan.h": "c", + "minions.h": "c" }, }, "tasks": { diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index f1f8221d6..14ddfbf7e 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -11,6 +11,7 @@ #include "Minions.h" #include "os.h" #include "os_cfg_app.h" +#include "Tasks.h" //#include "Display.h" // Length of the array and motor PBC saturation buffers @@ -44,14 +45,14 @@ // State of Charge scalar to scale it to correct fixed point #define SOC_SCALER 1000000 -// // CAN watchdog timer variable -// static OS_TMR canWatchTimer; +// CAN watchdog timer variable +static OS_TMR canWatchTimer; -// // Array precharge bypass contactor delay timer variable -// static OS_TMR arrayPBCDlyTimer; +// Array precharge bypass contactor delay timer variable +static OS_TMR arrayPBCDlyTimer; -// // Motor controller precharge bypass contactor delay timer variable -// static OS_TMR motorControllerPBCDlyTimer; +// Motor controller precharge bypass contactor delay timer variable +static OS_TMR motorControllerPBCDlyTimer; // NOTE: This should not be written to anywhere other than ReadCarCAN. If the need arises, a mutex to protect it must be added. // Indicates whether or not regenerative braking / charging is enabled. @@ -122,7 +123,7 @@ static void disableArrayPrechargeBypassContactor(void){ // Assert error to disable regen and update saturation in callback function assertReadCarCANError(READCARCAN_ERR_CHARGE_DISABLE); // Turn off the array contactor display light - UpdateDisplay_SetArray(false); // Can assume contactor turned off or else this won't be reached + //UpdateDisplay_SetArray(false); // Can assume contactor turned off or else this won't be reached } /** @@ -224,7 +225,7 @@ static void updateHVPlusMinusSaturation(int8_t messageState){ void attemptTurnArrayPBCOn(void){ if(arrPBCComplete && chargeEnable){ Contactors_Set(ARRAY_PRECHARGE_BYPASS_CONTACTOR, ON, true); // Turn on - UpdateDisplay_SetArray(true); + //UpdateDisplay_SetArray(true); arrPBCComplete = false; } } @@ -246,7 +247,7 @@ static void updateHVPlusMinusSaturation(int8_t messageState){ */ void turnMotorControllerPBCOff(void){ Contactors_Set(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR, OFF, true); - UpdateDisplay_SetMotor(false); + //UpdateDisplay_SetMotor(false); } @@ -438,7 +439,7 @@ static void handler_ReadCarCAN_contactorsDisable(void) { bool ret = (bool)Contactors_Get(ARRAY_PRECHARGE_BYPASS_CONTACTOR) || (bool)Contactors_Get(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR); if(ret) { // Contactor failed to turn off; display the evac screen and infinite loop - Display_Evac(SOC, SBPV); + //Display_Evac(SOC, SBPV); while(1){;} } } @@ -449,7 +450,7 @@ static void handler_ReadCarCAN_contactorsDisable(void) { */ static void handler_ReadCarCAN_BPSTrip(void) { chargeEnable = false; // Not really necessary but makes inspection less confusing - Display_Evac(SOC, SBPV); // Display evacuation screen + //Display_Evac(SOC, SBPV); // Display evacuation screen } @@ -459,7 +460,7 @@ static void handler_ReadCarCAN_BPSTrip(void) { * @param rcc_err error code to specify the issue encountered */ static void assertReadCarCANError(ReadCarCAN_error_code_t rcc_err){ - Error_ReadCarCAN = (error_code_t) rcc_err; // Store error code for inspection + //Error_ReadCarCAN = (error_code_t) rcc_err; // Store error code for inspection switch (rcc_err) { case READCARCAN_ERR_NONE: diff --git a/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h b/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h index f2be9de83..99fb2fccf 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h @@ -1,32 +1,174 @@ -#ifdef TEST_READCARCAN -#include_next "ReadCarCAN.h" // Include the next instance of the file. -// If the real version is in the include search paths after the mock one, it will include it here -#else // Mocked Contactors.h +// #ifdef TEST_READCARCAN +// #include_next "ReadCarCAN.h" // Include the next instance of the file. +// // If the real version is in the include search paths after the mock one, it will include it here +// #else // Mocked Contactors.h #ifndef __TASKS_H #define __TASKS_H #include "fff.h" +#include "os.h" +#include "common.h" -DECLARE_FAKE_VOID_FUNC(Task_Init); +/** + * Task initialization macro + * @param task name of the task + * @param prio the task's priority + * @param arg the argument to pass to the task + * @param err the local OS_ERR variable + */ -DECLARE_FAKE_VOID_FUNC(Task_SendTritium); +/** + * Priority Definitions + */ +#define TASK_INIT_PRIO 2 +#define TASK_READ_TRITIUM_PRIO 3 +#define TASK_SEND_TRITIUM_PRIO 4 +#define TASK_READ_CAR_CAN_PRIO 5 +#define TASK_UPDATE_DISPLAY_PRIO 6 +#define TASK_SEND_CAR_CAN_PRIO 7 +#define TASK_DEBUG_DUMP_PRIO 8 +#define TASK_COMMAND_LINE_PRIO 9 -DECLARE_FAKE_VOID_FUNC(Task_ReadCarCAN); +/** + * Stack Sizes + */ +#define DEFAULT_STACK_SIZE 256 +#define WATERMARK_STACK_LIMIT DEFAULT_STACK_SIZE/2 -DECLARE_FAKE_VOID_FUNC(Task_UpdateDisplay); +#define TASK_INIT_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_SEND_TRITIUM_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_READ_CAR_CAN_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_UPDATE_DISPLAY_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_READ_TRITIUM_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_SEND_CAR_CAN_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_DEBUG_DUMP_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_COMMAND_LINE_STACK_SIZE DEFAULT_STACK_SIZE -DECLARE_FAKE_VOID_FUNC(Task_ReadTritium); +/** + * Task error variable type +*/ +typedef uint16_t error_code_t; -DECLARE_FAKE_VOID_FUNC(Task_SendCarCAN); +/** + * Task Prototypes + */ +void Task_Init(void* p_arg); -DECLARE_FAKE_VOID_FUNC(Task_DebugDump); +void Task_SendTritium(void* p_arg); -DECLARE_FAKE_VOID_FUNC(Task_CommandLine); +void Task_ReadCarCAN(void* p_arg); -DECLARE_FAKE_VOID_FUNC(TaskSwHook_Init); +void Task_UpdateDisplay(void* p_arg); -DECLARE_FAKE_VOID_FUNC(EmergencyContactorOpen); +void Task_ReadTritium(void* p_arg); -DECLARE_FAKE_VOID_FUNC(_assertOSError); +void Task_SendCarCAN(void* p_arg); + +void Task_DebugDump(void *p_arg); + +void Task_CommandLine(void* p_arg); + + + +/** + * TCBs + */ +extern OS_TCB Init_TCB; +extern OS_TCB SendTritium_TCB; +extern OS_TCB ReadCarCAN_TCB; +extern OS_TCB UpdateDisplay_TCB; +extern OS_TCB ReadTritium_TCB; +extern OS_TCB SendCarCAN_TCB; +extern OS_TCB DebugDump_TCB; +extern OS_TCB CommandLine_TCB; + + +/** + * Stacks + */ +extern CPU_STK Init_Stk[TASK_INIT_STACK_SIZE]; +extern CPU_STK SendTritium_Stk[TASK_SEND_TRITIUM_STACK_SIZE]; +extern CPU_STK ReadCarCAN_Stk[TASK_READ_CAR_CAN_STACK_SIZE]; +extern CPU_STK UpdateDisplay_Stk[TASK_UPDATE_DISPLAY_STACK_SIZE]; +extern CPU_STK ReadTritium_Stk[TASK_READ_TRITIUM_STACK_SIZE]; +extern CPU_STK SendCarCAN_Stk[TASK_SEND_CAR_CAN_STACK_SIZE]; +extern CPU_STK DebugDump_Stk[TASK_DEBUG_DUMP_STACK_SIZE]; +extern CPU_STK CommandLine_Stk[TASK_COMMAND_LINE_STACK_SIZE]; + +/** + * Queues + */ +extern OS_Q CANBus_MsgQ; + +/** + * @brief Initialize the task switch hook + * Registers the hook with the RTOS + */ +void TaskSwHook_Init(void); + +/** + * Task trace + * + * Stores the last TASK_TRACE_LENGTH tasks that were run + * The most recent task is at tasks[index], the one before at tasks[index-1], + * wrapping back around at the beginnning + * + */ +#define TASK_TRACE_LENGTH 8 +typedef struct { + OS_TCB *tasks[TASK_TRACE_LENGTH]; + uint32_t index; +} task_trace_t; + +extern task_trace_t PrevTasks; + +// Store error codes that are set in task error assertion functions +extern error_code_t Error_ReadTritium; +extern error_code_t Error_ReadCarCAN; +extern error_code_t Error_UpdateDisplay; + +/** + * Error-handling option enums +*/ + +// Scheduler lock parameter option for asserting a task error +typedef enum { + OPT_NO_LOCK_SCHED, + OPT_LOCK_SCHED +} error_scheduler_lock_opt_t; + +// Recoverable/nonrecoverable parameter option for asserting a task error +typedef enum { + OPT_RECOV, + OPT_NONRECOV +} error_recov_opt_t; + + +// DECLARE_FAKE_VOID_FUNC(MOCK_TEST); + +DECLARE_FAKE_VOID_FUNC(Task_Init, void*); + +// DECLARE_FAKE_VOID_FUNC(Task_SendTritium, void*); + +DECLARE_FAKE_VOID_FUNC(Task_ReadCarCAN, void*); + +// DECLARE_FAKE_VOID_FUNC(Task_UpdateDisplay, void*); + +// DECLARE_FAKE_VOID_FUNC(Task_ReadTritium, void*); + +// DECLARE_FAKE_VOID_FUNC(Task_SendCarCAN, void*); + +// DECLARE_FAKE_VOID_FUNC(Task_DebugDump, void*); + +// DECLARE_FAKE_VOID_FUNC(Task_CommandLine, void*); + +// DECLARE_FAKE_VOID_FUNC(TaskSwHook_Init); + +// DECLARE_FAKE_VOID_FUNC(EmergencyContactorOpen); + +DECLARE_FAKE_VOID_FUNC(throwTaskError, error_code_t, callback_t, error_scheduler_lock_opt_t, error_recov_opt_t); + + +DECLARE_FAKE_VOID_FUNC(_assertOSError, OS_ERR); #endif -#endif \ No newline at end of file +// #endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Src/Tasks.c b/Tests/UnitTests/Mocks/Apps/Src/Tasks.c index 36ce78330..2a506b63c 100644 --- a/Tests/UnitTests/Mocks/Apps/Src/Tasks.c +++ b/Tests/UnitTests/Mocks/Apps/Src/Tasks.c @@ -1,24 +1,61 @@ #include "fff.h" #include "Tasks.h" +#include "Minions.h" -DEFINE_FAKE_VOID_FUNC(Task_Init); +/** + * TCBs + */ +OS_TCB Init_TCB; +OS_TCB SendTritium_TCB; +OS_TCB ReadCarCAN_TCB; +OS_TCB UpdateDisplay_TCB; +OS_TCB ReadTritium_TCB; +OS_TCB SendCarCAN_TCB; +OS_TCB DebugDump_TCB; +OS_TCB CommandLine_TCB; -DEFINE_FAKE_VOID_FUNC(Task_SendTritium); +// task_trace_t PrevTasks; -DEFINE_FAKE_VOID_FUNC(Task_ReadCarCAN); +/** + * Stacks + */ +// CPU_STK Init_Stk[TASK_INIT_STACK_SIZE]; +// CPU_STK SendTritium_Stk[TASK_SEND_TRITIUM_STACK_SIZE]; +// CPU_STK ReadCarCAN_Stk[TASK_READ_CAR_CAN_STACK_SIZE]; +// CPU_STK UpdateDisplay_Stk[TASK_UPDATE_DISPLAY_STACK_SIZE]; +// CPU_STK ReadTritium_Stk[TASK_READ_TRITIUM_STACK_SIZE]; +// CPU_STK SendCarCAN_Stk[TASK_SEND_CAR_CAN_STACK_SIZE]; +// CPU_STK DebugDump_Stk[TASK_DEBUG_DUMP_STACK_SIZE]; +// CPU_STK CommandLine_Stk[TASK_COMMAND_LINE_STACK_SIZE]; -DEFINE_FAKE_VOID_FUNC(Task_UpdateDisplay); +// Variables to store error codes, stored and cleared in task error assert functions +error_code_t Error_ReadCarCAN = /*READCARCAN_ERR_NONE*/ 0; // TODO: change this back to the error +// error_code_t Error_ReadTritium = T_NONE; // Initialized to no error +// error_code_t Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; -DEFINE_FAKE_VOID_FUNC(Task_ReadTritium); +extern const pinInfo_t PININFO_LUT[]; // For GPIO writes. Externed from Minions Driver C file. -DEFINE_FAKE_VOID_FUNC(Task_SendCarCAN); +DEFINE_FAKE_VOID_FUNC(Task_Init, void*); -DEFINE_FAKE_VOID_FUNC(Task_DebugDump); +// DEFINE_FAKE_VOID_FUNC(Task_SendTritium, void*); -DEFINE_FAKE_VOID_FUNC(Task_CommandLine); +// DEFINE_FAKE_VOID_FUNC(Task_ReadCarCAN, void*); -DEFINE_FAKE_VOID_FUNC(TaskSwHook_Init); +// DEFINE_FAKE_VOID_FUNC(Task_UpdateDisplay, void*); -DEFINE_FAKE_VOID_FUNC(EmergencyContactorOpen); +// DEFINE_FAKE_VOID_FUNC(Task_ReadTritium, void*); -DEFINE_FAKE_VOID_FUNC(_assertOSError); +// DEFINE_FAKE_VOID_FUNC(Task_SendCarCAN, void*); + +// DEFINE_FAKE_VOID_FUNC(Task_DebugDump, void*); + +// DEFINE_FAKE_VOID_FUNC(Task_CommandLine, void*); + +// DEFINE_FAKE_VOID_FUNC(TaskSwHook_Init); + +// DEFINE_FAKE_VOID_FUNC(EmergencyContactorOpen); + +DEFINE_FAKE_VOID_FUNC(throwTaskError, error_code_t, callback_t, error_scheduler_lock_opt_t, error_recov_opt_t); + + +DEFINE_FAKE_VOID_FUNC(_assertOSError, OS_ERR); diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h b/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h index 3bbc17e8c..a27ea65e8 100644 --- a/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h +++ b/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h @@ -1,7 +1,7 @@ -#ifdef TEST_READCARCAN -#include_next "ReadCarCAN.h" // Include the next instance of the file. -// If the real version is in the include search paths after the mock one, it will include it here -#else // Mocked Contactors.h +// #ifdef TEST_READCARCAN +// #include_next "ReadCarCAN.h" // Include the next instance of the file. +// // If the real version is in the include search paths after the mock one, it will include it here +// #else // Mocked Contactors.h #ifndef MINIONS_H #define MINIONS_H #include "fff.h" @@ -38,4 +38,4 @@ DECLARE_FAKE_VOID_FUNC(Minions_Init); DECLARE_FAKE_VALUE_FUNC(bool, Minions_Read, pin_t); #endif -#endif \ No newline at end of file +// #endif \ No newline at end of file diff --git a/Tests/UnitTests/Tests/Test_ReadCarCAN.c b/Tests/UnitTests/Tests/Test_ReadCarCAN.c index 5825d72b6..e6591044b 100644 --- a/Tests/UnitTests/Tests/Test_ReadCarCAN.c +++ b/Tests/UnitTests/Tests/Test_ReadCarCAN.c @@ -15,7 +15,7 @@ DEFINE_FFF_GLOBALS; /*** CAN Messages ***/ -// static CANDATA_t bps_trip_msg = {.ID=BPS_TRIP, .idx=0, .data={1}}; +static CANDATA_t bps_trip_msg = {.ID=BPS_TRIP, .idx=0, .data={1}}; // static CANDATA_t supp_voltage_msg = {.ID=SUPPLEMENTAL_VOLTAGE, .idx=0, .data={100}}; // static CANDATA_t state_of_charge_msg = {.ID=STATE_OF_CHARGE, .idx=0, .data={0}}; // static CANDATA_t HV_Array_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b001}}; @@ -23,14 +23,25 @@ DEFINE_FFF_GLOBALS; // static CANDATA_t HV_MC_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b110}}; // static CANDATA_t HV_Enabled_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b111}}; -void setUp(void) {} +void setUp(void) { + FFF_RESET_HISTORY(); +} void tearDown(void) {} -void test_UnitTest_bsptrip(void){ - CANbus_Read_fake.return_val = SUCCESS; - // CANbus_Read_fake.arg0_val = bps_trip_msg; +ErrorStatus CANbus_Custom_fake(CANDATA_t* data, bool blocking, CAN_t bus){ + data = &bps_trip_msg; + return SUCCESS; +} +void test_UnitTest_bsptrip(void){ + Task_Init_fake(NULL); + Task_ReadCarCAN(NULL); + CANbus_Read_fake.custom_fake = CANbus_Custom_fake; + printf("%d", CANbus_Read_fake.call_count); + // + //TEST_ASSERT_EQUAL(4, throwTaskError_fake.arg0_history[0]); + // printf("%d", throwTaskError_fake.call_count); } @@ -41,4 +52,4 @@ int main(void) UNITY_BEGIN(); RUN_TEST(test_UnitTest_bsptrip); return UNITY_END(); -} \ No newline at end of file +} From 9f8b4902eadde2b53c499f96be687ef9d8f39a5a Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Wed, 10 Jan 2024 17:16:34 -0600 Subject: [PATCH 16/57] Fixed problem of gcc including the incorrect Tasks.h. Issue was that gcc searches the current directory for #include files before the -I directories, so using the real ReadCarCAN.h caused gcc to use the real Tasks.h since it resides in the same directory. Adding -iquote stops the compile from searching the current directory unless it is listed as a -I flag directory, so now fake Tasks.h will still be found first, even if we use a file in the real Apps/Inc! --- Tests/UnitTests/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index 75941b499..3526e667d 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -76,6 +76,7 @@ SF = st-flash #$(filter-out $(wildcard Mocks/*/$(TEST).h), $(wildcard Mocks/*/Inc/*.h)) *Doesn't work since we can only include directories as search paths, not actual files C_INCLUDES := \ +-iquote \ -I../../Tests/UnitTests/Mocks/Apps/Inc \ -I../../Tests/UnitTests/Mocks/Drivers/Inc \ -I../../Tests/UnitTests/Mocks/BSP/Inc \ From 54594c89b6f4ae7f116403ae4438230d09801ba9 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Wed, 10 Jan 2024 21:38:49 -0600 Subject: [PATCH 17/57] Wrote two tests for ReadCarCAN, mocked UpdateDisplay and Display, changed Makefile a bit more to use deprecated -I- for now since it seems to work better than iquote, which would cause the directory after to become unable to be found. --- Apps/Src/ReadCarCAN.c | 28 +++---- Tests/UnitTests/Makefile | 11 ++- Tests/UnitTests/Mocks/Apps/Inc/Tasks.h | 20 ++--- .../UnitTests/Mocks/Apps/Inc/UpdateDisplay.h | 70 ++++++++++++++++ Tests/UnitTests/Mocks/Apps/Src/Tasks.c | 2 +- .../UnitTests/Mocks/Apps/Src/UpdateDisplay.c | 82 +++++++++++++++++++ Tests/UnitTests/Mocks/Drivers/Inc/Display.h | 75 +++++++++++++++++ Tests/UnitTests/Mocks/Drivers/Src/Display.c | 32 ++++++++ Tests/UnitTests/Tests/Test_ReadCarCAN.c | 41 ++++++++-- 9 files changed, 323 insertions(+), 38 deletions(-) create mode 100644 Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h create mode 100644 Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c create mode 100644 Tests/UnitTests/Mocks/Drivers/Inc/Display.h create mode 100644 Tests/UnitTests/Mocks/Drivers/Src/Display.c diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index 14ddfbf7e..f55624d46 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -6,13 +6,13 @@ */ #include "ReadCarCAN.h" -//#include "UpdateDisplay.h" +#include "UpdateDisplay.h" #include "Contactors.h" #include "Minions.h" #include "os.h" #include "os_cfg_app.h" #include "Tasks.h" -//#include "Display.h" +#include "Display.h" // Length of the array and motor PBC saturation buffers #define SAT_BUF_LENGTH 5 @@ -123,7 +123,7 @@ static void disableArrayPrechargeBypassContactor(void){ // Assert error to disable regen and update saturation in callback function assertReadCarCANError(READCARCAN_ERR_CHARGE_DISABLE); // Turn off the array contactor display light - //UpdateDisplay_SetArray(false); // Can assume contactor turned off or else this won't be reached + UpdateDisplay_SetArray(false); // Can assume contactor turned off or else this won't be reached } /** @@ -225,7 +225,7 @@ static void updateHVPlusMinusSaturation(int8_t messageState){ void attemptTurnArrayPBCOn(void){ if(arrPBCComplete && chargeEnable){ Contactors_Set(ARRAY_PRECHARGE_BYPASS_CONTACTOR, ON, true); // Turn on - //UpdateDisplay_SetArray(true); + UpdateDisplay_SetArray(true); arrPBCComplete = false; } } @@ -237,7 +237,7 @@ static void updateHVPlusMinusSaturation(int8_t messageState){ void attemptTurnMotorControllerPBCOn(void){ if(mcPBCComplete){ Contactors_Set(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR, ON, true); - // UpdateDisplay_SetMotor(true); + UpdateDisplay_SetMotor(true); } } @@ -247,7 +247,7 @@ static void updateHVPlusMinusSaturation(int8_t messageState){ */ void turnMotorControllerPBCOff(void){ Contactors_Set(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR, OFF, true); - //UpdateDisplay_SetMotor(false); + UpdateDisplay_SetMotor(false); } @@ -338,8 +338,8 @@ void Task_ReadCarCAN(void *p_arg){ // would need to be reimplemented. memset(HVArrayChargeMsgBuffer, DISABLE_SATURATION_MSG, sizeof(HVArrayChargeMsgBuffer)); memset(HVPlusMinusChargeMsgBuffer, DISABLE_SATURATION_MSG, sizeof(HVPlusMinusChargeMsgBuffer)); - - while(1){ + int x = -3; + while(++x){ updatePrechargeContactors(); // Sets array and motor controller PBC if all conditions (PBC Status, Threshold, Precharge Complete) permit @@ -375,12 +375,12 @@ void Task_ReadCarCAN(void *p_arg){ case SUPPLEMENTAL_VOLTAGE: { SBPV = (*(uint16_t *) &dataBuf.data); - // UpdateDisplay_SetSBPV(SBPV); // Receive value in mV + UpdateDisplay_SetSBPV(SBPV); // Receive value in mV break; } case STATE_OF_CHARGE:{ SOC = (*(uint32_t*) &dataBuf.data)/(SOC_SCALER); // Convert to integer percent - // UpdateDisplay_SetSOC(SOC); + UpdateDisplay_SetSOC(SOC); break; } default: { @@ -408,7 +408,7 @@ static void handler_ReadCarCAN_chargeDisable(void) { bool ret = (bool)Contactors_Get(ARRAY_PRECHARGE_BYPASS_CONTACTOR); if(ret) { // Contactor failed to turn off; display the evac screen and infinite loop - // Display_Evac(SOC, SBPV); + Display_Evac(SOC, SBPV); while(1){;} } } @@ -439,7 +439,7 @@ static void handler_ReadCarCAN_contactorsDisable(void) { bool ret = (bool)Contactors_Get(ARRAY_PRECHARGE_BYPASS_CONTACTOR) || (bool)Contactors_Get(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR); if(ret) { // Contactor failed to turn off; display the evac screen and infinite loop - //Display_Evac(SOC, SBPV); + Display_Evac(SOC, SBPV); while(1){;} } } @@ -450,7 +450,7 @@ static void handler_ReadCarCAN_contactorsDisable(void) { */ static void handler_ReadCarCAN_BPSTrip(void) { chargeEnable = false; // Not really necessary but makes inspection less confusing - //Display_Evac(SOC, SBPV); // Display evacuation screen + Display_Evac(SOC, SBPV); // Display evacuation screen } @@ -460,7 +460,7 @@ static void handler_ReadCarCAN_BPSTrip(void) { * @param rcc_err error code to specify the issue encountered */ static void assertReadCarCANError(ReadCarCAN_error_code_t rcc_err){ - //Error_ReadCarCAN = (error_code_t) rcc_err; // Store error code for inspection + Error_ReadCarCAN = (error_code_t) rcc_err; // Store error code for inspection switch (rcc_err) { case READCARCAN_ERR_NONE: diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index 3526e667d..eac3ec3de 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -75,24 +75,27 @@ SF = st-flash #AS_INCLUDES = #co TEST=Pedals -> include Pedals.c and Pedals.h #$(filter-out $(wildcard Mocks/*/$(TEST).h), $(wildcard Mocks/*/Inc/*.h)) *Doesn't work since we can only include directories as search paths, not actual files +#-iquote: used to stop the compiler from searching the current directory first. Another effect: -Idirs before it are only searched for "" files +# Whatever I put after iquote doesn't seem to be found, but putting it in twice works. This will break #include-next, though C_INCLUDES := \ --iquote \ +-I- \ +-I../../Tests/Inc/ \ -I../../Tests/UnitTests/Mocks/Apps/Inc \ -I../../Tests/UnitTests/Mocks/Drivers/Inc \ -I../../Tests/UnitTests/Mocks/BSP/Inc \ -I../../Tests/UnitTests/Mocks/RTOS/ \ -I../../Apps/Inc \ -I../../Drivers/Inc \ --I../../Config/Inc \ -I../../BSP/Inc \ --I../../Tests/Inc/ \ +-I../../Config/Inc \ -I../../Tests/UnitTests \ -I../../Tests/UnitTests/Unity \ -I../../RTOS/uCOS-III-STM32F4/uCOS-III/Source/ \ -I../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/ \ -I../../RTOS/uCOS-III-STM32F4/uC-CPU/ \ -I../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/ \ --I../../RTOS/uCOS-III-STM32F4/uC-LIB/ \ +-I../../RTOS/uCOS-III-STM32F4/uC-LIB/ + $(foreach src,$(C_INCLUDES),$(info --- $(src))) diff --git a/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h b/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h index 99fb2fccf..eb3b3c28e 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h @@ -52,21 +52,21 @@ typedef uint16_t error_code_t; /** * Task Prototypes */ -void Task_Init(void* p_arg); +//void Task_Init(void* p_arg); -void Task_SendTritium(void* p_arg); +//void Task_SendTritium(void* p_arg); void Task_ReadCarCAN(void* p_arg); -void Task_UpdateDisplay(void* p_arg); +//void Task_UpdateDisplay(void* p_arg); -void Task_ReadTritium(void* p_arg); +//void Task_ReadTritium(void* p_arg); -void Task_SendCarCAN(void* p_arg); +//void Task_SendCarCAN(void* p_arg); -void Task_DebugDump(void *p_arg); +//void Task_DebugDump(void *p_arg); -void Task_CommandLine(void* p_arg); +//void Task_CommandLine(void* p_arg); @@ -146,11 +146,11 @@ typedef enum { // DECLARE_FAKE_VOID_FUNC(MOCK_TEST); -DECLARE_FAKE_VOID_FUNC(Task_Init, void*); +DECLARE_FAKE_VOID_FUNC(Task_Init, void *); // DECLARE_FAKE_VOID_FUNC(Task_SendTritium, void*); -DECLARE_FAKE_VOID_FUNC(Task_ReadCarCAN, void*); +// DECLARE_FAKE_VOID_FUNC(Task_ReadCarCAN, void*); // DECLARE_FAKE_VOID_FUNC(Task_UpdateDisplay, void*); @@ -169,6 +169,6 @@ DECLARE_FAKE_VOID_FUNC(Task_ReadCarCAN, void*); DECLARE_FAKE_VOID_FUNC(throwTaskError, error_code_t, callback_t, error_scheduler_lock_opt_t, error_recov_opt_t); -DECLARE_FAKE_VOID_FUNC(_assertOSError, OS_ERR); +//DECLARE_FAKE_VOID_FUNC(_assertOSError, OS_ERR); #endif // #endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h b/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h new file mode 100644 index 000000000..a8ce420b3 --- /dev/null +++ b/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h @@ -0,0 +1,70 @@ +//////////////////////////// MOCK +#ifdef TEST_UPDATEDISPLAY +#include_next "UpdateDisplay.h" +#else +#ifndef __UPDATE_DISPLAY_H +#define __UPDATE_DISPLAY_H + +//#include "os.h" +#include "common.h" +//#include "Tasks.h" + +#include "Display.h" +//#include "Contactors.h" +#include "fff.h" + +/** + * Error types + */ +typedef enum{ + UPDATEDISPLAY_ERR_NONE, + UPDATEDISPLAY_ERR_FIFO_PUT, // Error putting command in fifo + UPDATEDISPLAY_ERR_FIFO_POP, // Error popping command from fifo + UPDATEDISPLAY_ERR_PARSE_COMP, // Error parsing component/val in SetComponent + UPDATEDISPLAY_ERR_DRIVER // Driver call returned an error +} UpdateDisplayError_t; + +/** + * For display elements with three states + */ +typedef enum{ + STATE_0 =0, + STATE_1 =1, + STATE_2 =2 +} TriState_t; + +// For cruise control and regen +#define DISP_DISABLED STATE_0 +#define DISP_ENABLED STATE_1 // Able to be used +#define DISP_ACTIVE STATE_2 // Actively being used right now + +// For gear changes +#define DISP_NEUTRAL STATE_0 +#define DISP_FORWARD STATE_1 +#define DISP_REVERSE STATE_2 + +DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_Init); + +DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetPage, Page_t); + +DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetSOC, uint8_t); + +DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetSBPV, uint32_t); + +DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetVelocity, uint32_t); + +DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetAccel, uint8_t); + +DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetArray, bool); + +DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetMotor, bool); + +DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetGear, TriState_t); + +DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetRegenState, TriState_t); + +DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetCruiseState, TriState_t); + +DECLARE_FAKE_VOID_FUNC(UpdateDisplay_ClearQueue); +#endif +#endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Src/Tasks.c b/Tests/UnitTests/Mocks/Apps/Src/Tasks.c index 2a506b63c..e3be836b2 100644 --- a/Tests/UnitTests/Mocks/Apps/Src/Tasks.c +++ b/Tests/UnitTests/Mocks/Apps/Src/Tasks.c @@ -58,4 +58,4 @@ DEFINE_FAKE_VOID_FUNC(Task_Init, void*); DEFINE_FAKE_VOID_FUNC(throwTaskError, error_code_t, callback_t, error_scheduler_lock_opt_t, error_recov_opt_t); -DEFINE_FAKE_VOID_FUNC(_assertOSError, OS_ERR); +//DEFINE_FAKE_VOID_FUNC(_assertOSError, OS_ERR); diff --git a/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c b/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c new file mode 100644 index 000000000..023d2af6a --- /dev/null +++ b/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c @@ -0,0 +1,82 @@ +#include "UpdateDisplay.h" +#include "Minions.h" +#include +#include "fff.h" + +/** + * Creates queue for display commands. + */ +#define DISP_Q_SIZE 10 + +#define FIFO_TYPE DisplayCmd_t +#define FIFO_SIZE DISP_Q_SIZE +#define FIFO_NAME disp_fifo +#include "fifo.h" + +// For fault handling +#define RESTART_THRESHOLD 3 // number of times to reset before displaying the fault screen + +disp_fifo_t msg_queue; + + +/** + * Enum and corresponding array for easy component selection. + */ +typedef enum{ + // Boolean components + ARRAY=0, + MOTOR, + // Non-boolean components + VELOCITY, + ACCEL_METER, + SOC, + SUPP_BATT, + CRUISE_ST, + REGEN_ST, + GEAR, + // Fault code components + OS_CODE, + FAULT_CODE +} Component_t; + +const char* compStrings[15]= { + // Boolean components + "arr", + "mot", + // Non-boolean components + "vel", + "accel", + "soc", + "supp", + "cruiseSt", + "rbsSt", + "gear", + // Fault code components + "oserr", + "faulterr" +}; + +DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_Init); + +DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetPage, Page_t); + +DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetSOC, uint8_t); + +DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetSBPV, uint32_t); + +DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetVelocity, uint32_t); + +DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetAccel, uint8_t); + +DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetArray, bool); + +DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetMotor, bool); + +DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetGear, TriState_t); + +DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetRegenState, TriState_t); + +DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetCruiseState, TriState_t); + +DEFINE_FAKE_VOID_FUNC(UpdateDisplay_ClearQueue); + diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/Display.h b/Tests/UnitTests/Mocks/Drivers/Inc/Display.h new file mode 100644 index 000000000..3bd112235 --- /dev/null +++ b/Tests/UnitTests/Mocks/Drivers/Inc/Display.h @@ -0,0 +1,75 @@ +#ifdef TEST_DISPLAY +#include_next "Display.h" +#else +#ifndef __DISPLAY_H +#define __DISPLAY_H + +#include "common.h" // common headers +#include "Tasks.h" +#include "fff.h" + +#define MAX_ARGS 2 // maximum # of arguments in a command packet + +/** + * Error types + */ +typedef enum{ // Currently only ERR_NONE and ERR_PARSE are used + DISPLAY_ERR_NONE, + DISPLAY_ERR_PARSE, // Error parsing command struct passed to Display_Send + DISPLAY_ERR_INV_INSTR, // Invalid instruction passed to nextion (0x00) + DISPLAY_ERR_INV_COMP, // Invalid component id passed to nextion (0x02) + DISPLAY_ERR_INV_PGID, // Invalid page id passed to nextion (0x03) + DISPLAY_ERR_INV_VAR, // Invalid variable name passed to nextion (0x1A) + DISPLAY_ERR_INV_VAROP, // Invalid variable operation passed to nextion (0x1B) + DISPLAY_ERR_ASSIGN, // Assignment failure nextion (0x1C) + DISPLAY_ERR_PARAMS, // Invalid number of parameters passed to nextion (0x1E) + DISPLAY_ERR_MAX_ARGS, // Command arg list exceeded MAX_ARGS elements + DISPLAY_ERR_OTHER // Other nextion display error +} DisplayError_t; + + +/** + * All three pages on the HMI + */ +typedef enum{ + STARTUP =0, + INFO, + FAULT +} Page_t; + +/** + * Argument types + */ +typedef enum{ + STR_ARG, + INT_ARG +} Arg_e; + +/** + * Packages relevant display command data + */ +typedef struct{ + char* compOrCmd; + char* attr; + char* op; + uint8_t numArgs; + Arg_e argTypes[MAX_ARGS]; // TRUE for integers, FALSE for strings + union{ + char* str; + uint32_t num; + } args[MAX_ARGS]; +} DisplayCmd_t; + + +DECLARE_FAKE_VALUE_FUNC(DisplayError_t, Display_Send, DisplayCmd_t); + +DECLARE_FAKE_VALUE_FUNC(DisplayError_t, Display_Init); + +DECLARE_FAKE_VALUE_FUNC(DisplayError_t, Display_Reset); + +DECLARE_FAKE_VALUE_FUNC(DisplayError_t, Display_Error, error_code_t); + +DECLARE_FAKE_VALUE_FUNC(DisplayError_t, Display_Evac, uint8_t, uint32_t); + +#endif +#endif diff --git a/Tests/UnitTests/Mocks/Drivers/Src/Display.c b/Tests/UnitTests/Mocks/Drivers/Src/Display.c new file mode 100644 index 000000000..741d419f0 --- /dev/null +++ b/Tests/UnitTests/Mocks/Drivers/Src/Display.c @@ -0,0 +1,32 @@ +/** + * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar + * @file Display.c + * @brief Function implementations for the display driver. + * + * This contains functions relevant to sending/receiving messages + * to/from our Nextion display. + * + */ + +#include "Display.h" +#include "bsp.h" // for writing to UART +#include "Tasks.h" // for os and fault error codes +#include "fff.h" + +#define DISP_OUT UART_3 +#define MAX_MSG_LEN 32 +#define MAX_ARG_LEN 16 +// Assignment commands have only 1 arg, an operator, and an attribute +#define isAssignCmd(cmd) (cmd.compOrCmd != NULL && cmd.op != NULL && cmd.attr != NULL && cmd.numArgs == 1) +// Operational commands have no attribute and no operator, just a command and >= 0 arguments +#define isOpCmd(cmd) (cmd.op == NULL && cmd.attr == NULL) + +DEFINE_FAKE_VALUE_FUNC(DisplayError_t, Display_Send, DisplayCmd_t); + +DEFINE_FAKE_VALUE_FUNC(DisplayError_t, Display_Init); + +DEFINE_FAKE_VALUE_FUNC(DisplayError_t, Display_Reset); + +DEFINE_FAKE_VALUE_FUNC(DisplayError_t, Display_Error, error_code_t); + +DEFINE_FAKE_VALUE_FUNC(DisplayError_t, Display_Evac, uint8_t, uint32_t); \ No newline at end of file diff --git a/Tests/UnitTests/Tests/Test_ReadCarCAN.c b/Tests/UnitTests/Tests/Test_ReadCarCAN.c index e6591044b..688d6a08e 100644 --- a/Tests/UnitTests/Tests/Test_ReadCarCAN.c +++ b/Tests/UnitTests/Tests/Test_ReadCarCAN.c @@ -10,16 +10,19 @@ // fff header so we can DEFINE_FFF_GLOBALS // (can only happen once per test) #include "fff.h" +///////////////////// +// Mock headers +#include "UpdateDisplay.h" DEFINE_FFF_GLOBALS; /*** CAN Messages ***/ static CANDATA_t bps_trip_msg = {.ID=BPS_TRIP, .idx=0, .data={1}}; -// static CANDATA_t supp_voltage_msg = {.ID=SUPPLEMENTAL_VOLTAGE, .idx=0, .data={100}}; +//static CANDATA_t supp_voltage_msg = {.ID=SUPPLEMENTAL_VOLTAGE, .idx=0, .data={100}}; // static CANDATA_t state_of_charge_msg = {.ID=STATE_OF_CHARGE, .idx=0, .data={0}}; // static CANDATA_t HV_Array_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b001}}; -// static CANDATA_t HV_Disable_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b000}}; +static CANDATA_t HV_Disable_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b000}}; // static CANDATA_t HV_MC_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b110}}; // static CANDATA_t HV_Enabled_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b111}}; @@ -29,27 +32,47 @@ void setUp(void) { void tearDown(void) {} -ErrorStatus CANbus_Custom_fake(CANDATA_t* data, bool blocking, CAN_t bus){ - data = &bps_trip_msg; +ErrorStatus CANbus_Custom_fake_bps(CANDATA_t* data, bool blocking, CAN_t bus){ + *data = bps_trip_msg; + return SUCCESS; +} + +ErrorStatus CANbus_Custom_fake_bpscontactor(CANDATA_t* data, bool blocking, CAN_t bus){ + *data = HV_Disable_Msg; return SUCCESS; } void test_UnitTest_bsptrip(void){ - Task_Init_fake(NULL); + Task_Init(NULL); + CANbus_Read_fake.custom_fake = CANbus_Custom_fake_bps; Task_ReadCarCAN(NULL); - CANbus_Read_fake.custom_fake = CANbus_Custom_fake; - printf("%d", CANbus_Read_fake.call_count); + printf("\n\r%d\n\r", CANbus_Read_fake.call_count); // - //TEST_ASSERT_EQUAL(4, throwTaskError_fake.arg0_history[0]); - // printf("%d", throwTaskError_fake.call_count); + TEST_ASSERT_EQUAL(3, throwTaskError_fake.arg0_history[0]); + TEST_ASSERT_EQUAL(4, throwTaskError_fake.arg0_history[1]); + printf("%d", throwTaskError_fake.call_count); + TEST_ASSERT_EQUAL(false, UpdateDisplay_SetArray_fake.arg0_history[0]); + TEST_ASSERT_EQUAL(2, Display_Evac_fake.call_count) } +void test_UnitTest_bspcontactor(void){ + Task_Init(NULL); + CANbus_Read_fake.custom_fake = CANbus_Custom_fake_bpscontactor; + Task_ReadCarCAN(NULL); + printf("\n\r%d\n\r", CANbus_Read_fake.call_count); + // + TEST_ASSERT_EQUAL(3, throwTaskError_fake.arg0_history[0]); + //TEST_ASSERT_EQUAL(4, throwTaskError_fake.arg0_history[1]); + printf("%d", throwTaskError_fake.call_count); + TEST_ASSERT_EQUAL(false, UpdateDisplay_SetArray_fake.arg0_history[0]); +} /*=======MAIN=====*/ int main(void) { UNITY_BEGIN(); + RUN_TEST(test_UnitTest_bspcontactor); RUN_TEST(test_UnitTest_bsptrip); return UNITY_END(); } From 8e459320de038df9d6ef122371bc751960427319 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Mon, 15 Jan 2024 02:06:29 -0600 Subject: [PATCH 18/57] Mocked the rest of the relevant os functions; currently doesn't expand correctly and doesn't compile. --- Tests/UnitTests/Mocks/RTOS/os.c | 162 +++++++++++++++++++++++++++++++- Tests/UnitTests/Mocks/RTOS/os.h | 156 ++++++++++++++++++++++++++++++ 2 files changed, 316 insertions(+), 2 deletions(-) diff --git a/Tests/UnitTests/Mocks/RTOS/os.c b/Tests/UnitTests/Mocks/RTOS/os.c index 2b63f2c0d..18416dd20 100644 --- a/Tests/UnitTests/Mocks/RTOS/os.c +++ b/Tests/UnitTests/Mocks/RTOS/os.c @@ -2,14 +2,64 @@ #include "os.h" +/****** Event Flags *******/ + +DEFINE_FAKE_VOID_FUNC(OSFlagCreate, OS_FLAG_GRP*, CPU_CHAR*, OS_FLAGS, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSFlagDel, OS_FLAG_GRP*, OS_OPT, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(OS_FLAGS, OSFlagPend, OS_FLAG_GRP*, OS_FLAGS, OS_TICK, OS_OPT, CPU_TS*, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSFlagPendAbort, OS_FLAG_GRP*, OS_OPT, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(OS_FLAGS, OSFlagPendGetFlagsRdy, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(OS_FLAGS, OSFlagPost, OS_FLAG_GRP*, OS_FLAGS, OS_OPT, OS_ERR*); + +/****** FIXED SIZE MEMORY BLOCK MANAGEMENT ******/ + +DEFINE_FAKE_VOID_FUNC(OSMemCreate, OS_MEM*, CPU_CHAR*, void*, OS_MEM_QTY, OS_MEM_SIZE, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(void*, OSMemGet, OS_MEM*, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSMemPut, OS_MEM*, void*, OS_ERR*); + +/****** MUTUAL EXCLUSION SEMAPHORES ******/ + DEFINE_FAKE_VOID_FUNC(OSMutexCreate, OS_MUTEX*, char* , OS_ERR*); +DEFINE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSMutexDel, OS_MUTEX*, OS_OPT, OS_ERR*); + DEFINE_FAKE_VOID_FUNC(OSMutexPend, OS_MUTEX*, OS_TICK, OS_OPT, CPU_TS*, OS_ERR*); +DEFINE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSMutexPendAbort, OS_MUTEX*, OS_OPT, OS_ERR*); + DEFINE_FAKE_VOID_FUNC(OSMutexPost, OS_MUTEX*, OS_OPT, OS_ERR*); +/****** MULTI PEND ******/ + +DEFINE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSPendMulti, OS_PEND_DATA*, OS_OBJ_QTY, OS_TICK, OS_OPT, OS_ERR*); + +/****** MESSAGE QUEUES ******/ + +DEFINE_FAKE_VOID_FUNC(OSQCreate, OS_Q*, CPU_CHAR*, OS_MSG_QTY, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSQDel, OS_Q*, OS_OPT, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(OS_MSG_QTY, OSQFlush, OS_Q*, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(void*, OSQPend, OS_Q*, OS_TICK, OS_OPT, OS_MSG_SIZE*, CPU_TS*, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSQPendAbort, OS_Q*, OS_OPT, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSQPost, OS_Q*, void*, OS_MSG_SIZE, OS_OPT, OS_ERR*); + +/****** SEMAPHORES ******/ + DEFINE_FAKE_VOID_FUNC(OSSemCreate, OS_SEM*, CPU_CHAR*, OS_SEM_CTR, OS_ERR*); +DEFINE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSSemDel, OS_SEM*, OS_OPT, OS_ERR*); + DEFINE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSSemPend, OS_SEM*, OS_TICK, OS_OPT, CPU_TS*, OS_ERR*); DEFINE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSSemPendAbort, OS_SEM*, OS_OPT, OS_ERR*); @@ -18,12 +68,120 @@ DEFINE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSSemPost, OS_SEM*, OS_OPT, OS_ERR*); DEFINE_FAKE_VOID_FUNC(OSSemSet, OS_SEM*, OS_SEM_CTR, OS_ERR*); -DEFINE_FAKE_VOID_FUNC(OSTaskCreate, OS_TCB*, CPU_CHAR*, OS_TASK_PTR, void*, OS_PRIO, CPU_STK*, CPU_STK_SIZE, CPU_STK_SIZE, OS_MSG_QTY, OS_TICK, void*, OS_OPT, OS_ERR*); +/****** TASK MANAGEMENT ******/ + +DECLARE_FAKE_VOID_FUNC(OSTaskChangePrio, OS_TCB*, OS_PRIO, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskCreate, OS_TCB*, CPU_CHAR*, OS_TASK_PTR, void*, OS_PRIO, CPU_STK*, CPU_STK_SIZE, CPU_STK_SIZE, OS_MSG_QTY, OS_TICK, void*, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskDel, OS_TCB*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_MSG_QTY, OSTaskQFlush, OS_TCB*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(void*, OSTaskQPend, OS_TICK, OS_OPT, OS_MSG_SIZE*, CPU_TS*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(CPU_BOOLEAN, OSTaskQPendAbort, OS_TCB*, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskQPost, OS_TCB*, void*, OS_MSG_SIZE, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_REG, OSTaskRegGet, OS_TCB*, OS_REG_ID, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_REG_ID, OSTaskRegGetID, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskRegSet, OS_TCB*, OS_REG_ID, OS_REG, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskResume, OS_TCB*, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskSuspend, OS_TCB*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSTaskSemPend, OS_TICK, OS_OPT, CPU_TS*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(CPU_BOOLEAN, OSTaskSemPendAbort, OS_TCB*, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSTaskSemPost, OS_TCB*, OS_OPT, OS_ERR*); -DEFINE_FAKE_VOID_FUNC(OSTaskDel, OS_TCB*, OS_ERR*); +DECLARE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSTaskSemSet, OS_TCB*, OS_SEM_CTR, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskStkChk, OS_TCB*, CPU_STK_SIZE*, CPU_STK_SIZE*, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskTimeQuantaSet, OS_TCB*, OS_TICK, OS_ERR*); + +/****** TASK LOCAL STORAGE (TLS) SUPPORT *******/ + +// Not currently used + +/****** TIME MANAGEMENT ******/ DEFINE_FAKE_VOID_FUNC(OSTimeDly, OS_TICK, OS_OPT, OS_ERR*); DEFINE_FAKE_VOID_FUNC(OSTimeDlyHMSM, CPU_INT16U, CPU_INT16U, CPU_INT16U, CPU_INT32U, OS_OPT, OS_ERR*); +DEFINE_FAKE_VOID_FUNC(OSTimeDlyResume, OS_TCB*, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(OS_TICK, OSTimeGet, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSTimeSet, OS_TICK, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSTimeTick); + +/****** TIMER MANAGEMENT ******/ + DEFINE_FAKE_VOID_FUNC(OSTmrCreate, OS_TMR*, CPU_CHAR*, OS_TICK, OS_TICK, OS_OPT, OS_TMR_CALLBACK_PTR, void*, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(CPU_BOOLEAN, OSTmrDel, OS_TMR*, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(OS_TICK, OSTmrRemainGet, OS_TMR*, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(CPU_BOOLEAN, OSTmrStart, OS_TMR*, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(OS_STATE, OSTmrStateGet, OS_TMR*, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(CPU_BOOLEAN, OSTmrStop, OS_TMR*, OS_OPT, void*, OS_ERR*); + +/****** MISCELLANEOUS ******/ + +DEFINE_FAKE_VOID_FUNC(OSInit, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSIntEnter); + +DEFINE_FAKE_VOID_FUNC(OSIntExit); + +DEFINE_FAKE_VOID_FUNC(OSSafetyCriticalStart); + +DEFINE_FAKE_VOID_FUNC(OSSchedRoundRobinCfg, CPU_BOOLEAN, OS_TICK, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSSchedRoundRobinYield, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSSched); + +DEFINE_FAKE_VOID_FUNC(OSSchedLock, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSSchedUnlock, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSStart, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSStatReset, OS_ERR*); + +DEFINE_FAKE_VOID_FUNC(OSStatTaskCPUUsageInit, OS_ERR*); + +DEFINE_FAKE_VALUE_FUNC(CPU_INT16U, OSVersion, OS_ERR*); + +/****** T A R G E T S P E C I F I C F U N C T I O N S ******/ + +DEFINE_FAKE_VOID_FUNC(OSInitHook); + +DEFINE_FAKE_VOID_FUNC(OSTaskCreateHook, OS_TCB*); + +DEFINE_FAKE_VOID_FUNC(OSTaskDelHook, OS_TCB*); + +DEFINE_FAKE_VOID_FUNC(OSIdleTaskHook); + +DEFINE_FAKE_VOID_FUNC(OSTaskReturnHook, OS_TCB*); + +DEFINE_FAKE_VOID_FUNC(OSStatTaskHook); + +DEFINE_FAKE_VALUE_FUNC(CPU_STK*, OSTaskStkInit, OS_TASK_PTR, void*, CPU_STK*, CPU_STK*, CPU_STK_SIZE, OS_OPT); + +DEFINE_FAKE_VOID_FUNC(OSTaskSwHook); + +DEFINE_FAKE_VOID_FUNC(OSTimeTickHook); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/RTOS/os.h b/Tests/UnitTests/Mocks/RTOS/os.h index 523dbb438..4f32d63eb 100644 --- a/Tests/UnitTests/Mocks/RTOS/os.h +++ b/Tests/UnitTests/Mocks/RTOS/os.h @@ -1368,16 +1368,64 @@ extern CPU_STK OSCfg_TickTaskStk[]; extern CPU_STK OSCfg_TmrTaskStk[]; #endif +/****** EVENT FLAGS *******/ +DECLARE_FAKE_VOID_FUNC(OSFlagCreate, OS_FLAG_GRP*, CPU_CHAR*, OS_FLAGS, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSFlagDel, OS_FLAG_GRP*, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_FLAGS, OSFlagPend, OS_FLAG_GRP*, OS_FLAGS, OS_TICK, OS_OPT, CPU_TS*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSFlagPendAbort, OS_FLAG_GRP*, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_FLAGS, OSFlagPendGetFlagsRdy, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_FLAGS, OSFlagPost, OS_FLAG_GRP*, OS_FLAGS, OS_OPT, OS_ERR*); + +/****** FIXED SIZE MEMORY BLOCK MANAGEMENT ******/ + +DECLARE_FAKE_VOID_FUNC(OSMemCreate, OS_MEM*, CPU_CHAR*, void*, OS_MEM_QTY, OS_MEM_SIZE, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(void*, OSMemGet, OS_MEM*, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSMemPut, OS_MEM*, void*, OS_ERR*); + +/****** MUTUAL EXCLUSION SEMAPHORES ******/ DECLARE_FAKE_VOID_FUNC(OSMutexCreate, OS_MUTEX*, char* , OS_ERR*); +DECLARE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSMutexDel, OS_MUTEX*, OS_OPT, OS_ERR*); + DECLARE_FAKE_VOID_FUNC(OSMutexPend, OS_MUTEX*, OS_TICK, OS_OPT, CPU_TS*, OS_ERR*); +DECLARE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSMutexPendAbort, OS_MUTEX*, OS_OPT, OS_ERR*); + DECLARE_FAKE_VOID_FUNC(OSMutexPost, OS_MUTEX*, OS_OPT, OS_ERR*); +/****** MULTI PEND ******/ + +DECLARE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSPendMulti, OS_PEND_DATA*, OS_OBJ_QTY, OS_TICK, OS_OPT, OS_ERR*); + +/****** MESSAGE QUEUES ******/ + +DECLARE_FAKE_VOID_FUNC(OSQCreate, OS_Q*, CPU_CHAR*, OS_MSG_QTY, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSQDel, OS_Q*, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_MSG_QTY, OSQFlush, OS_Q*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(void*, OSQPend, OS_Q*, OS_TICK, OS_OPT, OS_MSG_SIZE*, CPU_TS*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSQPendAbort, OS_Q*, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSQPost, OS_Q*, void*, OS_MSG_SIZE, OS_OPT, OS_ERR*); + +/****** SEMAPHORES ******/ + DECLARE_FAKE_VOID_FUNC(OSSemCreate, OS_SEM*, CPU_CHAR*, OS_SEM_CTR, OS_ERR*); +DECLARE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSSemDel, OS_SEM*, OS_OPT, OS_ERR*); + DECLARE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSSemPend, OS_SEM*, OS_TICK, OS_OPT, CPU_TS*, OS_ERR*); DECLARE_FAKE_VALUE_FUNC(OS_OBJ_QTY, OSSemPendAbort, OS_SEM*, OS_OPT, OS_ERR*); @@ -1386,15 +1434,123 @@ DECLARE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSSemPost, OS_SEM*, OS_OPT, OS_ERR*); DECLARE_FAKE_VOID_FUNC(OSSemSet, OS_SEM*, OS_SEM_CTR, OS_ERR*); +/****** TASK MANAGEMENT ******/ + +DECLARE_FAKE_VOID_FUNC(OSTaskChangePrio, OS_TCB*, OS_PRIO, OS_ERR*); + DECLARE_FAKE_VOID_FUNC(OSTaskCreate, OS_TCB*, CPU_CHAR*, OS_TASK_PTR, void*, OS_PRIO, CPU_STK*, CPU_STK_SIZE, CPU_STK_SIZE, OS_MSG_QTY, OS_TICK, void*, OS_OPT, OS_ERR*); DECLARE_FAKE_VOID_FUNC(OSTaskDel, OS_TCB*, OS_ERR*); +DECLARE_FAKE_VALUE_FUNC(OS_MSG_QTY, OSTaskQFlush, OS_TCB*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(void*, OSTaskQPend, OS_TICK, OS_OPT, OS_MSG_SIZE*, CPU_TS*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(CPU_BOOLEAN, OSTaskQPendAbort, OS_TCB*, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskQPost, OS_TCB*, void*, OS_MSG_SIZE, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_REG, OSTaskRegGet, OS_TCB*, OS_REG_ID, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_REG_ID, OSTaskRegGetID, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskRegSet, OS_TCB*, OS_REG_ID, OS_REG, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskResume, OS_TCB*, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskSuspend, OS_TCB*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSTaskSemPend, OS_TICK, OS_OPT, CPU_TS*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(CPU_BOOLEAN, OSTaskSemPendAbort, OS_TCB*, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSTaskSemPost, OS_TCB*, OS_OPT, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSTaskSemSet, OS_TCB*, OS_SEM_CTR, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskStkChk, OS_TCB*, CPU_STK_SIZE*, CPU_STK_SIZE*, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTaskTimeQuantaSet, OS_TCB*, OS_TICK, OS_ERR*); + +/****** TASK LOCAL STORAGE (TLS) SUPPORT *******/ + +// Not currently used + +/****** TIME MANAGEMENT ******/ + DECLARE_FAKE_VOID_FUNC(OSTimeDly, OS_TICK, OS_OPT, OS_ERR*); DECLARE_FAKE_VOID_FUNC(OSTimeDlyHMSM, CPU_INT16U, CPU_INT16U, CPU_INT16U, CPU_INT32U, OS_OPT, OS_ERR*); +DECLARE_FAKE_VOID_FUNC(OSTimeDlyResume, OS_TCB*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_TICK, OSTimeGet, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTimeSet, OS_TICK, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSTimeTick); + +/****** TIMER MANAGEMENT ******/ + DECLARE_FAKE_VOID_FUNC(OSTmrCreate, OS_TMR*, CPU_CHAR*, OS_TICK, OS_TICK, OS_OPT, OS_TMR_CALLBACK_PTR, void*, OS_ERR*); +DECLARE_FAKE_VALUE_FUNC(CPU_BOOLEAN, OSTmrDel, OS_TMR*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_TICK, OSTmrRemainGet, OS_TMR*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(CPU_BOOLEAN, OSTmrStart, OS_TMR*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(OS_STATE, OSTmrStateGet, OS_TMR*, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(CPU_BOOLEAN, OSTmrStop, OS_TMR*, OS_OPT, void*, OS_ERR*); + +/****** MISCELLANEOUS ******/ + +DECLARE_FAKE_VOID_FUNC(OSInit, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSIntEnter); + +DECLARE_FAKE_VOID_FUNC(OSIntExit); + +DECLARE_FAKE_VOID_FUNC(OSSafetyCriticalStart); + +DECLARE_FAKE_VOID_FUNC(OSSchedRoundRobinCfg, CPU_BOOLEAN, OS_TICK, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSSchedRoundRobinYield, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSSched); + +DECLARE_FAKE_VOID_FUNC(OSSchedLock, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSSchedUnlock, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSStart, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSStatReset, OS_ERR*); + +DECLARE_FAKE_VOID_FUNC(OSStatTaskCPUUsageInit, OS_ERR*); + +DECLARE_FAKE_VALUE_FUNC(CPU_INT16U, OSVersion, OS_ERR*); + +/****** T A R G E T S P E C I F I C F U N C T I O N S ******/ + +DECLARE_FAKE_VOID_FUNC(OSInitHook); + +DECLARE_FAKE_VOID_FUNC(OSTaskCreateHook, OS_TCB*); + +DECLARE_FAKE_VOID_FUNC(OSTaskDelHook, OS_TCB*); + +DECLARE_FAKE_VOID_FUNC(OSIdleTaskHook); + +DECLARE_FAKE_VOID_FUNC(OSTaskReturnHook, OS_TCB*); + +DECLARE_FAKE_VOID_FUNC(OSStatTaskHook); + +DECLARE_FAKE_VALUE_FUNC(CPU_STK*, OSTaskStkInit, OS_TASK_PTR, void*, CPU_STK*, CPU_STK*, CPU_STK_SIZE, OS_OPT); + +DECLARE_FAKE_VOID_FUNC(OSTaskSwHook); + +DECLARE_FAKE_VOID_FUNC(OSTimeTickHook); + #endif // #endif \ No newline at end of file From 7efeb409cc57ec898690e2d3696dc3bfd9f4e4d2 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 16 Jan 2024 11:05:59 -0600 Subject: [PATCH 19/57] Fixed mocked os (wrote DECLARE instead of DEFINE), added semicolon to Test_ReadCarCAN. --- Tests/UnitTests/Mocks/RTOS/os.c | 36 ++++++++++++------------- Tests/UnitTests/Tests/Test_ReadCarCAN.c | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Tests/UnitTests/Mocks/RTOS/os.c b/Tests/UnitTests/Mocks/RTOS/os.c index 18416dd20..4d5f11c2b 100644 --- a/Tests/UnitTests/Mocks/RTOS/os.c +++ b/Tests/UnitTests/Mocks/RTOS/os.c @@ -70,41 +70,41 @@ DEFINE_FAKE_VOID_FUNC(OSSemSet, OS_SEM*, OS_SEM_CTR, OS_ERR*); /****** TASK MANAGEMENT ******/ -DECLARE_FAKE_VOID_FUNC(OSTaskChangePrio, OS_TCB*, OS_PRIO, OS_ERR*); +DEFINE_FAKE_VOID_FUNC(OSTaskChangePrio, OS_TCB*, OS_PRIO, OS_ERR*); -DECLARE_FAKE_VOID_FUNC(OSTaskCreate, OS_TCB*, CPU_CHAR*, OS_TASK_PTR, void*, OS_PRIO, CPU_STK*, CPU_STK_SIZE, CPU_STK_SIZE, OS_MSG_QTY, OS_TICK, void*, OS_OPT, OS_ERR*); +DEFINE_FAKE_VOID_FUNC(OSTaskCreate, OS_TCB*, CPU_CHAR*, OS_TASK_PTR, void*, OS_PRIO, CPU_STK*, CPU_STK_SIZE, CPU_STK_SIZE, OS_MSG_QTY, OS_TICK, void*, OS_OPT, OS_ERR*); -DECLARE_FAKE_VOID_FUNC(OSTaskDel, OS_TCB*, OS_ERR*); +DEFINE_FAKE_VOID_FUNC(OSTaskDel, OS_TCB*, OS_ERR*); -DECLARE_FAKE_VALUE_FUNC(OS_MSG_QTY, OSTaskQFlush, OS_TCB*, OS_ERR*); +DEFINE_FAKE_VALUE_FUNC(OS_MSG_QTY, OSTaskQFlush, OS_TCB*, OS_ERR*); -DECLARE_FAKE_VALUE_FUNC(void*, OSTaskQPend, OS_TICK, OS_OPT, OS_MSG_SIZE*, CPU_TS*, OS_ERR*); +DEFINE_FAKE_VALUE_FUNC(void*, OSTaskQPend, OS_TICK, OS_OPT, OS_MSG_SIZE*, CPU_TS*, OS_ERR*); -DECLARE_FAKE_VALUE_FUNC(CPU_BOOLEAN, OSTaskQPendAbort, OS_TCB*, OS_OPT, OS_ERR*); +DEFINE_FAKE_VALUE_FUNC(CPU_BOOLEAN, OSTaskQPendAbort, OS_TCB*, OS_OPT, OS_ERR*); -DECLARE_FAKE_VOID_FUNC(OSTaskQPost, OS_TCB*, void*, OS_MSG_SIZE, OS_OPT, OS_ERR*); +DEFINE_FAKE_VOID_FUNC(OSTaskQPost, OS_TCB*, void*, OS_MSG_SIZE, OS_OPT, OS_ERR*); -DECLARE_FAKE_VALUE_FUNC(OS_REG, OSTaskRegGet, OS_TCB*, OS_REG_ID, OS_ERR*); +DEFINE_FAKE_VALUE_FUNC(OS_REG, OSTaskRegGet, OS_TCB*, OS_REG_ID, OS_ERR*); -DECLARE_FAKE_VALUE_FUNC(OS_REG_ID, OSTaskRegGetID, OS_ERR*); +DEFINE_FAKE_VALUE_FUNC(OS_REG_ID, OSTaskRegGetID, OS_ERR*); -DECLARE_FAKE_VOID_FUNC(OSTaskRegSet, OS_TCB*, OS_REG_ID, OS_REG, OS_ERR*); +DEFINE_FAKE_VOID_FUNC(OSTaskRegSet, OS_TCB*, OS_REG_ID, OS_REG, OS_ERR*); -DECLARE_FAKE_VOID_FUNC(OSTaskResume, OS_TCB*, OS_ERR*); +DEFINE_FAKE_VOID_FUNC(OSTaskResume, OS_TCB*, OS_ERR*); -DECLARE_FAKE_VOID_FUNC(OSTaskSuspend, OS_TCB*, OS_ERR*); +DEFINE_FAKE_VOID_FUNC(OSTaskSuspend, OS_TCB*, OS_ERR*); -DECLARE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSTaskSemPend, OS_TICK, OS_OPT, CPU_TS*, OS_ERR*); +DEFINE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSTaskSemPend, OS_TICK, OS_OPT, CPU_TS*, OS_ERR*); -DECLARE_FAKE_VALUE_FUNC(CPU_BOOLEAN, OSTaskSemPendAbort, OS_TCB*, OS_OPT, OS_ERR*); +DEFINE_FAKE_VALUE_FUNC(CPU_BOOLEAN, OSTaskSemPendAbort, OS_TCB*, OS_OPT, OS_ERR*); -DECLARE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSTaskSemPost, OS_TCB*, OS_OPT, OS_ERR*); +DEFINE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSTaskSemPost, OS_TCB*, OS_OPT, OS_ERR*); -DECLARE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSTaskSemSet, OS_TCB*, OS_SEM_CTR, OS_ERR*); +DEFINE_FAKE_VALUE_FUNC(OS_SEM_CTR, OSTaskSemSet, OS_TCB*, OS_SEM_CTR, OS_ERR*); -DECLARE_FAKE_VOID_FUNC(OSTaskStkChk, OS_TCB*, CPU_STK_SIZE*, CPU_STK_SIZE*, OS_ERR*); +DEFINE_FAKE_VOID_FUNC(OSTaskStkChk, OS_TCB*, CPU_STK_SIZE*, CPU_STK_SIZE*, OS_ERR*); -DECLARE_FAKE_VOID_FUNC(OSTaskTimeQuantaSet, OS_TCB*, OS_TICK, OS_ERR*); +DEFINE_FAKE_VOID_FUNC(OSTaskTimeQuantaSet, OS_TCB*, OS_TICK, OS_ERR*); /****** TASK LOCAL STORAGE (TLS) SUPPORT *******/ diff --git a/Tests/UnitTests/Tests/Test_ReadCarCAN.c b/Tests/UnitTests/Tests/Test_ReadCarCAN.c index 688d6a08e..c61f6ca2e 100644 --- a/Tests/UnitTests/Tests/Test_ReadCarCAN.c +++ b/Tests/UnitTests/Tests/Test_ReadCarCAN.c @@ -52,7 +52,7 @@ void test_UnitTest_bsptrip(void){ TEST_ASSERT_EQUAL(4, throwTaskError_fake.arg0_history[1]); printf("%d", throwTaskError_fake.call_count); TEST_ASSERT_EQUAL(false, UpdateDisplay_SetArray_fake.arg0_history[0]); - TEST_ASSERT_EQUAL(2, Display_Evac_fake.call_count) + TEST_ASSERT_EQUAL(2, Display_Evac_fake.call_count); } void test_UnitTest_bspcontactor(void){ From 667aaecaad23efa36315c9822a935970eba7acfb Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 16 Jan 2024 11:11:07 -0600 Subject: [PATCH 20/57] Uncommented OS functions in ReadCarCAN, still compiles. --- Apps/Src/ReadCarCAN.c | 100 +++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index f55624d46..d625ee6da 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -132,19 +132,19 @@ static void disableArrayPrechargeBypassContactor(void){ * @param None */ static void updateArrayPrechargeBypassContactor(void){ - // OS_ERR err = OS_ERR_NONE; + OS_ERR err = OS_ERR_NONE; if((arrIgnStatus || mcIgnStatus) // Ignition is ON && HVArrayMsgSaturation >= ARRAY_SATURATION_THRESHOLD // Saturation Threshold has be met && (Contactors_Get(ARRAY_PRECHARGE_BYPASS_CONTACTOR) == OFF) // Array PBC is OFF - /*&& (OSTmrStateGet(&arrayPBCDlyTimer, &err) != OS_TMR_STATE_RUNNING)*/){ // and precharge is currently not happening + && (OSTmrStateGet(&arrayPBCDlyTimer, &err) != OS_TMR_STATE_RUNNING)){ // and precharge is currently not happening // Asserts error for OS timer state above if conditional was met - // assertOSError(err); + assertOSError(err); // Wait to make sure precharge is finished and then restart array - // OSTmrStart(&arrayPBCDlyTimer, &err); + OSTmrStart(&arrayPBCDlyTimer, &err); } // Asserts error for OS timer state above if conditional was not met - // assertOSError(err); + assertOSError(err); } @@ -154,18 +154,18 @@ static void updateArrayPrechargeBypassContactor(void){ * @param None */ static void updateMCPBC(void){ - // OS_ERR err = OS_ERR_NONE; + OS_ERR err = OS_ERR_NONE; if(mcIgnStatus // Ignition is ON && HVPlusMinusChargeMsgSaturation >= PLUS_MINUS_SATURATION_THRESHOLD // Saturation Threshold has be met &&(Contactors_Get(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR) == OFF) // Motor Controller PBC is OFF - /*&& (OSTmrStateGet(&motorControllerPBCDlyTimer, &err) != OS_TMR_STATE_RUNNING)*/){ // and precharge is currently not happening + && (OSTmrStateGet(&motorControllerPBCDlyTimer, &err) != OS_TMR_STATE_RUNNING)){ // and precharge is currently not happening // Asserts error for OS timer state above if conditional was met - // assertOSError(err); + assertOSError(err); // Wait to make sure precharge is finished and then restart array - // OSTmrStart(&motorControllerPBCDlyTimer, &err); + OSTmrStart(&motorControllerPBCDlyTimer, &err); } // Asserts error for OS timer start above if conditional was not met - // assertOSError(err); + assertOSError(err); } /** @@ -286,52 +286,52 @@ static void updateHVPlusMinusSaturation(int8_t messageState){ } void Task_ReadCarCAN(void *p_arg){ - // OS_ERR err; + OS_ERR err; // data struct for CAN message CANDATA_t dataBuf; // Create the CAN Watchdog (periodic) timer, which disconnects the array and disables regenerative braking // if we do not get a CAN message with the ID Charge_Enable within the desired interval. - // OSTmrCreate( - // &canWatchTimer, - // "CAN Watch Timer", - // CAN_WATCH_TMR_DLY_TMR_TS, // Initial delay equal to the period since 0 doesn't seem to work - // CAN_WATCH_TMR_DLY_TMR_TS, - // OS_OPT_TMR_PERIODIC, - // callbackCANWatchdog, - // NULL, - // &err - // ); - // assertOSError(err); - - // OSTmrCreate( - // &arrayPBCDlyTimer, - // "Array Bypass Precharge Delay Timer", - // 0, - // ARRAY_PRECHARGE_BYPASS_DLY_TMR_TS, - // OS_OPT_TMR_ONE_SHOT, - // setArrayBypassPrechargeComplete, - // NULL, - // &err - // ); - // assertOSError(err); - - // OSTmrCreate( - // &motorControllerPBCDlyTimer, - // "Motor Controller Bypass Precharge Delay Timer", - // 0, - // MOTOR_CONTROLLER_PRECHARGE_BYPASS_DLY_TMR_TS, - // OS_OPT_TMR_ONE_SHOT, - // setMotorControllerBypassPrechargeComplete, - // NULL, - // &err - // ); - // assertOSError(err); + OSTmrCreate( + &canWatchTimer, + "CAN Watch Timer", + CAN_WATCH_TMR_DLY_TMR_TS, // Initial delay equal to the period since 0 doesn't seem to work + CAN_WATCH_TMR_DLY_TMR_TS, + OS_OPT_TMR_PERIODIC, + callbackCANWatchdog, + NULL, + &err + ); + assertOSError(err); + + OSTmrCreate( + &arrayPBCDlyTimer, + "Array Bypass Precharge Delay Timer", + 0, + ARRAY_PRECHARGE_BYPASS_DLY_TMR_TS, + OS_OPT_TMR_ONE_SHOT, + setArrayBypassPrechargeComplete, + NULL, + &err + ); + assertOSError(err); + + OSTmrCreate( + &motorControllerPBCDlyTimer, + "Motor Controller Bypass Precharge Delay Timer", + 0, + MOTOR_CONTROLLER_PRECHARGE_BYPASS_DLY_TMR_TS, + OS_OPT_TMR_ONE_SHOT, + setMotorControllerBypassPrechargeComplete, + NULL, + &err + ); + assertOSError(err); // Start CAN Watchdog timer - // OSTmrStart(&canWatchTimer, &err); - // assertOSError(err); + OSTmrStart(&canWatchTimer, &err); + assertOSError(err); // Fills buffers with disable messages // NOTE: If the buffer becomes bigger than of type int8_t, memset will not work and @@ -357,8 +357,8 @@ void Task_ReadCarCAN(void *p_arg){ } case BPS_CONTACTOR: { - // OSTmrStart(&canWatchTimer, &err); // Restart CAN Watchdog timer for BPS Contactor msg - // assertOSError(err); + OSTmrStart(&canWatchTimer, &err); // Restart CAN Watchdog timer for BPS Contactor msg + assertOSError(err); // Retrieving HV contactor statuses using bit mapping // Bitwise to get HV Plus and Minus, and then &&ing to ensure both are on From 163f877b8c2b0158ebb5701387df7a6d346df2d4 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 16 Jan 2024 11:33:41 -0600 Subject: [PATCH 21/57] Moved task prototypes to their respective header files. --- Apps/Inc/ReadCarCAN.h | 7 +++++++ Apps/Inc/ReadTritium.h | 6 ++++++ Apps/Inc/SendCarCAN.h | 6 ++++++ Apps/Inc/SendTritium.h | 6 ++++++ Apps/Inc/Tasks.h | 10 ---------- Apps/Inc/UpdateDisplay.h | 6 ++++++ Apps/Src/main.c | 3 +++ 7 files changed, 34 insertions(+), 10 deletions(-) diff --git a/Apps/Inc/ReadCarCAN.h b/Apps/Inc/ReadCarCAN.h index a7a592b50..8a2519352 100644 --- a/Apps/Inc/ReadCarCAN.h +++ b/Apps/Inc/ReadCarCAN.h @@ -27,6 +27,13 @@ typedef enum{ READCARCAN_ERR_BPS_TRIP // Received a BPS trip msg (0 or 1) } ReadCarCAN_error_code_t; + +/** + * Task Prototype + */ +void Task_ReadCarCAN(void* p_arg); + + /** * @brief Returns whether regen braking / charging is enabled or not * @return Whether regen braking / charging is enabled or not diff --git a/Apps/Inc/ReadTritium.h b/Apps/Inc/ReadTritium.h index 0d1f76338..9888dadcb 100755 --- a/Apps/Inc/ReadTritium.h +++ b/Apps/Inc/ReadTritium.h @@ -34,6 +34,12 @@ typedef enum{ T_NONE = 0x00, } tritium_error_code_t; +/** + * Task Prototype + */ +void Task_ReadTritium(void* p_arg); + + float Motor_RPM_Get(); float Motor_Velocity_Get(); diff --git a/Apps/Inc/SendCarCAN.h b/Apps/Inc/SendCarCAN.h index 99772bfb3..1a8626075 100644 --- a/Apps/Inc/SendCarCAN.h +++ b/Apps/Inc/SendCarCAN.h @@ -3,6 +3,12 @@ #include "CANbus.h" +/** + * Task Prototype + */ +void Task_SendCarCAN(void* p_arg); + + /** * @brief Initialize SendCarCAN */ diff --git a/Apps/Inc/SendTritium.h b/Apps/Inc/SendTritium.h index 65ed7be29..4d4cd84b2 100644 --- a/Apps/Inc/SendTritium.h +++ b/Apps/Inc/SendTritium.h @@ -66,6 +66,12 @@ extern float velocityObserved; extern float cruiseVelSetpoint; #endif +/** + * Task Prototype + */ +void Task_SendTritium(void* p_arg); + + // Getter functions for local variables in SendTritium.c EXPOSE_GETTER(bool, cruiseEnable) EXPOSE_GETTER(bool, cruiseSet) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 3f6d700e8..36b1b99a0 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -60,16 +60,6 @@ typedef uint16_t error_code_t; */ void Task_Init(void* p_arg); -void Task_SendTritium(void* p_arg); - -void Task_ReadCarCAN(void* p_arg); - -void Task_UpdateDisplay(void* p_arg); - -void Task_ReadTritium(void* p_arg); - -void Task_SendCarCAN(void* p_arg); - void Task_DebugDump(void *p_arg); void Task_CommandLine(void* p_arg); diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index 12cb5ca99..161618339 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -53,6 +53,12 @@ typedef enum{ #define DISP_FORWARD STATE_1 #define DISP_REVERSE STATE_2 +/** + * Task Prototype + */ +void Task_UpdateDisplay(void* p_arg); + + /** * @brief Initializes UpdateDisplay application * @returns UpdateDisplayError_t diff --git a/Apps/Src/main.c b/Apps/Src/main.c index aeb19ff15..4c85c7b7f 100644 --- a/Apps/Src/main.c +++ b/Apps/Src/main.c @@ -16,7 +16,10 @@ #include "Minions.h" #include "Pedals.h" #include "UpdateDisplay.h" +#include "ReadCarCAN.h" #include "SendCarCAN.h" +#include "ReadTritium.h" +#include "SendTritium.h" #define IGN_CONT_PERIOD 100 From 72fd00c07306b18a50b5df046823b4c0ff615ff1 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 16 Jan 2024 17:19:47 -0600 Subject: [PATCH 22/57] Mocked/stubbed BSP stm32f4xx.h and _gpio.h/c files from CMSIS- this should cover all the parts of the os we need, I think? --- Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h | 32 + .../UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h | 1041 ++++++++--------- .../UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c | 34 + 3 files changed, 579 insertions(+), 528 deletions(-) create mode 100644 Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h create mode 100644 Tests/UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c diff --git a/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h b/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h new file mode 100644 index 000000000..508969d1f --- /dev/null +++ b/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h @@ -0,0 +1,32 @@ + +#ifndef __STM32F4xx_H +#define __STM32F4xx_H + +#include + + +#ifndef __CONFIG_H +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; +#endif + +#define __IO volatile + +/** + * @brief General Purpose I/O + */ + +typedef struct +{ + __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ + __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ + __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ + __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ + __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ + __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ + __IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */ + __IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */ + __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ + __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ +} GPIO_TypeDef; + +#endif diff --git a/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h b/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h index d15b0f6e4..fc1368098 100644 --- a/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h +++ b/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h @@ -1,157 +1,132 @@ -// /** -// ****************************************************************************** -// * @file stm32f4xx_gpio.h -// * @author MCD Application Team -// * @version V1.8.0 -// * @date 04-November-2016 -// * @brief This file contains all the functions prototypes for the GPIO firmware -// * library. -// ****************************************************************************** -// * @attention -// * -// *

© COPYRIGHT 2016 STMicroelectronics

-// * -// * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); -// * You may not use this file except in compliance with the License. -// * You may obtain a copy of the License at: -// * -// * http://www.st.com/software_license_agreement_liberty_v2 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// * -// ****************************************************************************** -// */ - -// /* Define to prevent recursive inclusion -------------------------------------*/ +//////// MOCK ///////////////// + +/* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __STM32F4xx_GPIO_H #define __STM32F4xx_GPIO_H -// #ifdef __cplusplus -// extern "C" { -// #endif - -// /* Includes ------------------------------------------------------------------*/ -// #include "stm32f4xx.h" - -// /** @addtogroup STM32F4xx_StdPeriph_Driver -// * @{ -// */ - -// /** @addtogroup GPIO -// * @{ -// */ - -// /* Exported types ------------------------------------------------------------*/ - -// #define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ -// ((PERIPH) == GPIOB) || \ -// ((PERIPH) == GPIOC) || \ -// ((PERIPH) == GPIOD) || \ -// ((PERIPH) == GPIOE) || \ -// ((PERIPH) == GPIOF) || \ -// ((PERIPH) == GPIOG) || \ -// ((PERIPH) == GPIOH) || \ -// ((PERIPH) == GPIOI) || \ -// ((PERIPH) == GPIOJ) || \ -// ((PERIPH) == GPIOK)) - -// /** -// * @brief GPIO Configuration Mode enumeration -// */ -// typedef enum -// { -// GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ -// GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ -// GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ -// GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */ -// }GPIOMode_TypeDef; -// #define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN) || ((MODE) == GPIO_Mode_OUT) || \ -// ((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN)) - -// /** -// * @brief GPIO Output type enumeration -// */ -// typedef enum -// { -// GPIO_OType_PP = 0x00, -// GPIO_OType_OD = 0x01 -// }GPIOOType_TypeDef; -// #define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD)) - - -// /** -// * @brief GPIO Output Maximum frequency enumeration -// */ -// typedef enum -// { -// GPIO_Low_Speed = 0x00, /*!< Low speed */ -// GPIO_Medium_Speed = 0x01, /*!< Medium speed */ -// GPIO_Fast_Speed = 0x02, /*!< Fast speed */ -// GPIO_High_Speed = 0x03 /*!< High speed */ -// }GPIOSpeed_TypeDef; - -// /* Add legacy definition */ -// #define GPIO_Speed_2MHz GPIO_Low_Speed -// #define GPIO_Speed_25MHz GPIO_Medium_Speed -// #define GPIO_Speed_50MHz GPIO_Fast_Speed -// #define GPIO_Speed_100MHz GPIO_High_Speed +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" +#include "fff.h" + +/** @addtogroup STM32F4xx_StdPeriph_Driver + * @{ + */ + +/** @addtogroup GPIO + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ + ((PERIPH) == GPIOB) || \ + ((PERIPH) == GPIOC) || \ + ((PERIPH) == GPIOD) || \ + ((PERIPH) == GPIOE) || \ + ((PERIPH) == GPIOF) || \ + ((PERIPH) == GPIOG) || \ + ((PERIPH) == GPIOH) || \ + ((PERIPH) == GPIOI) || \ + ((PERIPH) == GPIOJ) || \ + ((PERIPH) == GPIOK)) + +/** + * @brief GPIO Configuration Mode enumeration + */ +typedef enum +{ + GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ + GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ + GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ + GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */ +}GPIOMode_TypeDef; +#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN) || ((MODE) == GPIO_Mode_OUT) || \ + ((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN)) + +/** + * @brief GPIO Output type enumeration + */ +typedef enum +{ + GPIO_OType_PP = 0x00, + GPIO_OType_OD = 0x01 +}GPIOOType_TypeDef; +#define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD)) + + +/** + * @brief GPIO Output Maximum frequency enumeration + */ +typedef enum +{ + GPIO_Low_Speed = 0x00, /*!< Low speed */ + GPIO_Medium_Speed = 0x01, /*!< Medium speed */ + GPIO_Fast_Speed = 0x02, /*!< Fast speed */ + GPIO_High_Speed = 0x03 /*!< High speed */ +}GPIOSpeed_TypeDef; + +/* Add legacy definition */ +#define GPIO_Speed_2MHz GPIO_Low_Speed +#define GPIO_Speed_25MHz GPIO_Medium_Speed +#define GPIO_Speed_50MHz GPIO_Fast_Speed +#define GPIO_Speed_100MHz GPIO_High_Speed -// #define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Low_Speed) || ((SPEED) == GPIO_Medium_Speed) || \ -// ((SPEED) == GPIO_Fast_Speed)|| ((SPEED) == GPIO_High_Speed)) - -// /** -// * @brief GPIO Configuration PullUp PullDown enumeration -// */ -// typedef enum -// { -// GPIO_PuPd_NOPULL = 0x00, -// GPIO_PuPd_UP = 0x01, -// GPIO_PuPd_DOWN = 0x02 -// }GPIOPuPd_TypeDef; -// #define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \ -// ((PUPD) == GPIO_PuPd_DOWN)) - -// /** -// * @brief GPIO Bit SET and Bit RESET enumeration -// */ -// typedef enum -// { -// Bit_RESET = 0, -// Bit_SET -// }BitAction; -// #define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) - - -// /** -// * @brief GPIO Init structure definition -// */ -// typedef struct -// { -// uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. -// This parameter can be any value of @ref GPIO_pins_define */ - -// GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. -// This parameter can be a value of @ref GPIOMode_TypeDef */ - -// GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. -// This parameter can be a value of @ref GPIOSpeed_TypeDef */ - -// GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins. -// This parameter can be a value of @ref GPIOOType_TypeDef */ - -// GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. -// This parameter can be a value of @ref GPIOPuPd_TypeDef */ -// }GPIO_InitTypeDef; - -// /* Exported constants --------------------------------------------------------*/ - -// /** @defgroup GPIO_Exported_Constants -// * @{ -// */ +#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Low_Speed) || ((SPEED) == GPIO_Medium_Speed) || \ + ((SPEED) == GPIO_Fast_Speed)|| ((SPEED) == GPIO_High_Speed)) + +/** + * @brief GPIO Configuration PullUp PullDown enumeration + */ +typedef enum +{ + GPIO_PuPd_NOPULL = 0x00, + GPIO_PuPd_UP = 0x01, + GPIO_PuPd_DOWN = 0x02 +}GPIOPuPd_TypeDef; +#define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \ + ((PUPD) == GPIO_PuPd_DOWN)) + +/** + * @brief GPIO Bit SET and Bit RESET enumeration + */ +typedef enum +{ + Bit_RESET = 0, + Bit_SET +}BitAction; +#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) + + +/** + * @brief GPIO Init structure definition + */ +typedef struct +{ + uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref GPIO_pins_define */ + + GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref GPIOMode_TypeDef */ + + GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. + This parameter can be a value of @ref GPIOSpeed_TypeDef */ + + GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins. + This parameter can be a value of @ref GPIOOType_TypeDef */ + + GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. + This parameter can be a value of @ref GPIOPuPd_TypeDef */ +}GPIO_InitTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup GPIO_Exported_Constants + * @{ + */ /** @defgroup GPIO_pins_define * @{ @@ -197,396 +172,406 @@ */ -// /** @defgroup GPIO_Pin_sources -// * @{ -// */ -// #define GPIO_PinSource0 ((uint8_t)0x00) -// #define GPIO_PinSource1 ((uint8_t)0x01) -// #define GPIO_PinSource2 ((uint8_t)0x02) -// #define GPIO_PinSource3 ((uint8_t)0x03) -// #define GPIO_PinSource4 ((uint8_t)0x04) -// #define GPIO_PinSource5 ((uint8_t)0x05) -// #define GPIO_PinSource6 ((uint8_t)0x06) -// #define GPIO_PinSource7 ((uint8_t)0x07) -// #define GPIO_PinSource8 ((uint8_t)0x08) -// #define GPIO_PinSource9 ((uint8_t)0x09) -// #define GPIO_PinSource10 ((uint8_t)0x0A) -// #define GPIO_PinSource11 ((uint8_t)0x0B) -// #define GPIO_PinSource12 ((uint8_t)0x0C) -// #define GPIO_PinSource13 ((uint8_t)0x0D) -// #define GPIO_PinSource14 ((uint8_t)0x0E) -// #define GPIO_PinSource15 ((uint8_t)0x0F) - -// #define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \ -// ((PINSOURCE) == GPIO_PinSource1) || \ -// ((PINSOURCE) == GPIO_PinSource2) || \ -// ((PINSOURCE) == GPIO_PinSource3) || \ -// ((PINSOURCE) == GPIO_PinSource4) || \ -// ((PINSOURCE) == GPIO_PinSource5) || \ -// ((PINSOURCE) == GPIO_PinSource6) || \ -// ((PINSOURCE) == GPIO_PinSource7) || \ -// ((PINSOURCE) == GPIO_PinSource8) || \ -// ((PINSOURCE) == GPIO_PinSource9) || \ -// ((PINSOURCE) == GPIO_PinSource10) || \ -// ((PINSOURCE) == GPIO_PinSource11) || \ -// ((PINSOURCE) == GPIO_PinSource12) || \ -// ((PINSOURCE) == GPIO_PinSource13) || \ -// ((PINSOURCE) == GPIO_PinSource14) || \ -// ((PINSOURCE) == GPIO_PinSource15)) -// /** -// * @} -// */ - -// /** @defgroup GPIO_Alternat_function_selection_define -// * @{ -// */ -// /** -// * @brief AF 0 selection -// */ -// #define GPIO_AF_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ -// #define GPIO_AF_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ -// #define GPIO_AF_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ -// #define GPIO_AF_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ -// #define GPIO_AF_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ -// #if defined(STM32F446xx) -// #define GPIO_AF0_TIM2 ((uint8_t)0x00) /* TIM2 Alternate Function mapping */ -// #endif /* STM32F446xx */ - -// /** -// * @brief AF 1 selection -// */ -// #define GPIO_AF_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ -// #define GPIO_AF_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ -// #if defined(STM32F410xx) || defined(STM32F413_423xx) -// #define GPIO_AF_LPTIM ((uint8_t)0x01) /* LPTIM Alternate Function mapping */ -// #endif /* STM32F410xx || STM32F413_423xx */ -// /** -// * @brief AF 2 selection -// */ -// #define GPIO_AF_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ -// #define GPIO_AF_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ -// #define GPIO_AF_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ - -// /** -// * @brief AF 3 selection -// */ -// #define GPIO_AF_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */ -// #define GPIO_AF_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */ -// #define GPIO_AF_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */ -// #define GPIO_AF_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */ -// #if defined(STM32F446xx) -// #define GPIO_AF3_CEC ((uint8_t)0x03) /* CEC Alternate Function mapping */ -// #endif /* STM32F446xx */ -// #if defined(STM32F413_423xx) -// #define GPIO_AF3_DFSDM2 ((uint8_t)0x03) /* DFSDM2 Alternate Function mapping */ -// #endif /* STM32F413_423xx */ -// /** -// * @brief AF 4 selection -// */ -// #define GPIO_AF_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ -// #define GPIO_AF_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ -// #define GPIO_AF_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ -// #if defined(STM32F446xx) -// #define GPIO_AF4_CEC ((uint8_t)0x04) /* CEC Alternate Function mapping */ -// #endif /* STM32F446xx */ -// #if defined(STM32F410xx) || defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) -// #define GPIO_AF_FMPI2C ((uint8_t)0x04) /* FMPI2C Alternate Function mapping */ -// #endif /* STM32F410xx || STM32F446xx */ - -// /** -// * @brief AF 5 selection -// */ -// #define GPIO_AF_SPI1 ((uint8_t)0x05) /* SPI1/I2S1 Alternate Function mapping */ -// #define GPIO_AF_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */ -// #define GPIO_AF5_SPI3 ((uint8_t)0x05) /* SPI3/I2S3 Alternate Function mapping (Only for STM32F411xE and STM32F413_423xx Devices) */ -// #define GPIO_AF_SPI4 ((uint8_t)0x05) /* SPI4/I2S4 Alternate Function mapping */ -// #define GPIO_AF_SPI5 ((uint8_t)0x05) /* SPI5 Alternate Function mapping */ -// #define GPIO_AF_SPI6 ((uint8_t)0x05) /* SPI6 Alternate Function mapping */ - -// /** -// * @brief AF 6 selection -// */ -// #define GPIO_AF_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */ -// #define GPIO_AF6_SPI1 ((uint8_t)0x06) /* SPI1 Alternate Function mapping (Only for STM32F410xx Devices) */ -// #define GPIO_AF6_SPI2 ((uint8_t)0x06) /* SPI2 Alternate Function mapping (Only for STM32F410xx/STM32F411xE Devices) */ -// #define GPIO_AF6_SPI4 ((uint8_t)0x06) /* SPI4 Alternate Function mapping (Only for STM32F411xE Devices) */ -// #define GPIO_AF6_SPI5 ((uint8_t)0x06) /* SPI5 Alternate Function mapping (Only for STM32F410xx/STM32F411xE Devices) */ -// #define GPIO_AF_SAI1 ((uint8_t)0x06) /* SAI1 Alternate Function mapping */ -// #define GPIO_AF_I2S2ext ((uint8_t)0x06) /* I2S2ext_SD Alternate Function mapping (only for STM32F412xG and STM32F413_423xx Devices) */ -// #if defined(STM32F412xG) || defined(STM32F413_423xx) -// #define GPIO_AF6_DFSDM1 ((uint8_t)0x06) /* DFSDM1 Alternate Function mapping */ -// #endif /* STM32F412xG || STM32F413_423xx */ -// #if defined(STM32F413_423xx) -// #define GPIO_AF6_DFSDM2 ((uint8_t)0x06) /* DFSDM2 Alternate Function mapping */ -// #endif /* STM32F413_423xx */ - -// /** -// * @brief AF 7 selection -// */ -// #define GPIO_AF_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ -// #define GPIO_AF_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ -// #define GPIO_AF_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */ -// #define GPIO_AF7_SPI3 ((uint8_t)0x07) /* SPI3/I2S3ext Alternate Function mapping */ -// #if defined(STM32F413_423xx) -// #define GPIO_AF7_DFSDM2 ((uint8_t)0x07) /* DFSDM2 Alternate Function mapping */ -// #define GPIO_AF7_SAI1 ((uint8_t)0x07) /* SAI1 Alternate Function mapping */ -// #endif /* STM32F413_423xx */ - -// /** -// * @brief AF 7 selection Legacy -// */ -// #define GPIO_AF_I2S3ext GPIO_AF7_SPI3 - -// /** -// * @brief AF 8 selection -// */ -// #define GPIO_AF_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */ -// #define GPIO_AF_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */ -// #define GPIO_AF_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */ -// #define GPIO_AF_UART7 ((uint8_t)0x08) /* UART7 Alternate Function mapping */ -// #define GPIO_AF_UART8 ((uint8_t)0x08) /* UART8 Alternate Function mapping */ -// #if defined(STM32F412xG) || defined(STM32F413_423xx) -// #define GPIO_AF8_USART3 ((uint8_t)0x08) /* USART3 Alternate Function mapping */ -// #define GPIO_AF8_DFSDM1 ((uint8_t)0x08) /* DFSDM Alternate Function mapping */ -// #define GPIO_AF8_CAN1 ((uint8_t)0x08) /* CAN1 Alternate Function mapping */ -// #endif /* STM32F412xG || STM32F413_423xx */ -// #if defined(STM32F446xx) -// #define GPIO_AF8_SAI2 ((uint8_t)0x08) /* SAI2 Alternate Function mapping */ -// #define GPIO_AF_SPDIF ((uint8_t)0x08) /* SPDIF Alternate Function mapping */ -// #endif /* STM32F446xx */ - -// /** -// * @brief AF 9 selection -// */ -// #define GPIO_AF_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */ -// #define GPIO_AF_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */ -// #define GPIO_AF_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */ -// #define GPIO_AF_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */ -// #define GPIO_AF_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ -// #define GPIO_AF9_I2C2 ((uint8_t)0x09) /* I2C2 Alternate Function mapping (Only for STM32F401xx/STM32F410xx/STM32F411xE/STM32F412xG/STM32F413_423xx Devices) */ -// #define GPIO_AF9_I2C3 ((uint8_t)0x09) /* I2C3 Alternate Function mapping (Only for STM32F401xx/STM32F411xE/STM32F412xG and STM32F413_423xx Devices) */ -// #if defined(STM32F446xx) -// #define GPIO_AF9_SAI2 ((uint8_t)0x09) /* SAI2 Alternate Function mapping */ -// #endif /* STM32F446xx */ -// #define GPIO_AF9_LTDC ((uint8_t)0x09) /* LTDC Alternate Function mapping */ -// #if defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) || defined(STM32F469_479xx) -// #define GPIO_AF9_QUADSPI ((uint8_t)0x09) /* QuadSPI Alternate Function mapping */ -// #endif /* STM32F412xG || STM32F413_423xx || STM32F446xx || STM32F469_479xx */ -// #if defined(STM32F410xx) || defined(STM32F412xG) || defined(STM32F413_423xx) -// #define GPIO_AF9_FMPI2C ((uint8_t)0x09) /* FMPI2C Alternate Function mapping (Only for STM32F410xx Devices) */ -// #endif /* STM32F410xx || STM32F412xG || STM32F413_423xx */ - -// /** -// * @brief AF 10 selection -// */ -// #define GPIO_AF_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ -// #define GPIO_AF_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */ -// #if defined(STM32F446xx) -// #define GPIO_AF10_SAI2 ((uint8_t)0x0A) /* SAI2 Alternate Function mapping */ -// #endif /* STM32F446xx */ -// #if defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) || defined(STM32F469_479xx) -// #define GPIO_AF10_QUADSPI ((uint8_t)0x0A) /* QuadSPI Alternate Function mapping */ -// #endif /* STM32F412xG || STM32F413_423xx || STM32F446xx || STM32F469_479xx */ -// #if defined(STM32F412xG) || defined(STM32F413_423xx) -// #define GPIO_AF10_FMC ((uint8_t)0xA) /* FMC Alternate Function mapping */ -// #define GPIO_AF10_DFSDM1 ((uint8_t)0xA) /* DFSDM Alternate Function mapping */ -// #endif /* STM32F412xG || STM32F413_423xx */ -// #if defined(STM32F413_423xx) -// #define GPIO_AF10_DFSDM2 ((uint8_t)0x0A) /* DFSDM2 Alternate Function mapping */ -// #define GPIO_AF10_SAI1 ((uint8_t)0x0A) /* SAI1 Alternate Function mapping */ -// #endif /* STM32F413_423xx */ -// /** -// * @brief AF 11 selection -// */ -// #define GPIO_AF_ETH ((uint8_t)0x0B) /* ETHERNET Alternate Function mapping */ -// #if defined(STM32F413_423xx) -// #define GPIO_AF11_UART4 ((uint8_t)0x0B) /* UART4 Alternate Function mapping */ -// #define GPIO_AF11_UART5 ((uint8_t)0x0B) /* UART5 Alternate Function mapping */ -// #define GPIO_AF11_UART9 ((uint8_t)0x0B) /* UART9 Alternate Function mapping */ -// #define GPIO_AF11_UART10 ((uint8_t)0x0B) /* UART10 Alternate Function mapping */ -// #define GPIO_AF11_CAN3 ((uint8_t)0x0B) /* CAN3 Alternate Function mapping */ -// #endif /* STM32F413_423xx */ - -// /** -// * @brief AF 12 selection -// */ -// #if defined(STM32F40_41xxx) || defined(STM32F412xG) || defined(STM32F413_423xx) -// #define GPIO_AF_FSMC ((uint8_t)0xC) /* FSMC Alternate Function mapping */ -// #endif /* STM32F40_41xxx || STM32F412xG || STM32F413_423xx */ - -// #if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx) -// #define GPIO_AF_FMC ((uint8_t)0xC) /* FMC Alternate Function mapping */ -// #endif /* STM32F427_437xx || STM32F429_439xx || STM32F446xx || STM32F469_479xx */ - -// #define GPIO_AF_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */ -// #define GPIO_AF_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */ - -// /** -// * @brief AF 13 selection -// */ -// #define GPIO_AF_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */ -// #if defined(STM32F469_479xx) -// #define GPIO_AF_DSI ((uint8_t)0x0D) /* DSI Alternate Function mapping */ -// #endif /* STM32F469_479xx */ -// /** -// * @brief AF 14 selection -// */ -// #define GPIO_AF_LTDC ((uint8_t)0x0E) /* LCD-TFT Alternate Function mapping */ -// #if defined(STM32F413_423xx) -// #define GPIO_AF14_RNG ((uint8_t)0x0E) /* RNG Alternate Function mapping */ -// #endif /* STM32F413_423xx */ - -// /** -// * @brief AF 15 selection -// */ -// #define GPIO_AF_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ - -// #if defined(STM32F40_41xxx) -// #define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ -// ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ -// ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ -// ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ -// ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ -// ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ -// ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ -// ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ -// ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ -// ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ -// ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ -// ((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \ -// ((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \ -// ((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \ -// ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ -// ((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_OTG_HS_FS) || \ -// ((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_DCMI) || \ -// ((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_FSMC)) -// #endif /* STM32F40_41xxx */ - -// #if defined(STM32F401xx) -// #define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ -// ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ -// ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ -// ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ -// ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ -// ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ -// ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ -// ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ -// ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ -// ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ -// ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ -// ((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_USART6) || \ -// ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ -// ((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_SPI4)) -// #endif /* STM32F401xx */ - -// #if defined(STM32F411xE) -// #define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 13) && ((AF) != 14)) -// #endif /* STM32F411xE */ - -// #if defined(STM32F410xx) -// #define IS_GPIO_AF(AF) (((AF) < 10) || ((AF) == 15)) -// #endif /* STM32F410xx */ - -// #if defined(STM32F427_437xx) || defined(STM32F429_439xx) -// #define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ -// ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ -// ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ -// ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ -// ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ -// ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ -// ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ -// ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ -// ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ -// ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ -// ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ -// ((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \ -// ((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \ -// ((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \ -// ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ -// ((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_OTG_HS_FS) || \ -// ((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_DCMI) || \ -// ((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_SPI4) || \ -// ((AF) == GPIO_AF_SPI5) || ((AF) == GPIO_AF_SPI6) || \ -// ((AF) == GPIO_AF_UART7) || ((AF) == GPIO_AF_UART8) || \ -// ((AF) == GPIO_AF_FMC) || ((AF) == GPIO_AF_SAI1) || \ -// ((AF) == GPIO_AF_LTDC)) -// #endif /* STM32F427_437xx || STM32F429_439xx */ - -// #if defined(STM32F412xG) -// #define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 14)) -// #endif /* STM32F412xG */ - -// #if defined(STM32F413_423xx) -// #define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 13)) -// #endif /* STM32F413_423xx */ - -// #if defined(STM32F446xx) -// #define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 14)) -// #endif /* STM32F446xx */ - -// #if defined(STM32F469_479xx) -// #define IS_GPIO_AF(AF) ((AF) < 16) -// #endif /* STM32F469_479xx */ - -// /** -// * @} -// */ - -// /** @defgroup GPIO_Legacy -// * @{ -// */ +/** @defgroup GPIO_Pin_sources + * @{ + */ +#define GPIO_PinSource0 ((uint8_t)0x00) +#define GPIO_PinSource1 ((uint8_t)0x01) +#define GPIO_PinSource2 ((uint8_t)0x02) +#define GPIO_PinSource3 ((uint8_t)0x03) +#define GPIO_PinSource4 ((uint8_t)0x04) +#define GPIO_PinSource5 ((uint8_t)0x05) +#define GPIO_PinSource6 ((uint8_t)0x06) +#define GPIO_PinSource7 ((uint8_t)0x07) +#define GPIO_PinSource8 ((uint8_t)0x08) +#define GPIO_PinSource9 ((uint8_t)0x09) +#define GPIO_PinSource10 ((uint8_t)0x0A) +#define GPIO_PinSource11 ((uint8_t)0x0B) +#define GPIO_PinSource12 ((uint8_t)0x0C) +#define GPIO_PinSource13 ((uint8_t)0x0D) +#define GPIO_PinSource14 ((uint8_t)0x0E) +#define GPIO_PinSource15 ((uint8_t)0x0F) + +#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \ + ((PINSOURCE) == GPIO_PinSource1) || \ + ((PINSOURCE) == GPIO_PinSource2) || \ + ((PINSOURCE) == GPIO_PinSource3) || \ + ((PINSOURCE) == GPIO_PinSource4) || \ + ((PINSOURCE) == GPIO_PinSource5) || \ + ((PINSOURCE) == GPIO_PinSource6) || \ + ((PINSOURCE) == GPIO_PinSource7) || \ + ((PINSOURCE) == GPIO_PinSource8) || \ + ((PINSOURCE) == GPIO_PinSource9) || \ + ((PINSOURCE) == GPIO_PinSource10) || \ + ((PINSOURCE) == GPIO_PinSource11) || \ + ((PINSOURCE) == GPIO_PinSource12) || \ + ((PINSOURCE) == GPIO_PinSource13) || \ + ((PINSOURCE) == GPIO_PinSource14) || \ + ((PINSOURCE) == GPIO_PinSource15)) +/** + * @} + */ + +/** @defgroup GPIO_Alternat_function_selection_define + * @{ + */ +/** + * @brief AF 0 selection + */ +#define GPIO_AF_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ +#define GPIO_AF_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ +#define GPIO_AF_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ +#define GPIO_AF_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ +#define GPIO_AF_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ +#if defined(STM32F446xx) +#define GPIO_AF0_TIM2 ((uint8_t)0x00) /* TIM2 Alternate Function mapping */ +#endif /* STM32F446xx */ + +/** + * @brief AF 1 selection + */ +#define GPIO_AF_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ +#define GPIO_AF_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ +#if defined(STM32F410xx) || defined(STM32F413_423xx) +#define GPIO_AF_LPTIM ((uint8_t)0x01) /* LPTIM Alternate Function mapping */ +#endif /* STM32F410xx || STM32F413_423xx */ +/** + * @brief AF 2 selection + */ +#define GPIO_AF_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ +#define GPIO_AF_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ +#define GPIO_AF_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ + +/** + * @brief AF 3 selection + */ +#define GPIO_AF_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */ +#define GPIO_AF_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */ +#define GPIO_AF_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */ +#define GPIO_AF_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */ +#if defined(STM32F446xx) +#define GPIO_AF3_CEC ((uint8_t)0x03) /* CEC Alternate Function mapping */ +#endif /* STM32F446xx */ +#if defined(STM32F413_423xx) +#define GPIO_AF3_DFSDM2 ((uint8_t)0x03) /* DFSDM2 Alternate Function mapping */ +#endif /* STM32F413_423xx */ +/** + * @brief AF 4 selection + */ +#define GPIO_AF_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ +#define GPIO_AF_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ +#define GPIO_AF_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ +#if defined(STM32F446xx) +#define GPIO_AF4_CEC ((uint8_t)0x04) /* CEC Alternate Function mapping */ +#endif /* STM32F446xx */ +#if defined(STM32F410xx) || defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) +#define GPIO_AF_FMPI2C ((uint8_t)0x04) /* FMPI2C Alternate Function mapping */ +#endif /* STM32F410xx || STM32F446xx */ + +/** + * @brief AF 5 selection + */ +#define GPIO_AF_SPI1 ((uint8_t)0x05) /* SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF5_SPI3 ((uint8_t)0x05) /* SPI3/I2S3 Alternate Function mapping (Only for STM32F411xE and STM32F413_423xx Devices) */ +#define GPIO_AF_SPI4 ((uint8_t)0x05) /* SPI4/I2S4 Alternate Function mapping */ +#define GPIO_AF_SPI5 ((uint8_t)0x05) /* SPI5 Alternate Function mapping */ +#define GPIO_AF_SPI6 ((uint8_t)0x05) /* SPI6 Alternate Function mapping */ + +/** + * @brief AF 6 selection + */ +#define GPIO_AF_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF6_SPI1 ((uint8_t)0x06) /* SPI1 Alternate Function mapping (Only for STM32F410xx Devices) */ +#define GPIO_AF6_SPI2 ((uint8_t)0x06) /* SPI2 Alternate Function mapping (Only for STM32F410xx/STM32F411xE Devices) */ +#define GPIO_AF6_SPI4 ((uint8_t)0x06) /* SPI4 Alternate Function mapping (Only for STM32F411xE Devices) */ +#define GPIO_AF6_SPI5 ((uint8_t)0x06) /* SPI5 Alternate Function mapping (Only for STM32F410xx/STM32F411xE Devices) */ +#define GPIO_AF_SAI1 ((uint8_t)0x06) /* SAI1 Alternate Function mapping */ +#define GPIO_AF_I2S2ext ((uint8_t)0x06) /* I2S2ext_SD Alternate Function mapping (only for STM32F412xG and STM32F413_423xx Devices) */ +#if defined(STM32F412xG) || defined(STM32F413_423xx) +#define GPIO_AF6_DFSDM1 ((uint8_t)0x06) /* DFSDM1 Alternate Function mapping */ +#endif /* STM32F412xG || STM32F413_423xx */ +#if defined(STM32F413_423xx) +#define GPIO_AF6_DFSDM2 ((uint8_t)0x06) /* DFSDM2 Alternate Function mapping */ +#endif /* STM32F413_423xx */ + +/** + * @brief AF 7 selection + */ +#define GPIO_AF_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ +#define GPIO_AF_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ +#define GPIO_AF_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */ +#define GPIO_AF7_SPI3 ((uint8_t)0x07) /* SPI3/I2S3ext Alternate Function mapping */ +#if defined(STM32F413_423xx) +#define GPIO_AF7_DFSDM2 ((uint8_t)0x07) /* DFSDM2 Alternate Function mapping */ +#define GPIO_AF7_SAI1 ((uint8_t)0x07) /* SAI1 Alternate Function mapping */ +#endif /* STM32F413_423xx */ + +/** + * @brief AF 7 selection Legacy + */ +#define GPIO_AF_I2S3ext GPIO_AF7_SPI3 + +/** + * @brief AF 8 selection + */ +#define GPIO_AF_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */ +#define GPIO_AF_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */ +#define GPIO_AF_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */ +#define GPIO_AF_UART7 ((uint8_t)0x08) /* UART7 Alternate Function mapping */ +#define GPIO_AF_UART8 ((uint8_t)0x08) /* UART8 Alternate Function mapping */ +#if defined(STM32F412xG) || defined(STM32F413_423xx) +#define GPIO_AF8_USART3 ((uint8_t)0x08) /* USART3 Alternate Function mapping */ +#define GPIO_AF8_DFSDM1 ((uint8_t)0x08) /* DFSDM Alternate Function mapping */ +#define GPIO_AF8_CAN1 ((uint8_t)0x08) /* CAN1 Alternate Function mapping */ +#endif /* STM32F412xG || STM32F413_423xx */ +#if defined(STM32F446xx) +#define GPIO_AF8_SAI2 ((uint8_t)0x08) /* SAI2 Alternate Function mapping */ +#define GPIO_AF_SPDIF ((uint8_t)0x08) /* SPDIF Alternate Function mapping */ +#endif /* STM32F446xx */ + +/** + * @brief AF 9 selection + */ +#define GPIO_AF_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */ +#define GPIO_AF_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */ +#define GPIO_AF_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */ +#define GPIO_AF_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */ +#define GPIO_AF_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ +#define GPIO_AF9_I2C2 ((uint8_t)0x09) /* I2C2 Alternate Function mapping (Only for STM32F401xx/STM32F410xx/STM32F411xE/STM32F412xG/STM32F413_423xx Devices) */ +#define GPIO_AF9_I2C3 ((uint8_t)0x09) /* I2C3 Alternate Function mapping (Only for STM32F401xx/STM32F411xE/STM32F412xG and STM32F413_423xx Devices) */ +#if defined(STM32F446xx) +#define GPIO_AF9_SAI2 ((uint8_t)0x09) /* SAI2 Alternate Function mapping */ +#endif /* STM32F446xx */ +#define GPIO_AF9_LTDC ((uint8_t)0x09) /* LTDC Alternate Function mapping */ +#if defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) || defined(STM32F469_479xx) +#define GPIO_AF9_QUADSPI ((uint8_t)0x09) /* QuadSPI Alternate Function mapping */ +#endif /* STM32F412xG || STM32F413_423xx || STM32F446xx || STM32F469_479xx */ +#if defined(STM32F410xx) || defined(STM32F412xG) || defined(STM32F413_423xx) +#define GPIO_AF9_FMPI2C ((uint8_t)0x09) /* FMPI2C Alternate Function mapping (Only for STM32F410xx Devices) */ +#endif /* STM32F410xx || STM32F412xG || STM32F413_423xx */ + +/** + * @brief AF 10 selection + */ +#define GPIO_AF_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ +#define GPIO_AF_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */ +#if defined(STM32F446xx) +#define GPIO_AF10_SAI2 ((uint8_t)0x0A) /* SAI2 Alternate Function mapping */ +#endif /* STM32F446xx */ +#if defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) || defined(STM32F469_479xx) +#define GPIO_AF10_QUADSPI ((uint8_t)0x0A) /* QuadSPI Alternate Function mapping */ +#endif /* STM32F412xG || STM32F413_423xx || STM32F446xx || STM32F469_479xx */ +#if defined(STM32F412xG) || defined(STM32F413_423xx) +#define GPIO_AF10_FMC ((uint8_t)0xA) /* FMC Alternate Function mapping */ +#define GPIO_AF10_DFSDM1 ((uint8_t)0xA) /* DFSDM Alternate Function mapping */ +#endif /* STM32F412xG || STM32F413_423xx */ +#if defined(STM32F413_423xx) +#define GPIO_AF10_DFSDM2 ((uint8_t)0x0A) /* DFSDM2 Alternate Function mapping */ +#define GPIO_AF10_SAI1 ((uint8_t)0x0A) /* SAI1 Alternate Function mapping */ +#endif /* STM32F413_423xx */ +/** + * @brief AF 11 selection + */ +#define GPIO_AF_ETH ((uint8_t)0x0B) /* ETHERNET Alternate Function mapping */ +#if defined(STM32F413_423xx) +#define GPIO_AF11_UART4 ((uint8_t)0x0B) /* UART4 Alternate Function mapping */ +#define GPIO_AF11_UART5 ((uint8_t)0x0B) /* UART5 Alternate Function mapping */ +#define GPIO_AF11_UART9 ((uint8_t)0x0B) /* UART9 Alternate Function mapping */ +#define GPIO_AF11_UART10 ((uint8_t)0x0B) /* UART10 Alternate Function mapping */ +#define GPIO_AF11_CAN3 ((uint8_t)0x0B) /* CAN3 Alternate Function mapping */ +#endif /* STM32F413_423xx */ + +/** + * @brief AF 12 selection + */ +#if defined(STM32F40_41xxx) || defined(STM32F412xG) || defined(STM32F413_423xx) +#define GPIO_AF_FSMC ((uint8_t)0xC) /* FSMC Alternate Function mapping */ +#endif /* STM32F40_41xxx || STM32F412xG || STM32F413_423xx */ + +#if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx) +#define GPIO_AF_FMC ((uint8_t)0xC) /* FMC Alternate Function mapping */ +#endif /* STM32F427_437xx || STM32F429_439xx || STM32F446xx || STM32F469_479xx */ + +#define GPIO_AF_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */ +#define GPIO_AF_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */ + +/** + * @brief AF 13 selection + */ +#define GPIO_AF_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */ +#if defined(STM32F469_479xx) +#define GPIO_AF_DSI ((uint8_t)0x0D) /* DSI Alternate Function mapping */ +#endif /* STM32F469_479xx */ +/** + * @brief AF 14 selection + */ +#define GPIO_AF_LTDC ((uint8_t)0x0E) /* LCD-TFT Alternate Function mapping */ +#if defined(STM32F413_423xx) +#define GPIO_AF14_RNG ((uint8_t)0x0E) /* RNG Alternate Function mapping */ +#endif /* STM32F413_423xx */ + +/** + * @brief AF 15 selection + */ +#define GPIO_AF_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ + +#if defined(STM32F40_41xxx) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ + ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ + ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ + ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ + ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ + ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ + ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ + ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ + ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ + ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ + ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ + ((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \ + ((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \ + ((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \ + ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ + ((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_OTG_HS_FS) || \ + ((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_DCMI) || \ + ((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_FSMC)) +#endif /* STM32F40_41xxx */ + +#if defined(STM32F401xx) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ + ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ + ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ + ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ + ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ + ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ + ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ + ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ + ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ + ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ + ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ + ((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_USART6) || \ + ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ + ((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_SPI4)) +#endif /* STM32F401xx */ + +#if defined(STM32F411xE) +#define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 13) && ((AF) != 14)) +#endif /* STM32F411xE */ + +#if defined(STM32F410xx) +#define IS_GPIO_AF(AF) (((AF) < 10) || ((AF) == 15)) +#endif /* STM32F410xx */ + +#if defined(STM32F427_437xx) || defined(STM32F429_439xx) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ + ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ + ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ + ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ + ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ + ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ + ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ + ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ + ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ + ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ + ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ + ((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \ + ((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \ + ((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \ + ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ + ((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_OTG_HS_FS) || \ + ((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_DCMI) || \ + ((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_SPI4) || \ + ((AF) == GPIO_AF_SPI5) || ((AF) == GPIO_AF_SPI6) || \ + ((AF) == GPIO_AF_UART7) || ((AF) == GPIO_AF_UART8) || \ + ((AF) == GPIO_AF_FMC) || ((AF) == GPIO_AF_SAI1) || \ + ((AF) == GPIO_AF_LTDC)) +#endif /* STM32F427_437xx || STM32F429_439xx */ + +#if defined(STM32F412xG) +#define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 14)) +#endif /* STM32F412xG */ + +#if defined(STM32F413_423xx) +#define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 13)) +#endif /* STM32F413_423xx */ + +#if defined(STM32F446xx) +#define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 14)) +#endif /* STM32F446xx */ + +#if defined(STM32F469_479xx) +#define IS_GPIO_AF(AF) ((AF) < 16) +#endif /* STM32F469_479xx */ + +/** + * @} + */ + +/** @defgroup GPIO_Legacy + * @{ + */ -// #define GPIO_Mode_AIN GPIO_Mode_AN +#define GPIO_Mode_AIN GPIO_Mode_AN + +#define GPIO_AF_OTG1_FS GPIO_AF_OTG_FS +#define GPIO_AF_OTG2_HS GPIO_AF_OTG_HS +#define GPIO_AF_OTG2_FS GPIO_AF_OTG_HS_FS -// #define GPIO_AF_OTG1_FS GPIO_AF_OTG_FS -// #define GPIO_AF_OTG2_HS GPIO_AF_OTG_HS -// #define GPIO_AF_OTG2_FS GPIO_AF_OTG_HS_FS +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/* Function used to set the GPIO configuration to the default reset state ****/ +DECLARE_FAKE_VOID_FUNC(GPIO_DeInit, GPIO_TypeDef*); + +/* Initialization and Configuration functions *********************************/ +DECLARE_FAKE_VOID_FUNC(GPIO_Init, GPIO_TypeDef*, GPIO_InitTypeDef*); + +DECLARE_FAKE_VOID_FUNC(GPIO_StructInit, GPIO_InitTypeDef*); + +DECLARE_FAKE_VOID_FUNC(GPIO_PinLockConfig, GPIO_TypeDef*, uint16_t); -// /** -// * @} -// */ +/* GPIO Read and Write functions **********************************************/ +DECLARE_FAKE_VALUE_FUNC(uint8_t, GPIO_ReadInputDataBit, GPIO_TypeDef*, uint16_t); -// /** -// * @} -// */ +DECLARE_FAKE_VALUE_FUNC(uint16_t, GPIO_ReadInputData, GPIO_TypeDef*); -// /* Exported macro ------------------------------------------------------------*/ -// /* Exported functions --------------------------------------------------------*/ +DECLARE_FAKE_VALUE_FUNC(uint8_t, GPIO_ReadOutputDataBit, GPIO_TypeDef*, uint16_t); -// /* Function used to set the GPIO configuration to the default reset state ****/ -// void GPIO_DeInit(GPIO_TypeDef* GPIOx); +DECLARE_FAKE_VALUE_FUNC(uint16_t, GPIO_ReadOutputData, GPIO_TypeDef*); -// /* Initialization and Configuration functions *********************************/ -// void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); -// void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); -// void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +DECLARE_FAKE_VOID_FUNC(GPIO_SetBits, GPIO_TypeDef*, uint16_t); -// /* GPIO Read and Write functions **********************************************/ -// uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -// uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); -// uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -// uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); -// void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -// void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); -// void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); -// void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); -// void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +DECLARE_FAKE_VOID_FUNC(GPIO_ResetBits, GPIO_TypeDef*, uint16_t); -// /* GPIO Alternate functions configuration function ****************************/ -// void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF); +DECLARE_FAKE_VOID_FUNC(GPIO_WriteBit, GPIO_TypeDef*, uint16_t, BitAction); -// #ifdef __cplusplus -// } -// #endif +DECLARE_FAKE_VOID_FUNC(GPIO_Write, GPIO_TypeDef*, uint16_t); + +DECLARE_FAKE_VOID_FUNC(GPIO_ToggleBits, GPIO_TypeDef*, uint16_t); + +/* GPIO Alternate functions configuration function ****************************/ +DECLARE_FAKE_VOID_FUNC(GPIO_PinAFConfig, GPIO_TypeDef*, uint16_t, uint8_t); + +#ifdef __cplusplus +} +#endif #endif /*__STM32F4xx_GPIO_H */ -// /** -// * @} -// */ +/** + * @} + */ -// /** -// * @} -// */ +/** + * @} + */ -// /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Tests/UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c b/Tests/UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c new file mode 100644 index 000000000..c05086049 --- /dev/null +++ b/Tests/UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c @@ -0,0 +1,34 @@ +////////Mock + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_gpio.h" + +//#include "stm32f4xx_rcc.h" + +DEFINE_FAKE_VOID_FUNC(GPIO_DeInit, GPIO_TypeDef*); + +DEFINE_FAKE_VOID_FUNC(GPIO_Init, GPIO_TypeDef*, GPIO_InitTypeDef*); + +DEFINE_FAKE_VOID_FUNC(GPIO_StructInit, GPIO_InitTypeDef*); + +DEFINE_FAKE_VOID_FUNC(GPIO_PinLockConfig, GPIO_TypeDef*, uint16_t); + +DEFINE_FAKE_VALUE_FUNC(uint8_t, GPIO_ReadInputDataBit, GPIO_TypeDef*, uint16_t); + +DEFINE_FAKE_VALUE_FUNC(uint16_t, GPIO_ReadInputData, GPIO_TypeDef*); + +DEFINE_FAKE_VALUE_FUNC(uint8_t, GPIO_ReadOutputDataBit, GPIO_TypeDef*, uint16_t); + +DEFINE_FAKE_VALUE_FUNC(uint16_t, GPIO_ReadOutputData, GPIO_TypeDef*); + +DEFINE_FAKE_VOID_FUNC(GPIO_SetBits, GPIO_TypeDef*, uint16_t); + +DEFINE_FAKE_VOID_FUNC(GPIO_ResetBits, GPIO_TypeDef*, uint16_t); + +DEFINE_FAKE_VOID_FUNC(GPIO_WriteBit, GPIO_TypeDef*, uint16_t, BitAction); + +DEFINE_FAKE_VOID_FUNC(GPIO_Write, GPIO_TypeDef*, uint16_t); + +DEFINE_FAKE_VOID_FUNC(GPIO_ToggleBits, GPIO_TypeDef*, uint16_t); + +DEFINE_FAKE_VOID_FUNC(GPIO_PinAFConfig, GPIO_TypeDef*, uint16_t, uint8_t); \ No newline at end of file From 13265b3765beccebc7684788bc7a2aaeb8c0ceb9 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Thu, 18 Jan 2024 14:55:44 -0600 Subject: [PATCH 23/57] Cleaning up unneeded file changes to decrease the size of the PR. --- Apps/Inc/ReadCarCAN.h | 2 - Apps/Inc/Tasks.h | 1 + Apps/Src/ReadCarCAN.c | 9 +- Apps/Src/Tasks.c | 19 ++- BSP/Inc/BSP_ADC.h | 13 +- BSP/Inc/BSP_GPIO.h | 15 --- BSP/STM32F413/Makefile | 10 +- BSP/STM32F413/Src/BSP_ADC.c | 9 -- BSP/STM32F413/Src/BSP_GPIO.c | 17 +-- Drivers/Inc/Contactors.h | 2 + Drivers/Src/Contactors.c | 19 ++- Drivers/Src/Pedals.c | 3 +- Tests/Test_ReadCarCANrewrite.c | 1 - Tests/UnitTests/theMakefilecopyof | 216 ------------------------------ 14 files changed, 38 insertions(+), 298 deletions(-) delete mode 100644 Tests/UnitTests/theMakefilecopyof diff --git a/Apps/Inc/ReadCarCAN.h b/Apps/Inc/ReadCarCAN.h index 8a2519352..f06e888d2 100644 --- a/Apps/Inc/ReadCarCAN.h +++ b/Apps/Inc/ReadCarCAN.h @@ -13,8 +13,6 @@ #include "common.h" #include "CANbus.h" -#include "Tasks.h" -#include "Minions.h" /** * Error types diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 36b1b99a0..2c1d00eca 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -8,6 +8,7 @@ * @{ */ + #ifndef __TASKS_H #define __TASKS_H diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index d625ee6da..9a4b70068 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -11,7 +11,6 @@ #include "Minions.h" #include "os.h" #include "os_cfg_app.h" -#include "Tasks.h" #include "Display.h" // Length of the array and motor PBC saturation buffers @@ -330,8 +329,8 @@ void Task_ReadCarCAN(void *p_arg){ assertOSError(err); // Start CAN Watchdog timer - OSTmrStart(&canWatchTimer, &err); - assertOSError(err); + OSTmrStart(&canWatchTimer, &err); + assertOSError(err); // Fills buffers with disable messages // NOTE: If the buffer becomes bigger than of type int8_t, memset will not work and @@ -357,8 +356,8 @@ void Task_ReadCarCAN(void *p_arg){ } case BPS_CONTACTOR: { - OSTmrStart(&canWatchTimer, &err); // Restart CAN Watchdog timer for BPS Contactor msg - assertOSError(err); + OSTmrStart(&canWatchTimer, &err); // Restart CAN Watchdog timer for BPS Contactor msg + assertOSError(err); // Retrieving HV contactor statuses using bit mapping // Bitwise to get HV Plus and Minus, and then &&ing to ensure both are on diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 222b00b7c..af6382e1d 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -1,4 +1,3 @@ - /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file Tasks.c @@ -104,17 +103,17 @@ void throwTaskError(error_code_t errorCode, callback_t errorCallback, error_sche #if DEBUG == 1 // Print the error that caused this fault - printf("\n\rCurrent Error Code: 0x%04x\n\r", errorCode); + // printf("\n\rCurrent Error Code: 0x%04x\n\r", errorCode); - // Print the errors for each applications with error data - printf("\n\rAll application errors:\n\r"); - printf("Error_ReadCarCAN: 0x%04x\n\r", Error_ReadCarCAN); - printf("Error_ReadTritium: 0x%04x\n\r", Error_ReadTritium); - printf("Error_UpdateDisplay: 0x%04x\n\r", Error_UpdateDisplay); + // // Print the errors for each applications with error data + // printf("\n\rAll application errors:\n\r"); + // printf("Error_ReadCarCAN: 0x%04x\n\r", Error_ReadCarCAN); + // printf("Error_ReadTritium: 0x%04x\n\r", Error_ReadTritium); + // printf("Error_UpdateDisplay: 0x%04x\n\r", Error_UpdateDisplay); - // Delay so that we're not constantly printing - for (int i = 0; i < 9999999; i++) { - } + // // Delay so that we're not constantly printing + // for (int i = 0; i < 9999999; i++) { + // } #endif } diff --git a/BSP/Inc/BSP_ADC.h b/BSP/Inc/BSP_ADC.h index 9b133b299..33ccd47b4 100644 --- a/BSP/Inc/BSP_ADC.h +++ b/BSP/Inc/BSP_ADC.h @@ -11,9 +11,7 @@ #ifndef __BSP_ADC_H #define __BSP_ADC_H -#define MOCK_BSP_ADC -#ifndef MOCK_BSP_ADC -#endif + #include "bsp.h" #include "common.h" #include "config.h" @@ -29,13 +27,6 @@ typedef enum NUMBER_OF_CHANNELS } ADC_t; -#ifdef MOCKING -#include "fff.h" -DECLARE_FAKE_VOID_FUNC(BSP_ADC_Init); -DECLARE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Millivoltage, int); -DECLARE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Value, int); -#else - /** * @brief Initialize the ADC module * @return None @@ -57,6 +48,6 @@ int16_t BSP_ADC_Get_Value(ADC_t hardwareDevice); int16_t BSP_ADC_Get_Millivoltage(ADC_t hardwareDevice); #endif -#endif + /* @} */ diff --git a/BSP/Inc/BSP_GPIO.h b/BSP/Inc/BSP_GPIO.h index 5167b64f4..66db068c4 100644 --- a/BSP/Inc/BSP_GPIO.h +++ b/BSP/Inc/BSP_GPIO.h @@ -13,28 +13,14 @@ #define __BSP_GPIO_H #include "common.h" -#ifdef MOCKING -#include "fff.h" -#else #include "config.h" #include "stm32f4xx_gpio.h" #include #include -#endif typedef enum {PORTA = 0, PORTB, PORTC, PORTD, NUM_PORTS} port_t; typedef enum {INPUT = 0, OUTPUT} direction_t; -#ifdef MOCKING -DECLARE_FAKE_VOID_FUNC(BSP_GPIO_Write_Pin, port_t, uint16_t, bool); -DECLARE_FAKE_VOID_FUNC(BSP_GPIO_Init, port_t, uint16_t, direction_t); -//FAKE_VOID_FUNC3(OSMutexCreate, struct os_mutex, CPU_CHAR, OS_ERR); -DECLARE_FAKE_VALUE_FUNC(uint8_t,BSP_GPIO_Get_State, port_t, uint16_t ); -//FAKE_VOID_FUNC5(OSMutexPend, OS_MUTEX, OS_TICK, OS_OPT, CPU_TS, OS_ERR); -//FAKE_VOID_FUNC3(OSMutexPost, OS_MUTEX, OS_OPT, OS_ERR); -DECLARE_FAKE_VOID_FUNC(assertOSError, int); -#else - /** * @brief Initializes a GPIO port * @param port - port to initialize @@ -85,7 +71,6 @@ void BSP_GPIO_Write_Pin(port_t port, uint16_t pinmask, bool state); uint8_t BSP_GPIO_Get_State(port_t port, uint16_t pin); #endif -#endif /* @} */ diff --git a/BSP/STM32F413/Makefile b/BSP/STM32F413/Makefile index 0f26a319e..bfc0a49b9 100644 --- a/BSP/STM32F413/Makefile +++ b/BSP/STM32F413/Makefile @@ -41,6 +41,11 @@ C_SOURCES += \ $(filter-out ../../Apps/Src/main.c, $(wildcard ../../Apps/Src/*.c)) \ ../../$(TEST) +# ASM sources +ASM_SOURCES = \ +../../BSP/STM32F413/Src/startup_stm32f413xx.s \ +../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/os_cpu_a.s \ +../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/cpu_a.s ####################################### @@ -72,7 +77,7 @@ SF = st-flash CPU = -mcpu=cortex-m4 # float-abi -FLOAT-ABI = -mfloat-abi=soft +FLOAT-ABI = -mfloat-abi=hard # mcu MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) @@ -150,6 +155,9 @@ all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET # list of objects OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) vpath %.c $(sort $(dir $(C_SOURCES))) +# list of ASM program objects +OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) +vpath %.s $(sort $(dir $(ASM_SOURCES))) $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) @echo "CC $(<:../../%=%)" diff --git a/BSP/STM32F413/Src/BSP_ADC.c b/BSP/STM32F413/Src/BSP_ADC.c index 1972ae111..f49dac17b 100644 --- a/BSP/STM32F413/Src/BSP_ADC.c +++ b/BSP/STM32F413/Src/BSP_ADC.c @@ -3,12 +3,6 @@ #include "BSP_ADC.h" #include "stm32f4xx.h" - - -#ifdef MOCKING - -#else - static volatile uint16_t ADCresults[2]; static void ADC_InitDMA(void) { @@ -119,6 +113,3 @@ int16_t BSP_ADC_Get_Millivoltage(ADC_t hardwareDevice) { // Convert to millivoltage return (ADC_RANGE_MILLIVOLTS * data) >> ADC_PRECISION_BITS; } - - -#endif \ No newline at end of file diff --git a/BSP/STM32F413/Src/BSP_GPIO.c b/BSP/STM32F413/Src/BSP_GPIO.c index bcbbb3338..ffd20a800 100755 --- a/BSP/STM32F413/Src/BSP_GPIO.c +++ b/BSP/STM32F413/Src/BSP_GPIO.c @@ -1,21 +1,7 @@ /* Copyright (c) 2021 UT Longhorn Racing Solar */ #include "BSP_GPIO.h" -//#include "Tasks.h" - -#ifdef MOCKING -#include "fff.h" -DEFINE_FFF_GLOBALS; -DEFINE_FAKE_VOID_FUNC(BSP_GPIO_Write_Pin, port_t, uint16_t, bool); -DEFINE_FAKE_VOID_FUNC(BSP_GPIO_Init, port_t, uint16_t, direction_t); -//FAKE_VOID_FUNC3(OSMutexCreate, struct os_mutex, CPU_CHAR, OS_ERR); -DEFINE_FAKE_VALUE_FUNC(uint8_t,BSP_GPIO_Get_State, port_t, uint16_t ); -//FAKE_VOID_FUNC5(OSMutexPend, OS_MUTEX, OS_TICK, OS_OPT, CPU_TS, OS_ERR); -//FAKE_VOID_FUNC3(OSMutexPost, OS_MUTEX, OS_OPT, OS_ERR); -DEFINE_FAKE_VOID_FUNC(assertOSError, int); -#else - - +#include "Tasks.h" static GPIO_TypeDef* GPIO_GetPort(port_t port){ const GPIO_TypeDef* gpio_mapping[4] = {GPIOA, GPIOB, GPIOC, GPIOD}; @@ -122,4 +108,3 @@ uint8_t BSP_GPIO_Get_State(port_t port, uint16_t pin){ return GPIO_ReadOutputDataBit(gpio_port, pin); } -#endif \ No newline at end of file diff --git a/Drivers/Inc/Contactors.h b/Drivers/Inc/Contactors.h index 7ccaaabef..77cf7ec15 100644 --- a/Drivers/Inc/Contactors.h +++ b/Drivers/Inc/Contactors.h @@ -56,6 +56,8 @@ bool Contactors_Get(contactor_t contactor); * @return Whether or not the contactor was successfully set */ ErrorStatus Contactors_Set(contactor_t contactor, bool state, bool blocking); + #endif + /* @} */ diff --git a/Drivers/Src/Contactors.c b/Drivers/Src/Contactors.c index 370eaece5..66ec45e0f 100644 --- a/Drivers/Src/Contactors.c +++ b/Drivers/Src/Contactors.c @@ -6,9 +6,8 @@ */ #include "Contactors.h" +#include "stm32f4xx_gpio.h" #include "Tasks.h" -#include "os.h" - static OS_MUTEX contactorsMutex; @@ -49,10 +48,10 @@ void Contactors_Init() { setContactor(contactor, OFF); } - //initialize mutex + // initialize mutex OS_ERR err; OSMutexCreate(&contactorsMutex, "Contactors lock", &err); - assertOSError(err); + assertOSError(err); } /** @@ -95,18 +94,18 @@ ErrorStatus Contactors_Set(contactor_t contactor, bool state, bool blocking) { OSMutexPend(&contactorsMutex, 0, blocking ? OS_OPT_PEND_BLOCKING : OS_OPT_PEND_NON_BLOCKING, ×tamp, &err); if(err == OS_ERR_PEND_WOULD_BLOCK){ - return ERROR; - } - assertOSError(err); + return ERROR; + } + assertOSError(err); // change contactor to match state and make sure it worked setContactor(contactor, state); bool ret = (bool)Contactors_Get(contactor); result = (ret == state) ? SUCCESS: ERROR; - //release lock - OSMutexPost(&contactorsMutex, OS_OPT_POST_NONE, &err); - assertOSError(err); + // release lock + OSMutexPost(&contactorsMutex, OS_OPT_POST_NONE, &err); + assertOSError(err); return result; } diff --git a/Drivers/Src/Pedals.c b/Drivers/Src/Pedals.c index bab2e0e58..e28397fdf 100755 --- a/Drivers/Src/Pedals.c +++ b/Drivers/Src/Pedals.c @@ -6,11 +6,10 @@ */ #include "Pedals.h" -#include "BSP_ADC.h" + // Constants used to tune the pedals // Indexed using pedal_t // Refine in testing - static const int16_t LowerBound[NUMBER_OF_PEDALS] = { 400, // Accelerator lower bound 2100, // Brake lower bound diff --git a/Tests/Test_ReadCarCANrewrite.c b/Tests/Test_ReadCarCANrewrite.c index 07d8af11d..8ce93c952 100644 --- a/Tests/Test_ReadCarCANrewrite.c +++ b/Tests/Test_ReadCarCANrewrite.c @@ -42,7 +42,6 @@ enum { SEND_UNTIL_MOTOR_CONT_ON }; - /*** Constants ***/ #define SATURATION_THRESHOLD_TEST (((SAT_BUF_LENGTH + 1) * SAT_BUF_LENGTH) / 4) diff --git a/Tests/UnitTests/theMakefilecopyof b/Tests/UnitTests/theMakefilecopyof deleted file mode 100644 index 65ee0bf45..000000000 --- a/Tests/UnitTests/theMakefilecopyof +++ /dev/null @@ -1,216 +0,0 @@ -###################################### -# target -###################################### -TARGET = controls-leader - - -###################################### -# building variables -###################################### -# optimization -ifeq ($(DEBUG), 0) -OPT = -O3 -else -OPT = -Og -g3 -endif - -####################################### -# paths -####################################### -# Build path -BUILD_DIR = Objects#../../Objects - -###################################### -# source -###################################### -# C sources -# since current path is in the BSP folder, go to the top level with ../../ -# C_SOURCES = \ commented out! -# $(wildcard ../../Drivers/Src/*.c) \ -# $(wildcard ../../BSP/STM32F413/Src/*.c) \ -# $(wildcard ../../BSP/STM32F413/STM32F4xx_StdPeriph_Driver/Src/*.c) \ -# $(wildcard ../../CMSIS/DSP_Lib/Source/*.c) \ -# $(wildcard ../../RTOS/uCOS-III-STM32F4/uCOS-III/Source/*.c) \ -# $(wildcard ../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/*.c) \ -# $(wildcard ../../RTOS/uCOS-III-STM32F4/uC-CPU/*.c) \ -# $(wildcard ../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/*.c) \ -# $(wildcard ../../RTOS/uCOS-III-STM32F4/uC-LIB/*.c) - -# This line adds everything in Apps/Src/*.c except for main.c, then adds the test file -#C_SOURCES += \ -$(filter-out ../../Apps/Src/main.c, $(wildcard ../../Apps/Src/*.c)) \ -../../$(TEST) - -# changed to -C_SOURCES = \ -../$(TEST) - -# ASM sources -# ASM_SOURCES = \ commented out!## -# ../../BSP/STM32F413/Src/startup_stm32f413xx.s \ -# ../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/os_cpu_a.s \ -# ../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/cpu_a.s - - -####################################### -# binaries -####################################### -PREFIX = #arm-none-eabi- not this time! ## -# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) -# or it can be added to the PATH environment variable. -ifdef GCC_PATH -CC = $(GCC_PATH)/$(PREFIX)gcc -AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp -CP = $(GCC_PATH)/$(PREFIX)objcopy -SZ = $(GCC_PATH)/$(PREFIX)size -else -CC = $(PREFIX)gcc -AS = $(PREFIX)gcc -x assembler-with-cpp -CP = $(PREFIX)objcopy -SZ = $(PREFIX)size -endif -HEX = $(CP) -O ihex -BIN = $(CP) -O binary -S - -SF = st-flash - -####################################### -# CFLAGS -####################################### -# cpu -#CPU = -mcpu=cortex-m4 commented out## - -# float-abi -#FLOAT-ABI = -mfloat-abi=soft co## - -# mcu -#MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) co## - -# macros for gcc -# AS defines -#AS_DEFS = co## - -# C defines -# C_DEFS = \ co## -# -DSTM32F413_423xx \ -# -DUSE_STDPERIPH_DRIVER \ -# -D__FPU_PRESENT - - -# AS includes -#AS_INCLUDES = #co - -# C includes -# since current path is in the BSP folder, go to the top level with ../../ -#C_INCLUDES = \ #not sure if we need this...? - #-I../../Apps/Inc \ --I../../Drivers/Inc \ --I../../Config/Inc \ --I../../BSP/Inc \ --I../../CMSIS/Device/ST/STM32F4xx/Include \ --I../../CMSIS/Include \ --I../../BSP/STM32F413/STM32F4xx_StdPeriph_Driver/Inc \ --I../../RTOS/uCOS-III-STM32F4/uCOS-III/Source/ \ --I../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/ \ --I../../RTOS/uCOS-III-STM32F4/uC-CPU/ \ --I../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/ \ --I../../RTOS/uCOS-III-STM32F4/uC-LIB/ \ --I../../Tests/Inc/ \ - -# compile gcc flags -# ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections commented out - -CFLAGS = $(C_INCLUDES) -Wall -Werror -fdata-sections -ffunction-sections#$(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -Werror -fdata-sections -ffunction-sections - -ifeq ($(DEBUG), 1) -CFLAGS += -g3 -gdwarf-2 -DDEBUG -endif - -ifeq ($(MOTOR_LOOPBACK), 1) -CFLAGS += -DMOTOR_LOOPBACK -endif - -ifeq ($(CAR_LOOPBACK), 1) -CFLAGS += -DCAR_LOOPBACK -endif - -# Generate dependency information -CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" - - -####################################### -# LDFLAGS -####################################### -# link script -#LDSCRIPT = ./GCC/STM32F413RHTx_FLASH.ld #co### - -# libraries -LIBS = -lc -lm -lnosys -LIBDIR = -#LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections co## - -# default action: build all -all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin $(BUILD_DIR)/$(TARGET).o - - -####################################### -# build the application -####################################### -# list of objects -OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) -vpath %.c $(sort $(dir $(C_SOURCES))) -# list of ASM program objects -OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) -vpath %.s $(sort $(dir $(ASM_SOURCES))) - -$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) - @echo "CC $(<:../../%=%)" - @$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ - -$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) - @echo "AS $(<:../../%=%)" - @$(AS) -c $(CFLAGS) $< -o $@ - -$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile - @echo "LD $(<:../../%=%)" - @$(CC) $(OBJECTS) $(LDFLAGS) -o $@ - @echo "SZ $(<:../../%=%)" - @$(SZ) $@ - -#added -$(BUILD_DIR)/$(TARGET).o: $(OBJECTS) Makefile - @echo "LD $(<:../../%=%)" - @$(CC) $(OBJECTS) $(LDFLAGS) -o $@ - @echo "SZ $(<:../../%=%)" - @$(SZ) $@ -#end add - -$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) - @echo "HEX $(<:../../%=%)" - @$(HEX) $< $@ - -$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) - @echo "BIN $(<:../../%=%)" - @$(BIN) $< $@ - -$(BUILD_DIR): - mkdir $@ - -####################################### -# clean up -####################################### -clean: - -rm -fR $(BUILD_DIR) - -####################################### -# flash -####################################### -flash: - $(SF) write $(BUILD_DIR)/$(TARGET).bin 0x8000000 - -####################################### -# dependencies -####################################### --include $(wildcard $(BUILD_DIR)/*.d) - -# *** EOF *** From 0d89370230b8cb52cd67a44bc0a9df5156210df8 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Fri, 19 Jan 2024 19:19:07 -0600 Subject: [PATCH 24/57] Cleaned up files a bit / added MOCK to mock files because I am easily confused / Added a filter to the unit test makefile to ensure we find the correct real source file to test and not accidentally a mock one. --- Apps/Src/ReadCarCAN.c | 2 +- Drivers/Inc/Pedals.h | 6 +- Makefile | 10 +- Tests/UnitTests/Makefile | 84 ++----- Tests/UnitTests/MakefileBSPAnnotated | 209 ++++++++++++++++++ Tests/UnitTests/Mocks/Apps/Inc/Tasks.h | 74 ++----- .../UnitTests/Mocks/Apps/Inc/UpdateDisplay.h | 8 +- Tests/UnitTests/Mocks/Apps/Src/Tasks.c | 54 ++--- .../UnitTests/Mocks/Apps/Src/UpdateDisplay.c | 3 + Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h | 3 + Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h | 16 +- Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h | 4 + Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c | 6 + Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c | 21 +- .../UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c | 7 +- Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h | 19 +- .../UnitTests/Mocks/Drivers/Inc/Contactors.h | 4 + Tests/UnitTests/Mocks/Drivers/Inc/Minions.h | 14 +- .../UnitTests/Mocks/Drivers/Src/Contactors.c | 6 + Tests/UnitTests/Mocks/Drivers/Src/Display.c | 12 +- Tests/UnitTests/Mocks/Drivers/Src/Minions.c | 4 + Tests/UnitTests/Mocks/RTOS/cpu.h | 4 + Tests/UnitTests/Mocks/RTOS/cpu_cfg.h | 4 + Tests/UnitTests/Mocks/RTOS/cpu_core.h | 4 + Tests/UnitTests/Mocks/RTOS/cpu_def.h | 4 + Tests/UnitTests/Mocks/RTOS/lib_def.h | 4 + Tests/UnitTests/Mocks/RTOS/os.c | 4 + Tests/UnitTests/Mocks/RTOS/os.h | 8 +- Tests/UnitTests/Mocks/RTOS/os_cfg.h | 4 + Tests/UnitTests/Mocks/RTOS/os_type.h | 4 + 30 files changed, 392 insertions(+), 214 deletions(-) create mode 100644 Tests/UnitTests/MakefileBSPAnnotated diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index fe8c7b0e0..d2bc4e6b8 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -131,7 +131,7 @@ static void disableArrayPrechargeBypassContactor(void){ * @param None */ static void updateArrayPrechargeBypassContactor(void){ - OS_ERR err = OS_ERR_NONE; + OS_ERR err = OS_ERR_NONE; if((arrIgnStatus || mcIgnStatus) // Ignition is ON && HVArrayMsgSaturation >= ARRAY_SATURATION_THRESHOLD // Saturation Threshold has be met && (Contactors_Get(ARRAY_PRECHARGE_BYPASS_CONTACTOR) == OFF) diff --git a/Drivers/Inc/Pedals.h b/Drivers/Inc/Pedals.h index 4363d8053..aa76d5590 100644 --- a/Drivers/Inc/Pedals.h +++ b/Drivers/Inc/Pedals.h @@ -11,8 +11,6 @@ #ifndef __PEDALS_H #define __PEDALS_H -#include -#include #include "BSP_ADC.h" /** @@ -31,14 +29,14 @@ typedef enum * @param None * @return None */ - void Pedals_Init(void); +void Pedals_Init(void); /** * @brief Provides the pedal distance pressed in percetage (accelerator or brake) * @param pedal_t pedal, ACCELERATOR or BRAKE as defined in enum * @return distance the pedal has been pressed in percentage */ - int8_t Pedals_Read(pedal_t pedal); +int8_t Pedals_Read(pedal_t pedal); #endif diff --git a/Makefile b/Makefile index 6a3a07176..7d5bfa4f3 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ else TEST_LEADER ?= Apps/Src/main.c endif -#Check if unit test file exists (and yes we don't use unittest right now but maybe we will in the future) +#Check if unit test file exists (just to inform user if it isn't found) ifneq (,$(wildcard Tests/UnitTests/Test_$(TEST).c)) UNITTEST ?= Tests/UnitTests/Test_$(TEST).c else @@ -43,7 +43,7 @@ stm32f413: @echo "${YELLOW}Compiling for leader...${NC}" $(MAKE) -C BSP -C STM32F413 -j TARGET=$(LEADER) TEST=$(TEST_LEADER) @echo "${BLUE}Compiled for leader! Jolly Good!${NC}" - #TEST - need to add .c somehow, also no longer TEST_LEADER but we may want to check that there's a valid file first + unittest: @echo "${YELLOW}Compiling unit test...${NC}" @echo "$(UNITTEST)" @@ -69,13 +69,9 @@ help: @echo " excluding the file type (.c) e.g. say you want to test Voltage.c, call" @echo " ${ORANGE}make ${BLUE}stm32f413 ${ORANGE}TEST=${PURPLE}Voltage${NC}" -unitclean: - clean: rm -fR Tests/UnitTests/Objects rm -fR Objects rm -f *.out - rm -fr Docs/doxygen - rm -fr Docs/build - \ No newline at end of file + rm -fr Docs/doxygen \ No newline at end of file diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index eac3ec3de..7a7d8e0fc 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -11,17 +11,17 @@ YELLOW=\033[0;33m NC=\033[0m # No Color # Build path -BUILD_DIR = Objects#../../Objects +BUILD_DIR = Objects ###################################### # source -# C sources changed to -# Need to include test, unity, source file for the test, mock c functions minus source file for test +# C sources +# Need to include test, unity, real source file for the test, mock c functions minus source file for test C_SOURCES = \ Tests/Test_$(TEST).c \ Unity/unity.c \ -$(wildcard ../../*/Src/$(TEST).c) \ +$(filter-out $(wildcard ../../Tests/*/Src/$(TEST).c), $(wildcard ../../*/Src/$(TEST).c)) \ $(wildcard Mocks/RTOS/os.c) \ $(filter-out $(wildcard Mocks/*/Src/$(TEST).c), $(wildcard Mocks/*/Src/*.c)) @@ -29,19 +29,14 @@ $(filter-out $(wildcard Mocks/*/Src/$(TEST).c), $(wildcard Mocks/*/Src/*.c)) $(foreach src,$(C_SOURCES),$(info --- $(src))) -#$(wildcard Stubs/*.c) -#echo "$(C_SOURCE) is c source" - ####################################### # binaries ####################################### -PREFIX = #arm-none-eabi- not this time! ## -# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) -# or it can be added to the PATH environment variable. -CC = $(PREFIX)gcc -AS = $(PREFIX)gcc -x assembler-with-cpp -CP = $(PREFIX)objcopy -SZ = $(PREFIX)size + +CC = gcc +AS = gcc -x assembler-with-cpp +CP = objcopy +SZ = size HEX = $(CP) -O ihex BIN = $(CP) -O binary -S @@ -49,32 +44,9 @@ BIN = $(CP) -O binary -S SF = st-flash ####################################### -# CFLAGS +# C_INCLUDES ####################################### -# cpu -#CPU = -mcpu=cortex-m4 commented out## - -# float-abi -#FLOAT-ABI = -mfloat-abi=soft co## - -# mcu -#MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) co## - -# macros for gcc -# AS defines -#AS_DEFS = co## - -# C defines -# C_DEFS = \ co## -# -DSTM32F413_423xx \ -# -DUSE_STDPERIPH_DRIVER \ -# -D__FPU_PRESENT - -# AS includes -#AS_INCLUDES = #co TEST=Pedals -> include Pedals.c and Pedals.h - -#$(filter-out $(wildcard Mocks/*/$(TEST).h), $(wildcard Mocks/*/Inc/*.h)) *Doesn't work since we can only include directories as search paths, not actual files #-iquote: used to stop the compiler from searching the current directory first. Another effect: -Idirs before it are only searched for "" files # Whatever I put after iquote doesn't seem to be found, but putting it in twice works. This will break #include-next, though C_INCLUDES := \ @@ -130,7 +102,7 @@ vpath %.s $(sort $(dir $(ASM_SOURCES))) ## # @$(CC) $(OBJECTS) -o $@ -#added + $(BUILD_DIR)/$(TEST): $(BUILD_DIR) $(C_SOURCES) @echo "LD $(<:../../%=%)" @$(CC) $(CFLAGS) $(C_INCLUDES) $(C_SOURCES) -o $(BUILD_DIR)/Test_$(TEST).out @@ -138,32 +110,6 @@ $(BUILD_DIR)/$(TEST): $(BUILD_DIR) $(C_SOURCES) - ./$(BUILD_DIR)/Test_$(TEST).out -# $(BUILD_DIR)/$(TOCOMPILE).o: $(TOCOMPILE).c Makefile | $(BUILD_DIR) -# @echo "CC $(<:../../%=%)" -# @$(CC) $(C_INCLUDES) -c $(CFLAGS) $< -o $@ -# - ./$(BUILD_DIR)/$(TOCOMPILE).o - -# $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) -# @echo "AS $(<:../../%=%)" -# @$(AS) -c $(CFLAGS) $< -o $@ - -# $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile -# @echo "LD $(<:../../%=%)" -# @$(CC) $(OBJECTS) $(LDFLAGS) -o $@ -# @echo "SZ $(<:../../%=%)" -# @$(SZ) $@ - -# $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) -# @echo "HEX $(<:../../%=%)" -# @$(HEX) $< $@ - -# $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) -# @echo "BIN $(<:../../%=%)" -# @$(BIN) $< $@ - -#end add ^^ use to be @$(SZ) $@ - - $(BUILD_DIR): mkdir $@ @@ -176,12 +122,12 @@ clean: ####################################### # flash ####################################### -flash: - $(SF) write $(BUILD_DIR)/$(TARGET).bin 0x8000000 - +#flash: +# $(SF) write $(BUILD_DIR)/$(TARGET).bin 0x8000000 +# unsure if this works or if we would ever use it ####################################### # dependencies ####################################### -include $(wildcard $(BUILD_DIR)/*.d) - +#don't think we use any .d files? # *** EOF *** diff --git a/Tests/UnitTests/MakefileBSPAnnotated b/Tests/UnitTests/MakefileBSPAnnotated new file mode 100644 index 000000000..20c594793 --- /dev/null +++ b/Tests/UnitTests/MakefileBSPAnnotated @@ -0,0 +1,209 @@ +###################################### +# target +###################################### +TARGET = controls-leader + + +###################################### +# building variables +###################################### +# optimization +ifeq ($(DEBUG), 0) +OPT = -O3 +else +OPT = -Og -g3 +endif + +####################################### +# paths +####################################### +# Build path +BUILD_DIR = ../../Objects + +###################################### +# source +###################################### +# C sources +# since current path is in the BSP folder, go to the top level with ../../ +C_SOURCES = \ #C_SOURCES is a long space-separated lists of a bunch of files +$(wildcard ../../Drivers/Src/*.c) \ +$(wildcard ../../BSP/STM32F413/Src/*.c) \ +$(wildcard ../../BSP/STM32F413/STM32F4xx_StdPeriph_Driver/Src/*.c) \ +$(wildcard ../../CMSIS/DSP_Lib/Source/*.c) \ +$(wildcard ../../RTOS/uCOS-III-STM32F4/uCOS-III/Source/*.c) \ +$(wildcard ../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/*.c) \ +$(wildcard ../../RTOS/uCOS-III-STM32F4/uC-CPU/*.c) \ +$(wildcard ../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/*.c) \ +$(wildcard ../../RTOS/uCOS-III-STM32F4/uC-LIB/*.c) + +# This line adds everything in Apps/Src/*.c except for main.c, then adds the test file +C_SOURCES += \ +$(filter-out ../../Apps/Src/main.c, $(wildcard ../../Apps/Src/*.c)) \ +../../$(TEST) + +# ASM sources +ASM_SOURCES = \ +../../BSP/STM32F413/Src/startup_stm32f413xx.s \ +../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/os_cpu_a.s \ +../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/cpu_a.s + + +####################################### +# binaries +####################################### +PREFIX = arm-none-eabi- +# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) +# either it can be added to the PATH environment variable. +ifdef GCC_PATH +CC = $(GCC_PATH)/$(PREFIX)gcc #Set CC as the given compiler for implicit rules +AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp +CP = $(GCC_PATH)/$(PREFIX)objcopy +SZ = $(GCC_PATH)/$(PREFIX)size +else +CC = $(PREFIX)gcc +AS = $(PREFIX)gcc -x assembler-with-cpp +CP = $(PREFIX)objcopy +SZ = $(PREFIX)size +endif +HEX = $(CP) -O ihex +BIN = $(CP) -O binary -S + +SF = st-flash + +####################################### +# CFLAGS +####################################### +# cpu +CPU = -mcpu=cortex-m4 + +# float-abi +FLOAT-ABI = -mfloat-abi=soft + +# mcu +MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) + +# macros for gcc +# AS defines +AS_DEFS = + +# C defines +C_DEFS = \ +-DSTM32F413_423xx \ +-DUSE_STDPERIPH_DRIVER \ +-D__FPU_PRESENT + + +# AS includes +AS_INCLUDES = + +# C includes +# since current path is in the BSP folder, go to the top level with ../../ +C_INCLUDES = \ +-I../../Apps/Inc \ +-I../../Drivers/Inc \ +-I../../Config/Inc \ +-I../../BSP/Inc \ +-I../../CMSIS/Device/ST/STM32F4xx/Include \ +-I../../CMSIS/Include \ +-I../../BSP/STM32F413/STM32F4xx_StdPeriph_Driver/Inc \ +-I../../RTOS/uCOS-III-STM32F4/uCOS-III/Source/ \ +-I../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/ \ +-I../../RTOS/uCOS-III-STM32F4/uC-CPU/ \ +-I../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/ \ +-I../../RTOS/uCOS-III-STM32F4/uC-LIB/ \ +-I../../Tests/Inc/ \ + +# compile gcc flags +ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections + +CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -Werror -fdata-sections -ffunction-sections + +ifeq ($(DEBUG), 1) +CFLAGS += -g3 -gdwarf-2 -DDEBUG +endif + +ifeq ($(MOTOR_LOOPBACK), 1) +CFLAGS += -DMOTOR_LOOPBACK +endif + +ifeq ($(CAR_LOOPBACK), 1) +CFLAGS += -DCAR_LOOPBACK +endif + +# Generate dependency information +CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" + + +####################################### +# LDFLAGS +####################################### +# link script +LDSCRIPT = ./GCC/STM32F413RHTx_FLASH.ld + +# libraries +LIBS = -lc -lm -lnosys +LIBDIR = +LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections + +# default action: build all +all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin +#Above are prereqruisites + +####################################### +# build the application +####################################### +# list of objects +OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) #Objects variable is ../../Objcts/*name*.o, using list of C sources but replacing c with o +vpath %.c $(sort $(dir $(C_SOURCES))) #I think this is saying .c files can be found in +# list of ASM program objects +OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) #Add assembly files (as .o) to the objects variable +vpath %.s $(sort $(dir $(ASM_SOURCES))) # Also list out where they can be found +# ////////////// I don't know why we need vpath if we list out the sources in C_SOURCES and ASM_SOURCES + +#Make all the .o files from the .c files +$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) # | means order only- don't check if BUILD_DIR is out of date, just make sure it exists before running this target + @echo "CC $(<:../../%=%)" + @$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ + + +# Compiles any .o file in Objects/ from assembly files +$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) + @echo "AS $(<:../../%=%)" + @$(AS) -c $(CFLAGS) $< -o $@ + +# Makes the .elf file from the .o files listed in OBJECTS which were compiled in the .o targets +$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile + @echo "LD $(<:../../%=%)" + @$(CC) $(OBJECTS) $(LDFLAGS) -o $@ #I guess this links stuff? Don't know about the LDFLAGS + @echo "SZ $(<:../../%=%)" + @$(SZ) $@ + +$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) + @echo "HEX $(<:../../%=%)" + @$(HEX) $< $@ + +$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) + @echo "BIN $(<:../../%=%)" + @$(BIN) $< $@ + +$(BUILD_DIR): + mkdir $@ + +####################################### +# clean up +####################################### +clean: + -rm -fR $(BUILD_DIR) + +####################################### +# flash +####################################### +flash: + $(SF) write $(BUILD_DIR)/$(TARGET).bin 0x8000000 + +####################################### +# dependencies +####################################### +-include $(wildcard $(BUILD_DIR)/*.d) + +# *** EOF *** diff --git a/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h b/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h index eb3b3c28e..0aa364d05 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h @@ -1,8 +1,10 @@ -// #ifdef TEST_READCARCAN -// #include_next "ReadCarCAN.h" // Include the next instance of the file. -// // If the real version is in the include search paths after the mock one, it will include it here -// #else // Mocked Contactors.h +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// +#ifdef TEST_TASKS +#include_next "Tasks.h" +#else #ifndef __TASKS_H #define __TASKS_H #include "fff.h" @@ -49,27 +51,6 @@ */ typedef uint16_t error_code_t; -/** - * Task Prototypes - */ -//void Task_Init(void* p_arg); - -//void Task_SendTritium(void* p_arg); - -void Task_ReadCarCAN(void* p_arg); - -//void Task_UpdateDisplay(void* p_arg); - -//void Task_ReadTritium(void* p_arg); - -//void Task_SendCarCAN(void* p_arg); - -//void Task_DebugDump(void *p_arg); - -//void Task_CommandLine(void* p_arg); - - - /** * TCBs */ @@ -100,12 +81,6 @@ extern CPU_STK CommandLine_Stk[TASK_COMMAND_LINE_STACK_SIZE]; */ extern OS_Q CANBus_MsgQ; -/** - * @brief Initialize the task switch hook - * Registers the hook with the RTOS - */ -void TaskSwHook_Init(void); - /** * Task trace * @@ -143,32 +118,31 @@ typedef enum { OPT_NONRECOV } error_recov_opt_t; - -// DECLARE_FAKE_VOID_FUNC(MOCK_TEST); - +#ifndef TEST_MAIN DECLARE_FAKE_VOID_FUNC(Task_Init, void *); +#else +void Task_Init(void* p_arg); +#endif -// DECLARE_FAKE_VOID_FUNC(Task_SendTritium, void*); - -// DECLARE_FAKE_VOID_FUNC(Task_ReadCarCAN, void*); - -// DECLARE_FAKE_VOID_FUNC(Task_UpdateDisplay, void*); - -// DECLARE_FAKE_VOID_FUNC(Task_ReadTritium, void*); - -// DECLARE_FAKE_VOID_FUNC(Task_SendCarCAN, void*); - -// DECLARE_FAKE_VOID_FUNC(Task_DebugDump, void*); +#ifndef TEST_DEBUGDUMP +DECLARE_FAKE_VOID_FUNC(Task_DebugDump, void*); +#else +void Task_DebugDump(void *p_arg); +#endif -// DECLARE_FAKE_VOID_FUNC(Task_CommandLine, void*); +#ifndef TEST_COMMANDLINE +DECLARE_FAKE_VOID_FUNC(Task_CommandLine, void*); +#else +void Task_CommandLine(void* p_arg); +#endif -// DECLARE_FAKE_VOID_FUNC(TaskSwHook_Init); +DECLARE_FAKE_VOID_FUNC(TaskSwHook_Init); -// DECLARE_FAKE_VOID_FUNC(EmergencyContactorOpen); +DECLARE_FAKE_VOID_FUNC(EmergencyContactorOpen); DECLARE_FAKE_VOID_FUNC(throwTaskError, error_code_t, callback_t, error_scheduler_lock_opt_t, error_recov_opt_t); +DECLARE_FAKE_VOID_FUNC(assertOSError, OS_ERR); -//DECLARE_FAKE_VOID_FUNC(_assertOSError, OS_ERR); #endif -// #endif \ No newline at end of file +#endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h b/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h index a8ce420b3..78ea27536 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h @@ -1,16 +1,14 @@ -//////////////////////////// MOCK +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// #ifdef TEST_UPDATEDISPLAY #include_next "UpdateDisplay.h" #else #ifndef __UPDATE_DISPLAY_H #define __UPDATE_DISPLAY_H -//#include "os.h" #include "common.h" -//#include "Tasks.h" - #include "Display.h" -//#include "Contactors.h" #include "fff.h" /** diff --git a/Tests/UnitTests/Mocks/Apps/Src/Tasks.c b/Tests/UnitTests/Mocks/Apps/Src/Tasks.c index e3be836b2..61191f959 100644 --- a/Tests/UnitTests/Mocks/Apps/Src/Tasks.c +++ b/Tests/UnitTests/Mocks/Apps/Src/Tasks.c @@ -1,6 +1,12 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// #include "fff.h" #include "Tasks.h" #include "Minions.h" +#include "ReadCarCAN.h" +#include "UpdateDisplay.h" +#include "ReadTritium.h" /** * TCBs @@ -14,48 +20,28 @@ OS_TCB SendCarCAN_TCB; OS_TCB DebugDump_TCB; OS_TCB CommandLine_TCB; -// task_trace_t PrevTasks; - -/** - * Stacks - */ -// CPU_STK Init_Stk[TASK_INIT_STACK_SIZE]; -// CPU_STK SendTritium_Stk[TASK_SEND_TRITIUM_STACK_SIZE]; -// CPU_STK ReadCarCAN_Stk[TASK_READ_CAR_CAN_STACK_SIZE]; -// CPU_STK UpdateDisplay_Stk[TASK_UPDATE_DISPLAY_STACK_SIZE]; -// CPU_STK ReadTritium_Stk[TASK_READ_TRITIUM_STACK_SIZE]; -// CPU_STK SendCarCAN_Stk[TASK_SEND_CAR_CAN_STACK_SIZE]; -// CPU_STK DebugDump_Stk[TASK_DEBUG_DUMP_STACK_SIZE]; -// CPU_STK CommandLine_Stk[TASK_COMMAND_LINE_STACK_SIZE]; - -// Variables to store error codes, stored and cleared in task error assert functions -error_code_t Error_ReadCarCAN = /*READCARCAN_ERR_NONE*/ 0; // TODO: change this back to the error -// error_code_t Error_ReadTritium = T_NONE; // Initialized to no error -// error_code_t Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; +error_code_t Error_ReadCarCAN = READCARCAN_ERR_NONE; +error_code_t Error_ReadTritium = T_NONE; +error_code_t Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; extern const pinInfo_t PININFO_LUT[]; // For GPIO writes. Externed from Minions Driver C file. +#ifndef TEST_MAIN DEFINE_FAKE_VOID_FUNC(Task_Init, void*); +#endif -// DEFINE_FAKE_VOID_FUNC(Task_SendTritium, void*); - -// DEFINE_FAKE_VOID_FUNC(Task_ReadCarCAN, void*); - -// DEFINE_FAKE_VOID_FUNC(Task_UpdateDisplay, void*); +#ifndef TEST_DEBUGDUMP +DEFINE_FAKE_VOID_FUNC(Task_DebugDump, void*); +#endif -// DEFINE_FAKE_VOID_FUNC(Task_ReadTritium, void*); +#ifndef TEST_COMMANDLINE +DEFINE_FAKE_VOID_FUNC(Task_CommandLine, void*); +#endif -// DEFINE_FAKE_VOID_FUNC(Task_SendCarCAN, void*); +DEFINE_FAKE_VOID_FUNC(TaskSwHook_Init); -// DEFINE_FAKE_VOID_FUNC(Task_DebugDump, void*); - -// DEFINE_FAKE_VOID_FUNC(Task_CommandLine, void*); - -// DEFINE_FAKE_VOID_FUNC(TaskSwHook_Init); - -// DEFINE_FAKE_VOID_FUNC(EmergencyContactorOpen); +DEFINE_FAKE_VOID_FUNC(EmergencyContactorOpen); DEFINE_FAKE_VOID_FUNC(throwTaskError, error_code_t, callback_t, error_scheduler_lock_opt_t, error_recov_opt_t); - -//DEFINE_FAKE_VOID_FUNC(_assertOSError, OS_ERR); +DEFINE_FAKE_VOID_FUNC(assertOSError, OS_ERR); diff --git a/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c b/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c index 023d2af6a..bf9091ae2 100644 --- a/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c +++ b/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c @@ -1,3 +1,6 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// #include "UpdateDisplay.h" #include "Minions.h" #include diff --git a/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h b/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h index 49495c2aa..43f3707ab 100644 --- a/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h +++ b/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h @@ -1,3 +1,6 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// #ifndef __BSP_ADC_H #define __BSP_ADC_H diff --git a/Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h b/Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h index 4f14ae69e..0d00f6085 100644 --- a/Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h +++ b/Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h @@ -9,13 +9,17 @@ typedef enum {PORTA = 0, PORTB, PORTC, PORTD, NUM_PORTS} port_t; typedef enum {INPUT = 0, OUTPUT} direction_t; -DECLARE_FAKE_VOID_FUNC(BSP_GPIO_Write_Pin, port_t, uint16_t, bool); DECLARE_FAKE_VOID_FUNC(BSP_GPIO_Init, port_t, uint16_t, direction_t); -//FAKE_VOID_FUNC3(OSMutexCreate, struct os_mutex, CPU_CHAR, OS_ERR); -DECLARE_FAKE_VALUE_FUNC(uint8_t,BSP_GPIO_Get_State, port_t, uint16_t ); -//FAKE_VOID_FUNC5(OSMutexPend, OS_MUTEX, OS_TICK, OS_OPT, CPU_TS, OS_ERR); -//FAKE_VOID_FUNC3(OSMutexPost, OS_MUTEX, OS_OPT, OS_ERR); -DECLARE_FAKE_VOID_FUNC(assertOSError, int); + +DECLARE_FAKE_VALUE_FUNC(uint16_t, BSP_GPIO_Read, port_t); + +DECLARE_FAKE_VOID_FUNC(BSP_GPIO_Write, port_t, uint16_t); + +DECLARE_FAKE_VALUE_FUNC(uint8_t, BSP_GPIO_Read_Pin, port_t, uint16_t); + +DECLARE_FAKE_VOID_FUNC(BSP_GPIO_Write_Pin, port_t, uint16_t, bool); + +DECLARE_FAKE_VALUE_FUNC(uint8_t, BSP_GPIO_Get_State, port_t, uint16_t); #endif diff --git a/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h b/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h index 508969d1f..01e1d4f9e 100644 --- a/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h +++ b/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h @@ -1,4 +1,8 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + #ifndef __STM32F4xx_H #define __STM32F4xx_H diff --git a/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c b/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c index 0ceb33869..879063215 100644 --- a/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c +++ b/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c @@ -1,7 +1,13 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + #include "common.h" #include "fff.h" #include "BSP_ADC.h" DEFINE_FAKE_VOID_FUNC(BSP_ADC_Init); + DEFINE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Millivoltage, int); + DEFINE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Value, int); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c b/Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c index ec9cf4966..98b89ff89 100644 --- a/Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c +++ b/Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c @@ -1,11 +1,20 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + #include "BSP_GPIO.h" #include "fff.h" -DEFINE_FAKE_VOID_FUNC(BSP_GPIO_Write_Pin, port_t, uint16_t, bool); DEFINE_FAKE_VOID_FUNC(BSP_GPIO_Init, port_t, uint16_t, direction_t); -//FAKE_VOID_FUNC3(OSMutexCreate, struct os_mutex, CPU_CHAR, OS_ERR); -DEFINE_FAKE_VALUE_FUNC(uint8_t,BSP_GPIO_Get_State, port_t, uint16_t ); -//FAKE_VOID_FUNC5(OSMutexPend, OS_MUTEX, OS_TICK, OS_OPT, CPU_TS, OS_ERR); -//FAKE_VOID_FUNC3(OSMutexPost, OS_MUTEX, OS_OPT, OS_ERR); -DEFINE_FAKE_VOID_FUNC(assertOSError, int); + +DEFINE_FAKE_VALUE_FUNC(uint16_t, BSP_GPIO_Read, port_t); + +DEFINE_FAKE_VOID_FUNC(BSP_GPIO_Write, port_t, uint16_t); + +DEFINE_FAKE_VALUE_FUNC(uint8_t, BSP_GPIO_Read_Pin, port_t, uint16_t); + +DEFINE_FAKE_VOID_FUNC(BSP_GPIO_Write_Pin, port_t, uint16_t, bool); + +DEFINE_FAKE_VALUE_FUNC(uint8_t, BSP_GPIO_Get_State, port_t, uint16_t); + diff --git a/Tests/UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c b/Tests/UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c index c05086049..2be8770d3 100644 --- a/Tests/UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c +++ b/Tests/UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c @@ -1,10 +1,11 @@ -////////Mock +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx_gpio.h" -//#include "stm32f4xx_rcc.h" - DEFINE_FAKE_VOID_FUNC(GPIO_DeInit, GPIO_TypeDef*); DEFINE_FAKE_VOID_FUNC(GPIO_Init, GPIO_TypeDef*, GPIO_InitTypeDef*); diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h b/Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h index 03323673f..e4ae5852a 100644 --- a/Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h +++ b/Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h @@ -1,7 +1,10 @@ -// #ifdef TEST_READCARCAN -// #include_next "ReadCarCAN.h" // Include the next instance of the file. -// // If the real version is in the include search paths after the mock one, it will include it here -// #else // Mocked Contactors.h +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#ifdef TEST_CANBUS +#include_next "CANbus.h" +#else #ifndef CAN_H__ #define CAN_H__ @@ -70,12 +73,6 @@ typedef struct { uint8_t data[8]; } CANDATA_t; -/** - * Standard identifier for whether or not a CAN transaction is blocking or not - * (DEPRECATED) - */ -// typedef enum {CAN_BLOCKING=0, CAN_NON_BLOCKING} CAN_blocking_t; - //Compatibility macros for deprecated enum #define CAN_BLOCKING true #define CAN_NON_BLOCKING false @@ -87,4 +84,4 @@ DECLARE_FAKE_VALUE_FUNC(ErrorStatus, CANbus_Send, CANDATA_t, bool, CAN_t); DECLARE_FAKE_VALUE_FUNC(ErrorStatus, CANbus_Read, CANDATA_t*, bool, CAN_t); #endif -// #endif \ No newline at end of file +#endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h b/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h index 2ab84fe3d..becb65c2a 100644 --- a/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h +++ b/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h @@ -1,3 +1,7 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + #ifdef TEST_CONTACTORS #include_next "Contactors.h" // Include the next instance of the file. // If the real version is in the include search paths after the mock one, it will include it here diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h b/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h index a27ea65e8..e764da880 100644 --- a/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h +++ b/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h @@ -1,7 +1,11 @@ -// #ifdef TEST_READCARCAN -// #include_next "ReadCarCAN.h" // Include the next instance of the file. -// // If the real version is in the include search paths after the mock one, it will include it here -// #else // Mocked Contactors.h +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#ifdef TEST_MINIONS +#include_next "Minions.h" +#else + #ifndef MINIONS_H #define MINIONS_H #include "fff.h" @@ -38,4 +42,4 @@ DECLARE_FAKE_VOID_FUNC(Minions_Init); DECLARE_FAKE_VALUE_FUNC(bool, Minions_Read, pin_t); #endif -// #endif \ No newline at end of file +#endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c b/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c index 3bad0c4d7..09c5bde45 100644 --- a/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c +++ b/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c @@ -1,6 +1,12 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + #include "fff.h" #include "Contactors.h" DEFINE_FAKE_VOID_FUNC(Contactors_Init); + DEFINE_FAKE_VALUE_FUNC(bool, Contactors_Get, contactor_t); + DEFINE_FAKE_VALUE_FUNC(ErrorStatus, Contactors_Set, contactor_t, bool, bool); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Src/Display.c b/Tests/UnitTests/Mocks/Drivers/Src/Display.c index 741d419f0..a651293fa 100644 --- a/Tests/UnitTests/Mocks/Drivers/Src/Display.c +++ b/Tests/UnitTests/Mocks/Drivers/Src/Display.c @@ -1,12 +1,6 @@ -/** - * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar - * @file Display.c - * @brief Function implementations for the display driver. - * - * This contains functions relevant to sending/receiving messages - * to/from our Nextion display. - * - */ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// #include "Display.h" #include "bsp.h" // for writing to UART diff --git a/Tests/UnitTests/Mocks/Drivers/Src/Minions.c b/Tests/UnitTests/Mocks/Drivers/Src/Minions.c index 4c47da5f1..6869f815e 100644 --- a/Tests/UnitTests/Mocks/Drivers/Src/Minions.c +++ b/Tests/UnitTests/Mocks/Drivers/Src/Minions.c @@ -1,3 +1,7 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + #include "fff.h" #include "Minions.h" diff --git a/Tests/UnitTests/Mocks/RTOS/cpu.h b/Tests/UnitTests/Mocks/RTOS/cpu.h index e09c037ff..9da751aa7 100644 --- a/Tests/UnitTests/Mocks/RTOS/cpu.h +++ b/Tests/UnitTests/Mocks/RTOS/cpu.h @@ -1,3 +1,7 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + /* ********************************************************************************************************* * uC/CPU diff --git a/Tests/UnitTests/Mocks/RTOS/cpu_cfg.h b/Tests/UnitTests/Mocks/RTOS/cpu_cfg.h index 90c45ffc9..174d3bccf 100644 --- a/Tests/UnitTests/Mocks/RTOS/cpu_cfg.h +++ b/Tests/UnitTests/Mocks/RTOS/cpu_cfg.h @@ -1,3 +1,7 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + /* ********************************************************************************************************* * uC/CPU diff --git a/Tests/UnitTests/Mocks/RTOS/cpu_core.h b/Tests/UnitTests/Mocks/RTOS/cpu_core.h index 471d136c0..2ca3efb74 100644 --- a/Tests/UnitTests/Mocks/RTOS/cpu_core.h +++ b/Tests/UnitTests/Mocks/RTOS/cpu_core.h @@ -1,3 +1,7 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + /* ********************************************************************************************************* * uC/CPU diff --git a/Tests/UnitTests/Mocks/RTOS/cpu_def.h b/Tests/UnitTests/Mocks/RTOS/cpu_def.h index c22fa41d0..59631196f 100644 --- a/Tests/UnitTests/Mocks/RTOS/cpu_def.h +++ b/Tests/UnitTests/Mocks/RTOS/cpu_def.h @@ -1,3 +1,7 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + /* ********************************************************************************************************* * uC/CPU diff --git a/Tests/UnitTests/Mocks/RTOS/lib_def.h b/Tests/UnitTests/Mocks/RTOS/lib_def.h index 9b920dec1..0fea0ce12 100644 --- a/Tests/UnitTests/Mocks/RTOS/lib_def.h +++ b/Tests/UnitTests/Mocks/RTOS/lib_def.h @@ -1,3 +1,7 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + /* ********************************************************************************************************* * uC/LIB diff --git a/Tests/UnitTests/Mocks/RTOS/os.c b/Tests/UnitTests/Mocks/RTOS/os.c index 4d5f11c2b..ebd9a9750 100644 --- a/Tests/UnitTests/Mocks/RTOS/os.c +++ b/Tests/UnitTests/Mocks/RTOS/os.c @@ -1,3 +1,7 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + #include "fff.h" #include "os.h" diff --git a/Tests/UnitTests/Mocks/RTOS/os.h b/Tests/UnitTests/Mocks/RTOS/os.h index 4f32d63eb..18ee5d389 100644 --- a/Tests/UnitTests/Mocks/RTOS/os.h +++ b/Tests/UnitTests/Mocks/RTOS/os.h @@ -1,7 +1,7 @@ -// #ifdef TEST_READCARCAN -// #include_next "ReadCarCAN.h" // Include the next instance of the file. -// // If the real version is in the include search paths after the mock one, it will include it here -// #else // Mocked Contactors.h +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + #ifndef OS_H #define OS_H #include "os_type.h" diff --git a/Tests/UnitTests/Mocks/RTOS/os_cfg.h b/Tests/UnitTests/Mocks/RTOS/os_cfg.h index 7de686f52..16ced5b23 100644 --- a/Tests/UnitTests/Mocks/RTOS/os_cfg.h +++ b/Tests/UnitTests/Mocks/RTOS/os_cfg.h @@ -1,3 +1,7 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + /* ************************************************************************************************************************ * uC/OS-III diff --git a/Tests/UnitTests/Mocks/RTOS/os_type.h b/Tests/UnitTests/Mocks/RTOS/os_type.h index 22bd2f8d0..214aeffc9 100644 --- a/Tests/UnitTests/Mocks/RTOS/os_type.h +++ b/Tests/UnitTests/Mocks/RTOS/os_type.h @@ -1,3 +1,7 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + /* ************************************************************************************************************************ * uC/OS-III From b0e2a36a77d9d291f49cf5d3c5a3844f2b6093ce Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Fri, 19 Jan 2024 20:21:52 -0600 Subject: [PATCH 25/57] Finished mocking BSP --- Tests/UnitTests/Mocks/BSP/Inc/BSP_CAN.h | 21 +++++++++++++++++++++ Tests/UnitTests/Mocks/BSP/Inc/BSP_SPI.h | 21 +++++++++++++++++++++ Tests/UnitTests/Mocks/BSP/Inc/BSP_UART.h | 22 ++++++++++++++++++++++ Tests/UnitTests/Mocks/BSP/Src/BSP_CAN.c | 13 +++++++++++++ Tests/UnitTests/Mocks/BSP/Src/BSP_SPI.c | 13 +++++++++++++ Tests/UnitTests/Mocks/BSP/Src/BSP_UART.c | 14 ++++++++++++++ 6 files changed, 104 insertions(+) create mode 100644 Tests/UnitTests/Mocks/BSP/Inc/BSP_CAN.h create mode 100644 Tests/UnitTests/Mocks/BSP/Inc/BSP_SPI.h create mode 100644 Tests/UnitTests/Mocks/BSP/Inc/BSP_UART.h create mode 100644 Tests/UnitTests/Mocks/BSP/Src/BSP_CAN.c create mode 100644 Tests/UnitTests/Mocks/BSP/Src/BSP_SPI.c create mode 100644 Tests/UnitTests/Mocks/BSP/Src/BSP_UART.c diff --git a/Tests/UnitTests/Mocks/BSP/Inc/BSP_CAN.h b/Tests/UnitTests/Mocks/BSP/Inc/BSP_CAN.h new file mode 100644 index 000000000..a4f98b09d --- /dev/null +++ b/Tests/UnitTests/Mocks/BSP/Inc/BSP_CAN.h @@ -0,0 +1,21 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#ifndef __BSP_CAN_H +#define __BSP_CAN_H + +#include "fff.h" +#include "common.h" +#include "config.h" +//#include + +typedef enum {CAN_1=0, CAN_3, NUM_CAN} CAN_t; + +DECLARE_FAKE_VOID_FUNC(BSP_CAN_Init, CAN_t, callback_t, callback_t, uint16_t*, uint8_t); + +DECLARE_FAKE_VALUE_FUNC(ErrorStatus, BSP_CAN_Write, CAN_t, uint32_t, uint8_t*, uint8_t); + +DECLARE_FAKE_VALUE_FUNC(ErrorStatus, BSP_CAN_Read, CAN_t, uint32_t*, uint8_t*); + +#endif diff --git a/Tests/UnitTests/Mocks/BSP/Inc/BSP_SPI.h b/Tests/UnitTests/Mocks/BSP/Inc/BSP_SPI.h new file mode 100644 index 000000000..80801863b --- /dev/null +++ b/Tests/UnitTests/Mocks/BSP/Inc/BSP_SPI.h @@ -0,0 +1,21 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#ifndef __BSP_SPI_H +#define __BSP_SPI_H + +#include "fff.h" +#include "common.h" + + + +DECLARE_FAKE_VOID_FUNC(BSP_SPI_Init); + +DECLARE_FAKE_VOID_FUNC(BSP_SPI_Write, uint8_t*, uint8_t); + +DECLARE_FAKE_VOID_FUNC(BSP_SPI_Read, uint8_t*, uint8_t); + +#endif + + diff --git a/Tests/UnitTests/Mocks/BSP/Inc/BSP_UART.h b/Tests/UnitTests/Mocks/BSP/Inc/BSP_UART.h new file mode 100644 index 000000000..15c9dd999 --- /dev/null +++ b/Tests/UnitTests/Mocks/BSP/Inc/BSP_UART.h @@ -0,0 +1,22 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#ifndef __BSP_UART_H +#define __BSP_UART_H + +#include "fff.h" +#include "common.h" +//#include + +typedef enum {UART_2, UART_3, NUM_UART} UART_t; + +DECLARE_FAKE_VOID_FUNC(BSP_UART_Init, UART_t); + +DECLARE_FAKE_VALUE_FUNC(uint32_t, BSP_UART_Read, UART_t, char*); + +DECLARE_FAKE_VALUE_FUNC(uint32_t, BSP_UART_Write, UART_t, char*, uint32_t); + +#endif + + diff --git a/Tests/UnitTests/Mocks/BSP/Src/BSP_CAN.c b/Tests/UnitTests/Mocks/BSP/Src/BSP_CAN.c new file mode 100644 index 000000000..07f3ac54c --- /dev/null +++ b/Tests/UnitTests/Mocks/BSP/Src/BSP_CAN.c @@ -0,0 +1,13 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#include "BSP_CAN.h" +//#include "stm32f4xx.h" +//#include "os.h" + +DEFINE_FAKE_VOID_FUNC(BSP_CAN_Init, CAN_t, callback_t, callback_t, uint16_t*, uint8_t); + +DEFINE_FAKE_VALUE_FUNC(ErrorStatus, BSP_CAN_Write, CAN_t, uint32_t, uint8_t*, uint8_t); + +DEFINE_FAKE_VALUE_FUNC(ErrorStatus, BSP_CAN_Read, CAN_t, uint32_t*, uint8_t*); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Src/BSP_SPI.c b/Tests/UnitTests/Mocks/BSP/Src/BSP_SPI.c new file mode 100644 index 000000000..14f3cf9d0 --- /dev/null +++ b/Tests/UnitTests/Mocks/BSP/Src/BSP_SPI.c @@ -0,0 +1,13 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#include "BSP_SPI.h" + + + +DEFINE_FAKE_VOID_FUNC(BSP_SPI_Init); + +DEFINE_FAKE_VOID_FUNC(BSP_SPI_Write, uint8_t*, uint8_t); + +DEFINE_FAKE_VOID_FUNC(BSP_SPI_Read, uint8_t*, uint8_t); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Src/BSP_UART.c b/Tests/UnitTests/Mocks/BSP/Src/BSP_UART.c new file mode 100644 index 000000000..3f6129d04 --- /dev/null +++ b/Tests/UnitTests/Mocks/BSP/Src/BSP_UART.c @@ -0,0 +1,14 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#include "BSP_UART.h" +//#include "stm32f4xx.h" +//#include "os.h" + + +DEFINE_FAKE_VOID_FUNC(BSP_UART_Init, UART_t); + +DEFINE_FAKE_VALUE_FUNC(uint32_t, BSP_UART_Read, UART_t, char*); + +DEFINE_FAKE_VALUE_FUNC(uint32_t, BSP_UART_Write, UART_t, char*, uint32_t); \ No newline at end of file From 4ca872b11761b8668d08d5d25d11d6838d592e20 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Fri, 19 Jan 2024 20:33:00 -0600 Subject: [PATCH 26/57] Finished mocking the rest of the necessary drivers. --- Tests/UnitTests/Mocks/Drivers/Inc/Pedals.h | 31 ++++++++++++++++++++++ Tests/UnitTests/Mocks/Drivers/Src/Pedals.c | 9 +++++++ 2 files changed, 40 insertions(+) create mode 100644 Tests/UnitTests/Mocks/Drivers/Inc/Pedals.h create mode 100755 Tests/UnitTests/Mocks/Drivers/Src/Pedals.c diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/Pedals.h b/Tests/UnitTests/Mocks/Drivers/Inc/Pedals.h new file mode 100644 index 000000000..89b3d57df --- /dev/null +++ b/Tests/UnitTests/Mocks/Drivers/Inc/Pedals.h @@ -0,0 +1,31 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#ifdef TEST_PEDALS +#include_next "Pedals.h" +#else + +#ifndef __PEDALS_H +#define __PEDALS_H + +#include "BSP_ADC.h" +#include "fff.h" + +/** + * @brief Stuff + * + */ +typedef enum +{ + ACCELERATOR, + BRAKE, + NUMBER_OF_PEDALS +} pedal_t; + +DECLARE_FAKE_VOID_FUNC(Pedals_Init); + +DECLARE_FAKE_VALUE_FUNC(int8_t, Pedals_Read, pedal_t); + +#endif +#endif diff --git a/Tests/UnitTests/Mocks/Drivers/Src/Pedals.c b/Tests/UnitTests/Mocks/Drivers/Src/Pedals.c new file mode 100755 index 000000000..880f7cbc4 --- /dev/null +++ b/Tests/UnitTests/Mocks/Drivers/Src/Pedals.c @@ -0,0 +1,9 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#include "Pedals.h" + +DEFINE_FAKE_VOID_FUNC(Pedals_Init); + +DEFINE_FAKE_VALUE_FUNC(int8_t, Pedals_Read, pedal_t); \ No newline at end of file From 8c177de939dcaebf07a5342ad5da066a1c44720d Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 20 Jan 2024 00:19:46 -0600 Subject: [PATCH 27/57] Mocked apps, define a LOOP macro which is either '' or while(1) depending on if we're running a unit test or not. --- Apps/Src/CommandLine.c | 2 +- Apps/Src/DebugDump.c | 2 +- Apps/Src/ReadCarCAN.c | 10 +- Apps/Src/ReadTritium.c | 2 +- Apps/Src/SendCarCAN.c | 4 +- Apps/Src/SendTritium.c | 2 +- Apps/Src/Tasks.c | 2 +- Apps/Src/UpdateDisplay.c | 2 +- BSP/STM32F413/Makefile | 3 + Tests/UnitTests/Makefile | 3 + Tests/UnitTests/Mocks/Apps/Inc/ReadCarCAN.h | 32 ++++++ Tests/UnitTests/Mocks/Apps/Inc/ReadTritium.h | 44 ++++++++ Tests/UnitTests/Mocks/Apps/Inc/SendCarCAN.h | 22 ++++ Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h | 108 +++++++++++++++++++ Tests/UnitTests/Mocks/Apps/Src/ReadCarCAN.c | 9 ++ Tests/UnitTests/Mocks/Apps/Src/ReadTritium.c | 11 ++ Tests/UnitTests/Mocks/Apps/Src/SendCarCAN.c | 12 +++ Tests/UnitTests/Mocks/Apps/Src/SendTritium.c | 59 ++++++++++ 18 files changed, 317 insertions(+), 12 deletions(-) create mode 100644 Tests/UnitTests/Mocks/Apps/Inc/ReadCarCAN.h create mode 100755 Tests/UnitTests/Mocks/Apps/Inc/ReadTritium.h create mode 100644 Tests/UnitTests/Mocks/Apps/Inc/SendCarCAN.h create mode 100644 Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h create mode 100644 Tests/UnitTests/Mocks/Apps/Src/ReadCarCAN.c create mode 100755 Tests/UnitTests/Mocks/Apps/Src/ReadTritium.c create mode 100644 Tests/UnitTests/Mocks/Apps/Src/SendCarCAN.c create mode 100644 Tests/UnitTests/Mocks/Apps/Src/SendTritium.c diff --git a/Apps/Src/CommandLine.c b/Apps/Src/CommandLine.c index 369759342..1d4159537 100644 --- a/Apps/Src/CommandLine.c +++ b/Apps/Src/CommandLine.c @@ -102,7 +102,7 @@ void Task_CommandLine(void* p_arg) { // output welcome/help screen printf(help); - while(1){ + LOOP { printf("> "); BSP_UART_Read(UART_2, input); printf("\n\r"); diff --git a/Apps/Src/DebugDump.c b/Apps/Src/DebugDump.c index 15cd48e98..805250a14 100644 --- a/Apps/Src/DebugDump.c +++ b/Apps/Src/DebugDump.c @@ -32,7 +32,7 @@ static const char *GEAR_STRING[] = { void Task_DebugDump(void* p_arg) { OS_ERR err; - while(1){ + LOOP { // Get pedal information int8_t accelPedal = Pedals_Read(ACCELERATOR); diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c index d2bc4e6b8..fbbfc304c 100644 --- a/Apps/Src/ReadCarCAN.c +++ b/Apps/Src/ReadCarCAN.c @@ -337,15 +337,17 @@ void Task_ReadCarCAN(void *p_arg){ // would need to be reimplemented. memset(HVArrayChargeMsgBuffer, DISABLE_SATURATION_MSG, sizeof(HVArrayChargeMsgBuffer)); memset(HVPlusMinusChargeMsgBuffer, DISABLE_SATURATION_MSG, sizeof(HVPlusMinusChargeMsgBuffer)); - int x = -3; - while(++x){ + + LOOP { updatePrechargeContactors(); // Sets array and motor controller PBC if all conditions (PBC Status, Threshold, Precharge Complete) permit // BPS sent a message ErrorStatus status = CANbus_Read(&dataBuf, true, CARCAN); if(status != SUCCESS){ + #ifndef MOCKING continue; + #endif } switch(dataBuf.ID){ // Switch case based on BPS msg received @@ -408,7 +410,7 @@ static void handler_ReadCarCAN_chargeDisable(void) { if(ret) { // Contactor failed to turn off; display the evac screen and infinite loop Display_Evac(SOC, SBPV); - while(1){;} + LOOP{;} } } @@ -439,7 +441,7 @@ static void handler_ReadCarCAN_contactorsDisable(void) { if(ret) { // Contactor failed to turn off; display the evac screen and infinite loop Display_Evac(SOC, SBPV); - while(1){;} + LOOP {;} } } diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 6b1055ce6..8a42e83ff 100755 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -42,7 +42,7 @@ void Task_ReadTritium(void *p_arg){ static bool watchdogCreated = false; - while (1){ + LOOP { ErrorStatus status = CANbus_Read(&dataBuf, true, MOTORCAN); if (status == SUCCESS){ diff --git a/Apps/Src/SendCarCAN.c b/Apps/Src/SendCarCAN.c index 0272b8b6d..6d5e4d32f 100644 --- a/Apps/Src/SendCarCAN.c +++ b/Apps/Src/SendCarCAN.c @@ -121,7 +121,7 @@ void Task_SendCarCAN(void *p_arg){ ); assertOSError(err); - while (1) { + LOOP { // Check if there's something to send in the queue (either IOState or Car state from sendTritium) OSSemPend(&CarCAN_Sem4, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); @@ -171,7 +171,7 @@ static void putIOState(void){ */ static void Task_PutIOState(void *p_arg) { OS_ERR err; - while (1) { + LOOP { putIOState(); OSTimeDlyHMSM(0, 0, 0, IO_STATE_DLY_MS, OS_OPT_TIME_HMSM_STRICT, &err); assertOSError(err); diff --git a/Apps/Src/SendTritium.c b/Apps/Src/SendTritium.c index 9f6f85307..1d6a36b54 100644 --- a/Apps/Src/SendTritium.c +++ b/Apps/Src/SendTritium.c @@ -655,7 +655,7 @@ void Task_SendTritium(void *p_arg){ }; #endif - while(1){ + LOOP { prevState = state; state.stateHandler(); // do what the current state does diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index af6382e1d..9db2d2f39 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -60,7 +60,7 @@ void _assertOSError(OS_ERR err) { EmergencyContactorOpen(); // Turn off contactors and turn on the brakelight to indicate an emergency Display_Error(err); // Display the location and error code - while(1){;} //nonrecoverable + LOOP {;} //nonrecoverable } } diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 7da45f42b..d5f8af9a0 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -328,7 +328,7 @@ void UpdateDisplay_ClearQueue(){ * @brief Loops through the display queue and sends all messages */ void Task_UpdateDisplay(void *p_arg) { - while (1) { + LOOP { UpdateDisplay_PopNext(); } } diff --git a/BSP/STM32F413/Makefile b/BSP/STM32F413/Makefile index bfc0a49b9..cd3d25a1a 100644 --- a/BSP/STM32F413/Makefile +++ b/BSP/STM32F413/Makefile @@ -130,6 +130,9 @@ ifeq ($(CAR_LOOPBACK), 1) CFLAGS += -DCAR_LOOPBACK endif +# Not mocking -> LOOP = while(1) +CFLAGS += -D'LOOP=while(1)' + # Generate dependency information CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index 7a7d8e0fc..3e61d2892 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -86,6 +86,9 @@ endif MOCKING=1 CFLAGS += -DMOCKING +# mocking -> LOOP = '' +CFLAGS += -D'LOOP=' + FILETOTEST = $(shell echo '$(TEST)' | tr '[:lower:]' '[:upper:]') #Uses shell to make TEST file uppercase to define a macro CFLAGS += -DTEST_$(FILETOTEST) #Defines a macro TEST_ to determine if we should use a mock or regular header file diff --git a/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCAN.h b/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCAN.h new file mode 100644 index 000000000..49a64a550 --- /dev/null +++ b/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCAN.h @@ -0,0 +1,32 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#ifdef TEST_READCARCAN +#include_next "ReadCarCAN.h" +#else + +#ifndef __READ_CAR_CAN_H +#define __READ_CAR_CAN_H + +#include "fff.h" +#include "common.h" + +/** + * Error types + */ +typedef enum{ + READCARCAN_ERR_NONE, + READCARCAN_ERR_CHARGE_DISABLE, // Received a charge disable msg + READCARCAN_ERR_MISSED_MSG, // Didn't receive a BPS charge msg in time + READCARCAN_ERR_DISABLE_CONTACTORS_MSG, // Ignition is turned to neither (off due to LV) or both at the same time (impossible) are on at + READCARCAN_ERR_BPS_TRIP // Received a BPS trip msg (0 or 1) +} ReadCarCAN_error_code_t; + + +DECLARE_FAKE_VOID_FUNC(Task_ReadCarCAN, void*); + +DECLARE_FAKE_VALUE_FUNC(bool, ChargeEnable_Get); + +#endif +#endif diff --git a/Tests/UnitTests/Mocks/Apps/Inc/ReadTritium.h b/Tests/UnitTests/Mocks/Apps/Inc/ReadTritium.h new file mode 100755 index 000000000..6c89a3872 --- /dev/null +++ b/Tests/UnitTests/Mocks/Apps/Inc/ReadTritium.h @@ -0,0 +1,44 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#ifdef TEST_READTRITIUM +#include_next "ReadTritium.h" +#else + +#ifndef __READ_TRITIUM_H +#define __READ_TRITIUM_H + +#include "fff.h" +#include "os.h" +#include "common.h" +#include "Tasks.h" + +/** + * Motor Error States + * Read messages from motor in ReadTritium and trigger appropriate error messages as needed based on bits + * + */ +typedef enum{ + T_HARDWARE_OVER_CURRENT_ERR = (1<<0), + T_SOFTWARE_OVER_CURRENT_ERR = (1<<1), + T_DC_BUS_OVERVOLT_ERR = (1<<2), + T_HALL_SENSOR_ERR = (1<<3), + T_WATCHDOG_LAST_RESET_ERR = (1<<4), + T_CONFIG_READ_ERR = (1<<5), + T_UNDER_VOLTAGE_LOCKOUT_ERR = (1<<6), + T_DESAT_FAULT_ERR = (1<<7), + T_MOTOR_OVER_SPEED_ERR = (1<<8), + T_INIT_FAIL = (1<<9), //motor controller fails to restart or initialize + T_MOTOR_WATCHDOG_TRIP = (1 << 15), + T_NONE = 0x00, +} tritium_error_code_t; + +DECLARE_FAKE_VOID_FUNC(Task_ReadTritium, void*); + +DECLARE_FAKE_VALUE_FUNC(float, Motor_RPM_Get); + +DECLARE_FAKE_VALUE_FUNC(float, Motor_Velocity_Get); + +#endif +#endif diff --git a/Tests/UnitTests/Mocks/Apps/Inc/SendCarCAN.h b/Tests/UnitTests/Mocks/Apps/Inc/SendCarCAN.h new file mode 100644 index 000000000..0d191fb9f --- /dev/null +++ b/Tests/UnitTests/Mocks/Apps/Inc/SendCarCAN.h @@ -0,0 +1,22 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#ifdef TEST_SENDCARCAN +#include_next "SendCarCAN.h" +#else + +#ifndef __SENDCARCAN_H +#define __SENDCARCAN_H + +#include "fff.h" +#include "CANbus.h" + +DECLARE_FAKE_VOID_FUNC(Task_SendCarCAN, void*); + +DECLARE_FAKE_VOID_FUNC(SendCarCAN_Init); + +DECLARE_FAKE_VOID_FUNC(SendCarCAN_Put, CANDATA_t); + +#endif +#endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h b/Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h new file mode 100644 index 000000000..96047b09e --- /dev/null +++ b/Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h @@ -0,0 +1,108 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// +#ifdef TEST_SENDTRITIUM +#include_next "SendTritium.h" +#else + +#ifndef __SENDTRITIUM_H +#define __SENDTRITIUM_H + +#include "fff.h" +#include "common.h" + +//#define SENDTRITIUM_PRINT_MES + +#define MOTOR_MSG_PERIOD 100 // in ms +#define FSM_PERIOD 100 // in ms +#define DEBOUNCE_PERIOD 2 // in units of FSM_PERIOD +#define MOTOR_MSG_COUNTER_THRESHOLD (MOTOR_MSG_PERIOD)/(FSM_PERIOD) + +#define FOREACH_Gear(GEAR) \ + GEAR(FORWARD_GEAR), \ + GEAR(NEUTRAL_GEAR), \ + GEAR(REVERSE_GEAR), \ + +typedef enum GEAR_ENUM { + FOREACH_Gear(GENERATE_ENUM) + NUM_GEARS, +} Gear_t; + +// State Names +typedef enum{ + FORWARD_DRIVE, + NEUTRAL_DRIVE, + REVERSE_DRIVE, + RECORD_VELOCITY, + POWERED_CRUISE, + COASTING_CRUISE, + BRAKE_STATE, + ONEPEDAL, + ACCELERATE_CRUISE +} TritiumStateName_t; + +// State Struct for FSM +typedef struct TritiumState{ + TritiumStateName_t name; + void (*stateHandler)(void); + void (*stateDecider)(void); +} TritiumState_t; + + +DECLARE_FAKE_VOID_FUNC(Task_SendTritium, void*); + +// Getter functions for local variables in SendTritium.c +DECLARE_FAKE_VALUE_FUNC(bool, GetCruiseEnable); + +DECLARE_FAKE_VALUE_FUNC(bool, GetCruiseSet); + +DECLARE_FAKE_VALUE_FUNC(bool, GetOnePedalEnable); + +DECLARE_FAKE_VALUE_FUNC(bool, GetRegenEnable); + +DECLARE_FAKE_VALUE_FUNC(uint8_t, GetBrakePedalPercent); + +DECLARE_FAKE_VALUE_FUNC(uint8_t, GetAccelPedalPercent); + +DECLARE_FAKE_VALUE_FUNC(Gear_t, GetGear); + +DECLARE_FAKE_VALUE_FUNC(TritiumState_t, GetState); + +DECLARE_FAKE_VALUE_FUNC(float, GetVelocityObserved); + +DECLARE_FAKE_VALUE_FUNC(float, GetCruiseVelSetpoint); + +DECLARE_FAKE_VALUE_FUNC(float, GetCurrentSetpoint); + +DECLARE_FAKE_VALUE_FUNC(float, GetVelocitySetpoint); + + +// Setter functions for local variables in SendTritium.c +#ifdef SENDTRITIUM_EXPOSE_VARS +DECLARE_FAKE_VOID_FUNC(SetCruiseEnable, bool); + +DECLARE_FAKE_VOID_FUNC(SetCruiseSet, bool); + +DECLARE_FAKE_VOID_FUNC(SetOnePedalEnable, bool); + +DECLARE_FAKE_VOID_FUNC(SetRegenEnable, bool); + +DECLARE_FAKE_VOID_FUNC(SetBrakePedalPercent, uint8_t); + +DECLARE_FAKE_VOID_FUNC(SetAccelPedalPercent, uint8_t); + +DECLARE_FAKE_VOID_FUNC(SetGear, Gear_t); + +DECLARE_FAKE_VOID_FUNC(SetState, TritiumState_t); + +DECLARE_FAKE_VOID_FUNC(SetVelocityObserved, float); + +DECLARE_FAKE_VOID_FUNC(SetCruiseVelSetpoint, float); + +DECLARE_FAKE_VOID_FUNC(SetCurrentSetpoint, float); + +DECLARE_FAKE_VOID_FUNC(SetVelocitySetpoint, float); +#endif + +#endif +#endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Src/ReadCarCAN.c b/Tests/UnitTests/Mocks/Apps/Src/ReadCarCAN.c new file mode 100644 index 000000000..c98411ede --- /dev/null +++ b/Tests/UnitTests/Mocks/Apps/Src/ReadCarCAN.c @@ -0,0 +1,9 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#include "ReadCarCAN.h" + +DEFINE_FAKE_VOID_FUNC(Task_ReadCarCAN, void*); + +DEFINE_FAKE_VALUE_FUNC(bool, ChargeEnable_Get); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Src/ReadTritium.c b/Tests/UnitTests/Mocks/Apps/Src/ReadTritium.c new file mode 100755 index 000000000..60626bb08 --- /dev/null +++ b/Tests/UnitTests/Mocks/Apps/Src/ReadTritium.c @@ -0,0 +1,11 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#include "ReadTritium.h" + +DEFINE_FAKE_VOID_FUNC(Task_ReadTritium, void*); + +DEFINE_FAKE_VALUE_FUNC(float, Motor_RPM_Get); + +DEFINE_FAKE_VALUE_FUNC(float, Motor_Velocity_Get); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Src/SendCarCAN.c b/Tests/UnitTests/Mocks/Apps/Src/SendCarCAN.c new file mode 100644 index 000000000..f32cf26cc --- /dev/null +++ b/Tests/UnitTests/Mocks/Apps/Src/SendCarCAN.c @@ -0,0 +1,12 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#include "SendCarCAN.h" + + +DEFINE_FAKE_VOID_FUNC(Task_SendCarCAN, void*); + +DEFINE_FAKE_VOID_FUNC(SendCarCAN_Init); + +DEFINE_FAKE_VOID_FUNC(SendCarCAN_Put, CANDATA_t); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Src/SendTritium.c b/Tests/UnitTests/Mocks/Apps/Src/SendTritium.c new file mode 100644 index 000000000..af89fd3a2 --- /dev/null +++ b/Tests/UnitTests/Mocks/Apps/Src/SendTritium.c @@ -0,0 +1,59 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#include "SendTritium.h" +#include "CANConfig.h" +#include "common.h" + +DEFINE_FAKE_VOID_FUNC(Task_SendTritium, void*); + +DEFINE_FAKE_VALUE_FUNC(bool, GetCruiseEnable); + +DEFINE_FAKE_VALUE_FUNC(bool, GetCruiseSet); + +DEFINE_FAKE_VALUE_FUNC(bool, GetOnePedalEnable); + +DEFINE_FAKE_VALUE_FUNC(bool, GetRegenEnable); + +DEFINE_FAKE_VALUE_FUNC(uint8_t, GetBrakePedalPercent); + +DEFINE_FAKE_VALUE_FUNC(uint8_t, GetAccelPedalPercent); + +DEFINE_FAKE_VALUE_FUNC(Gear_t, GetGear); + +DEFINE_FAKE_VALUE_FUNC(TritiumState_t, GetState); + +DEFINE_FAKE_VALUE_FUNC(float, GetVelocityObserved); + +DEFINE_FAKE_VALUE_FUNC(float, GetCruiseVelSetpoint); + +DEFINE_FAKE_VALUE_FUNC(float, GetCurrentSetpoint); + +DEFINE_FAKE_VALUE_FUNC(float, GetVelocitySetpoint); + +#ifdef SENDTRITIUM_EXPOSE_VARS +DEFINE_FAKE_VOID_FUNC(SetCruiseEnable, bool); + +DEFINE_FAKE_VOID_FUNC(SetCruiseSet, bool); + +DEFINE_FAKE_VOID_FUNC(SetOnePedalEnable, bool); + +DEFINE_FAKE_VOID_FUNC(SetRegenEnable, bool); + +DEFINE_FAKE_VOID_FUNC(SetBrakePedalPercent, uint8_t); + +DEFINE_FAKE_VOID_FUNC(SetAccelPedalPercent, uint8_t); + +DEFINE_FAKE_VOID_FUNC(SetGear, Gear_t); + +DEFINE_FAKE_VOID_FUNC(SetState, TritiumState_t); + +DEFINE_FAKE_VOID_FUNC(SetVelocityObserved, float); + +DEFINE_FAKE_VOID_FUNC(SetCruiseVelSetpoint, float); + +DEFINE_FAKE_VOID_FUNC(SetCurrentSetpoint, float); + +DEFINE_FAKE_VOID_FUNC(SetVelocitySetpoint, float); +#endif \ No newline at end of file From d0bc2724c492cbc115b68b28667e93b473dc8c03 Mon Sep 17 00:00:00 2001 From: Nathaniel Delgado <89701060+NathanielDelgado@users.noreply.github.com> Date: Sat, 20 Jan 2024 11:52:01 -0600 Subject: [PATCH 28/57] Dev/code cleanup again (#404) * Added clang format/tidy config files, changes to the makefiles to apply them and edited the github workflow to make sure the tools are enforced * Applied clang format and tidy * Updated embedded shairpoint which has correct install script --- .clang-format | 270 ++++++ .clang-tidy | 59 ++ .github/workflows/c-cpp.yml | 7 + Apps/Inc/MedianFilter.h | 221 ----- Apps/Inc/ReadCarCAN.h | 39 - Apps/Inc/ReadCarCan.h | 37 + Apps/Inc/ReadTritium.h | 50 +- Apps/Inc/{SendCarCAN.h => SendCarCan.h} | 18 +- Apps/Inc/SendTritium.h | 132 ++- Apps/Inc/Tasks.h | 192 ++-- Apps/Inc/UpdateDisplay.h | 80 +- Apps/Inc/common.h | 51 +- Apps/Inc/fifo.h | 128 ++- Apps/Src/CommandLine.c | 582 ++++++------- Apps/Src/DebugDump.c | 86 +- Apps/Src/PedalToPercent.c | 117 +-- Apps/Src/ReadCarCAN.c | 489 ----------- Apps/Src/ReadCarCan.c | 548 ++++++++++++ Apps/Src/ReadTritium.c | 261 +++--- Apps/Src/SendCarCAN.c | 179 ---- Apps/Src/SendCarCan.c | 176 ++++ Apps/Src/SendTritium.c | 1009 ++++++++++++---------- Apps/Src/Tasks.c | 235 ++--- Apps/Src/UpdateDisplay.c | 501 ++++++----- Apps/Src/common.c | 28 +- Apps/Src/main.c | 204 ++--- BSP/Inc/BSP_ADC.h | 35 +- BSP/Inc/BSP_CAN.h | 37 +- BSP/Inc/BSP_GPIO.h | 44 +- BSP/Inc/BSP_OS.h | 22 - BSP/Inc/BSP_SPI.h | 51 -- BSP/Inc/BSP_UART.h | 39 +- BSP/Inc/bsp.h | 32 +- BSP/STM32F413/Makefile | 30 + BSP/STM32F413/Src/BSP_ADC.c | 186 ++-- BSP/STM32F413/Src/BSP_CAN.c | 594 +++++++------ BSP/STM32F413/Src/BSP_GPIO.c | 102 ++- BSP/STM32F413/Src/BSP_SPI.c | 251 ------ BSP/STM32F413/Src/BSP_Switches.c | 0 BSP/STM32F413/Src/BSP_UART.c | 357 ++++---- BSP/STM32F413/Src/retarget.c | 31 +- Drivers/Inc/CANbus.h | 118 --- Drivers/Inc/CanBus.h | 121 +++ Drivers/Inc/{CANConfig.h => CanConfig.h} | 22 +- Drivers/Inc/Contactors.h | 51 +- Drivers/Inc/Display.h | 96 +- Drivers/Inc/GPIOExpander.h | 54 -- Drivers/Inc/Minions.h | 57 +- Drivers/Inc/Pedals.h | 28 +- Drivers/Src/CANConfig.c | 66 -- Drivers/Src/CANbus.c | 258 ------ Drivers/Src/CanBus.c | 240 +++++ Drivers/Src/CanConfig.c | 60 ++ Drivers/Src/Contactors.c | 91 +- Drivers/Src/Display.c | 201 +++-- Drivers/Src/Minions.c | 44 +- Drivers/Src/Pedals.c | 59 +- Embedded-Sharepoint | 2 +- Makefile | 8 +- 59 files changed, 4392 insertions(+), 4694 deletions(-) create mode 100644 .clang-format create mode 100644 .clang-tidy delete mode 100644 Apps/Inc/MedianFilter.h delete mode 100644 Apps/Inc/ReadCarCAN.h create mode 100644 Apps/Inc/ReadCarCan.h mode change 100755 => 100644 Apps/Inc/ReadTritium.h rename Apps/Inc/{SendCarCAN.h => SendCarCan.h} (52%) delete mode 100644 Apps/Src/ReadCarCAN.c create mode 100644 Apps/Src/ReadCarCan.c mode change 100755 => 100644 Apps/Src/ReadTritium.c delete mode 100644 Apps/Src/SendCarCAN.c create mode 100644 Apps/Src/SendCarCan.c delete mode 100644 BSP/Inc/BSP_OS.h delete mode 100644 BSP/Inc/BSP_SPI.h mode change 100755 => 100644 BSP/Inc/bsp.h mode change 100755 => 100644 BSP/STM32F413/Src/BSP_GPIO.c delete mode 100644 BSP/STM32F413/Src/BSP_SPI.c delete mode 100644 BSP/STM32F413/Src/BSP_Switches.c delete mode 100644 Drivers/Inc/CANbus.h create mode 100644 Drivers/Inc/CanBus.h rename Drivers/Inc/{CANConfig.h => CanConfig.h} (59%) delete mode 100644 Drivers/Inc/GPIOExpander.h delete mode 100644 Drivers/Src/CANConfig.c delete mode 100755 Drivers/Src/CANbus.c create mode 100644 Drivers/Src/CanBus.c create mode 100644 Drivers/Src/CanConfig.c mode change 100755 => 100644 Drivers/Src/Pedals.c diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..9da13e1b3 --- /dev/null +++ b/.clang-format @@ -0,0 +1,270 @@ +--- +Language: Cpp +# BasedOnStyle: Google +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseColons: false +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: + Kind: Always + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterExternBlock: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAfterAttributes: Never +BreakAfterJavaFieldAnnotations: false +BreakArrays: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Attach +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: true +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^<.*\.h>' + Priority: 1 + SortPriority: 0 + CaseSensitive: false + - Regex: '^<.*' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 3 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '([-_](test|unittest))?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: true +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +KeepEmptyLinesAtEOF: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 4 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PackConstructorInitializers: NextLine +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +PPIndentWidth: -1 +QualifierAlignment: Leave +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + - ParseTestProto + - ParsePartialTestProto + CanonicalDelimiter: pb + BasedOnStyle: google +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: Never +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Auto +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseTab: Never +VerilogBreakBetweenInstancePorts: true +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE +... + diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 000000000..36d765f8b --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,59 @@ +--- +Checks: 'clang-diagnostic-*,clang-analyzer-*, + bugprone-*, cppcoreguidelines-*, readability-*, + -cppcoreguidelines-avoid-non-const-global-variables, + -bugprone-easily-swappable-parameters, + -clang-analyzer-security.insecureAPI.*' +WarningsAsErrors: '' +HeaderFileExtensions: + - '' + - h + - hh + - hpp + - hxx +ImplementationFileExtensions: + - c + - cc + - cpp + - cxx +HeaderFilterRegex: '' +AnalyzeTemporaryDtors: false +FormatStyle: none +User: nate +CheckOptions: + cppcoreguidelines-avoid-magic-numbers.IgnoredIntegerValues: 1;2;3;4;100 + readability-magic-numbers.IgnoredIntegerValues: 1;2;3;4;100 + readability-identifier-naming.EnumCase: CamelCase + readability-identifier-naming.EnumConstantCase: CamelCase + readability-identifier-naming.EnumConstantPrefix: k + readability-identifier-naming.FunctionCase: camelBack + readability-identifier-naming.GlobalConstantCase: CamelCase + readability-identifier-naming.GlobalConstantPrefix: k + readability-identifier-naming.GlobalConstantPointerCase: CamelCase + readability-identifier-naming.GlobalConstantPointerPrefix: k + readability-identifier-naming.GlobalFunctionCase: CamelCase + readability-identifier-naming.GlobalPointerCase: lower_case + readability-identifier-naming.GlobalVariableCase: lower_case + readability-identifier-naming.LocalConstantCase: CamelCase + readability-identifier-naming.LocalConstantPrefix: k + readability-identifier-naming.LocalConstantPointerCase: CamelCase + readability-identifier-naming.LocalConstantPointerPrefix: k + readability-identifier-naming.LocalPointerCase: lower_case + readability-identifier-naming.LocalVariableCase: lower_case + readability-identifier-naming.MacroDefinitionCase: UPPER_CASE + readability-identifier-naming.ParameterCase: lower_case + readability-identifier-naming.PointerParameterCase: lower_case + readability-identifier-naming.StaticConstantCase: CamelCase + readability-identifier-naming.StaticConstantPrefix: k + readability-identifier-naming.StaticVariableCase: lower_case + readability-identifier-naming.TypedefCase: CamelCase + readability-identifier-naming.StructCase: lower_case + readability-identifier-naming.UnionCase: CamelCase + readability-identifier-naming.VariableCase: lower_case + readability-identifier-naming.IgnoreMainLikeFunctions: false + readability-identifier-length.MinimumVariableNameLength: 2 + readability-identifier-length.MinimumParameterNameLength: 2 + readability-function-cognitive-complexity.Threshold: 32 +SystemHeaders: false +... + diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 2c1b365dd..a03547c65 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -21,3 +21,10 @@ jobs: run: make clean - name: make leader run: make leader + # Run tidy and format and then tidy again in case format moves any NOLINTs to other lines, thus creating warnings/errors + - name: tidy + run: make tidy + - name: format + run: make format + - name: tidy + run: make tidy diff --git a/Apps/Inc/MedianFilter.h b/Apps/Inc/MedianFilter.h deleted file mode 100644 index 5dd629571..000000000 --- a/Apps/Inc/MedianFilter.h +++ /dev/null @@ -1,221 +0,0 @@ -/** - * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar - * @file MedianFilter.h - * @brief - * - * @defgroup MedianFilter - * @addtogroup MedianFilter - * @{ - */ - -/* - * This file implements a median filter. - * - * In order to use it in another file, you must import it in - * a particular way. - * - * 1. Define your data type, like so - * #define MEDIAN_FILTER_TYPE int - * 2. Define your filter depth, like so - * #define MEDIAN_FILTER_DEPTH (128) - * 3. Define the number of channels in your filter, like so - * #define MEDIAN_FILTER_CHANNELS (31) - * 3. Name your median filter - * #define MEDIAN_FILTER_NAME my_fifo - * 4. Import this file - * #include "MedianFilter.h" - * - * This file includes some defaults, but they might not work for - * your case! - * - * Also, this file undef's everything at the end, so you can import - * multiple times if you need. - * - * If MEDIAN_FILTER_NAME == my_filter, then your new data structure will be - * called my_filter_t. - * - * NOTE: importantly, this does not currently support usage from - * header files. That is, all these types/functions are statically - * declared, so there cannot be a non-static fifo at the moment. - */ - -// The header guard only guard the import, -// since this file can be imported multiple times -#ifndef MEDIAN_FILTER_H -#define MEDIAN_FILTER_H -#include -#include -#endif - -// The type of the median filter -#ifndef MEDIAN_FILTER_TYPE -#define MEDIAN_FILTER_TYPE int32_t -#endif - -// The depth of the median filter -#ifndef MEDIAN_FILTER_DEPTH -#define MEDIAN_FILTER_DEPTH 3 -#endif - -// The number of channels in the median filter -#ifndef MEDIAN_FILTER_CHANNELS -#define MEDIAN_FILTER_CHANNELS 1 -#endif - -// The name of the median filter (minus the _t) -#ifndef MEDIAN_FILTER_NAME -#define MEDIAN_FILTER_NAME define_your_filter_type -#endif - -// Utility definitions -#define _CONCAT(A, B) A ## B -#define CONCAT(A, B) _CONCAT(A, B) - -// some shorthand -#define MF_TYPE MEDIAN_FILTER_TYPE -#define MF_DEPTH MEDIAN_FILTER_DEPTH -#define MF_CHANNELS MEDIAN_FILTER_CHANNELS -#define MF_NAME MEDIAN_FILTER_NAME - -// Type names -#define MEDIAN_FILTER_STRUCT_NAME CONCAT(MF_NAME, _s) -#define MEDIAN_FILTER_TYPE_NAME CONCAT(MF_NAME, _t) - -// more shorthand -#define MF_STRUCT_NAME MEDIAN_FILTER_STRUCT_NAME -#define MF_TYPE_NAME MEDIAN_FILTER_TYPE_NAME - -// The actual structure -typedef struct MF_STRUCT_NAME { - MF_TYPE raw[MF_CHANNELS][MF_DEPTH]; - MF_TYPE filtered[MF_CHANNELS]; - uint32_t index; -} MF_TYPE_NAME; - -// Define some names for our functions -#define MEDIAN CONCAT(MF_NAME, _median) -#define INIT CONCAT(MF_NAME, _init) -#define GET CONCAT(MF_NAME, _get) -#define PUT CONCAT(MF_NAME, _put) -#define GETSINGLE CONCAT(MF_NAME, _getSingle) - -/** - * @brief Helper function to find the median of an array of MF_TYPE with length MF_DEPTH. - * DO NOT call this function directly. - * - * @param channel the channel in the median filter to find the median of - */ -static inline MF_TYPE __attribute__((unused)) -MEDIAN (MF_TYPE *channel) { - static MF_TYPE sorted[MF_DEPTH]; - - // copy channels into temporary array - memcpy(sorted, channel, MF_DEPTH * sizeof(MF_TYPE)); - - // sort temporary array - for (uint32_t i = 0; i < MF_DEPTH; ++i) { - MF_TYPE min = sorted[i]; - uint32_t minIdx = i; - for (uint32_t j = i + 1; j < MF_DEPTH; ++j) { - if (sorted[j] < min) { - min = sorted[j]; - minIdx = j; - } - } - sorted[minIdx] = sorted[i]; - sorted[i] = min; - } - - // return median - return sorted[MF_DEPTH >> 1]; -} - -/** - * @brief Initialize a new median filter - * - * If the type of the filter is myfilter_t, then this function - * will be called myfilter_init(). - * - * @param filter a pointer to the median filter to initialize - * @param low a value that is below the range of expected values - * @param high a value that is above the range of expected values - */ -static inline void __attribute__((unused)) -INIT (MF_TYPE_NAME *filter, MF_TYPE low, MF_TYPE high) { - // intialize the filter with alternating low and high values, so it will be stable at startup - for (uint32_t channel = 0; channel < MF_CHANNELS; ++channel) { - for (uint32_t i = 0; i < MF_DEPTH - 1; ++i) { - filter->raw[channel][i] = (i & 1) ? high : low; - } - filter->filtered[channel] = MEDIAN(filter->raw[channel]); - } - - filter->index = MF_DEPTH - 1; -} - -/** - * @brief update the median filter by giving it a new set of values for all channels - * - * @param filter a pointer to the median filter - * @param channels a complete set of new values for all channels to add to the median filter - * - */ -static inline void __attribute__((unused)) -PUT (MF_TYPE_NAME *filter, MF_TYPE *channels) { - // put the new data into the filter - for (uint32_t channel = 0; channel < MF_CHANNELS; ++channel) { - filter->raw[channel][filter->index] = channels[channel]; - } - (filter->index) = (filter->index + 1) % MF_DEPTH; - - // update the list of filtered values - for (uint32_t channel = 0; channel < MF_CHANNELS; ++channel) { - filter->filtered[channel] = MEDIAN(filter->raw[channel]); - } -} - -/** - * @brief get a complete set of filtered values for all channels - * - * @param filter a pointer to the median filter - * @param dest a pointer to a buffer to store all of the filtered values - */ -static inline void __attribute__((unused)) -GET (MF_TYPE_NAME *filter, MF_TYPE *dest) { - memcpy(dest, filter->filtered, sizeof(MF_TYPE) * MF_CHANNELS); -} - -/** - * @brief get a filtered value for a single channel in the median filter - * - * @param filter a pointer to the median filter - * @param channel the channel to read - * @return the filtered value - */ -static inline MF_TYPE __attribute__((unused)) -GETSINGLE (MF_TYPE_NAME *filter, uint32_t channel) { - return filter->filtered[channel]; -} - -// undef everything, so this file can be included multiple times -#undef MEDIAN_FILTER_TYPE -#undef MEDIAN_FILTER_DEPTH -#undef MEDIAN_FILTER_CHANNELS -#undef MEDIAN_FILTER_NAME -#undef _CONCAT -#undef CONCAT -#undef MF_TYPE -#undef MF_DEPTH -#undef MF_CHANNELS -#undef MF_NAME -#undef MEDIAN_FILTER_STRUCT_NAME -#undef MEDIAN_FILTER_TYPE_NAME -#undef MF_STRUCT_NAME -#undef MF_TYPE_NAME -#undef MEDIAN -#undef INIT -#undef GET -#undef PUT -#undef GETSINGLE - -/* @} */ \ No newline at end of file diff --git a/Apps/Inc/ReadCarCAN.h b/Apps/Inc/ReadCarCAN.h deleted file mode 100644 index a082bf312..000000000 --- a/Apps/Inc/ReadCarCAN.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar - * @file ReadCarCAN.h - * @brief - * - * @defgroup ReadCarCAN - * @addtogroup ReadCarCAN - * @{ - */ - -#ifndef __READ_CAR_CAN_H -#define __READ_CAR_CAN_H - -#include "os.h" -#include "common.h" -#include "Tasks.h" -#include "CANbus.h" - -/** - * Error types - */ -typedef enum{ - READCARCAN_ERR_NONE, - READCARCAN_ERR_CHARGE_DISABLE, // Received a charge disable msg - READCARCAN_ERR_MISSED_MSG, // Didn't receive a BPS charge msg in time - READCARCAN_ERR_DISABLE_CONTACTORS_MSG, // Ignition is turned to neither (off due to LV) or both at the same time (impossible) are on at - READCARCAN_ERR_BPS_TRIP // Received a BPS trip msg (0 or 1) -} ReadCarCAN_error_code_t; - -/** - * @brief Returns whether regen braking / charging is enabled or not - * @return Whether regen braking / charging is enabled or not -*/ -bool ChargeEnable_Get(void); - -#endif - - -/* @} */ diff --git a/Apps/Inc/ReadCarCan.h b/Apps/Inc/ReadCarCan.h new file mode 100644 index 000000000..51cb9fa4a --- /dev/null +++ b/Apps/Inc/ReadCarCan.h @@ -0,0 +1,37 @@ +/** + * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar + * @file ReadCarCAN.h + * @brief + * + * @defgroup ReadCarCAN + * @addtogroup ReadCarCAN + * @{ + */ + +#ifndef READ_CAR_CAN_H +#define READ_CAR_CAN_H + +#include "common.h" + +/** + * Error types + */ +typedef enum { + kReadCarCanErrNone, + kReadCarCanErrChargeDisable, // Received a charge disable msg + kReadCarCanErrMissedMsg, // Didn't receive a BPS charge msg in time + kReadCarCanErrDisableContactorsMsg, // Ignition is turned to neither (off + // due to LV) or both at the same time + // (impossible) are on at + kReadCarCanErrBpsTrip // Received a BPS trip msg (0 or 1) +} ReadCarCanErrorCode; + +/** + * @brief Returns whether regen braking / charging is enabled or not + * @return Whether regen braking / charging is enabled or not + */ +bool ChargeEnableGet(void); + +#endif + +/* @} */ diff --git a/Apps/Inc/ReadTritium.h b/Apps/Inc/ReadTritium.h old mode 100755 new mode 100644 index 0d1f76338..3a6fe947f --- a/Apps/Inc/ReadTritium.h +++ b/Apps/Inc/ReadTritium.h @@ -1,43 +1,39 @@ /* Copyright (c) 2021 UT Longhorn Racing Solar * @file ReadTritium.h - * @brief - * + * @brief + * * @defgroup ReadTritium * @addtogroup ReadTritium * @{ */ -#ifndef __READ_TRITIUM_H -#define __READ_TRITIUM_H - -#include "os.h" -#include "common.h" -#include "Tasks.h" +#ifndef READ_TRITIUM_H +#define READ_TRITIUM_H /** * Motor Error States - * Read messages from motor in ReadTritium and trigger appropriate error messages as needed based on bits - * + * Read messages from motor in ReadTritium and trigger appropriate error + * messages as needed based on bits + * */ -typedef enum{ - T_HARDWARE_OVER_CURRENT_ERR = (1<<0), - T_SOFTWARE_OVER_CURRENT_ERR = (1<<1), - T_DC_BUS_OVERVOLT_ERR = (1<<2), - T_HALL_SENSOR_ERR = (1<<3), - T_WATCHDOG_LAST_RESET_ERR = (1<<4), - T_CONFIG_READ_ERR = (1<<5), - T_UNDER_VOLTAGE_LOCKOUT_ERR = (1<<6), - T_DESAT_FAULT_ERR = (1<<7), - T_MOTOR_OVER_SPEED_ERR = (1<<8), - T_INIT_FAIL = (1<<9), //motor controller fails to restart or initialize - T_MOTOR_WATCHDOG_TRIP = (1 << 15), - T_NONE = 0x00, -} tritium_error_code_t; +typedef enum { + kHardwareOverCurrentErr = (1 << 0), + kSoftwareOverCurrentErr = (1 << 1), + kDcBusOverVoltErr = (1 << 2), + kHallSensorErr = (1 << 3), + kWatchdogLastResetErr = (1 << 4), + kConfigReadErr = (1 << 5), + kUnderVoltageLockoutErr = (1 << 6), + kDesatFaultErr = (1 << 7), + kMotorOverSpeedErr = (1 << 8), + kInitFail = (1 << 9), // motor controller fails to restart or initialize + kMotorWatchdogTrip = (1 << 15), + kNone = 0x00, +} TritiumErrorCode; -float Motor_RPM_Get(); -float Motor_Velocity_Get(); +float MotorRpmGet(); +float MotorVelocityGet(); #endif - /* @} */ diff --git a/Apps/Inc/SendCarCAN.h b/Apps/Inc/SendCarCan.h similarity index 52% rename from Apps/Inc/SendCarCAN.h rename to Apps/Inc/SendCarCan.h index 99772bfb3..090a4611b 100644 --- a/Apps/Inc/SendCarCAN.h +++ b/Apps/Inc/SendCarCan.h @@ -1,23 +1,23 @@ -#ifndef __SENDCARCAN_H -#define __SENDCARCAN_H +#ifndef SENDCARCAN_H +#define SENDCARCAN_H -#include "CANbus.h" +#include "CanBus.h" /** * @brief Initialize SendCarCAN -*/ -void SendCarCAN_Init(); + */ +void SendCarCanInit(); /** * @brief Wrapper to put new message in the CAN queue -*/ -void SendCarCAN_Put(CANDATA_t message); + */ +void SendCarCanPut(CanData message); /** * @brief return the space left in SendCarCAN_Q for debug purposes -*/ + */ #ifdef DEBUG -uint8_t get_SendCarCAN_Q_Space(void); +uint8_t GetSendCarCanQueueSpace(void); #endif #endif \ No newline at end of file diff --git a/Apps/Inc/SendTritium.h b/Apps/Inc/SendTritium.h index 8791f3833..0568d8749 100644 --- a/Apps/Inc/SendTritium.h +++ b/Apps/Inc/SendTritium.h @@ -1,102 +1,82 @@ /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file SendTritium.h - * @brief - * + * @brief + * * @defgroup SendTritium * @addtogroup SendTritium * @{ */ -#ifndef __SENDTRITIUM_H -#define __SENDTRITIUM_H +#ifndef SENDTRITIUM_H +#define SENDTRITIUM_H #include "common.h" -//#define SENDTRITIUM_PRINT_MES +#define SENDTRITIUM_PRINT_MES +#define SENDTRITIUM_EXPOSE_VARS -#define MOTOR_MSG_PERIOD 100 // in ms -#define FSM_PERIOD 100 // in ms -#define DEBOUNCE_PERIOD 2 // in units of FSM_PERIOD -#define MOTOR_MSG_COUNTER_THRESHOLD (MOTOR_MSG_PERIOD)/(FSM_PERIOD) +#define MOTOR_MSG_PERIOD 100 // in ms +#define FSM_PERIOD 100 // in ms +#define DEBOUNCE_PERIOD 2 // in units of FSM_PERIOD +#define MOTOR_MSG_COUNTER_THRESHOLD ((MOTOR_MSG_PERIOD) / (FSM_PERIOD)) -#define FOREACH_Gear(GEAR) \ - GEAR(FORWARD_GEAR), \ - GEAR(NEUTRAL_GEAR), \ - GEAR(REVERSE_GEAR), \ +#define FOREACH_GEAR(GEAR) \ + GEAR(kForwardGear), GEAR(kNeutralGear), GEAR(kReverseGear), -typedef enum GEAR_ENUM { - FOREACH_Gear(GENERATE_ENUM) - NUM_GEARS, -} Gear_t; +typedef enum { + FOREACH_GEAR(GENERATE_ENUM) kNumGears, +} Gear; // State Names -typedef enum{ - FORWARD_DRIVE, - NEUTRAL_DRIVE, - REVERSE_DRIVE, - RECORD_VELOCITY, - POWERED_CRUISE, - COASTING_CRUISE, - BRAKE_STATE, - ONEPEDAL, - ACCELERATE_CRUISE -} TritiumStateName_t; +typedef enum { + kForwardDrive, + kNeutralDrive, + kReverseDrive, + kRecordVelocity, + kPoweredCruise, + kCoastingCruise, + kBrakeState, + kOnePedal, + kAccelerateCruise +} TritiumStateName; // State Struct for FSM -typedef struct TritiumState{ - TritiumStateName_t name; +typedef struct TritiumState { + TritiumStateName name; void (*stateHandler)(void); void (*stateDecider)(void); -} TritiumState_t; +} TritiumState; + +// Getter functions for static variables +bool GetCruiseEnable(void); +bool GetCruiseSet(void); +bool GetOnePedalEnable(void); +bool GetRegenEnable(void); +uint8_t GetBrakePedalPercent(void); +uint8_t GetAccelPedalPercent(void); +Gear GetGear(void); +TritiumState GetState(void); +float GetVelocityObserved(void); +float GetCruiseVelSetpoint(void); +float GetCurrentSetpoint(void); +float GetVelocitySetpoint(void); #ifdef SENDTRITIUM_EXPOSE_VARS -// Inputs -extern bool cruiseEnable; -extern bool cruiseSet; -extern bool onePedalEnable; -extern bool regenEnable; - -extern uint8_t brakePedalPercent; -extern uint8_t accelPedalPercent; - -extern Gear_t gear; - -extern TritiumState_t state; -extern float velocityObserved; -extern float cruiseVelSetpoint; -#endif - -// Getter functions for local variables in SendTritium.c -EXPOSE_GETTER(bool, cruiseEnable) -EXPOSE_GETTER(bool, cruiseSet) -EXPOSE_GETTER(bool, onePedalEnable) -EXPOSE_GETTER(bool, regenEnable) -EXPOSE_GETTER(uint8_t, brakePedalPercent) -EXPOSE_GETTER(uint8_t, accelPedalPercent) -EXPOSE_GETTER(Gear_t, gear) -EXPOSE_GETTER(TritiumState_t, state) -EXPOSE_GETTER(float, velocityObserved) -EXPOSE_GETTER(float, cruiseVelSetpoint) -EXPOSE_GETTER(float, currentSetpoint) -EXPOSE_GETTER(float, velocitySetpoint) - -// Setter functions for local variables in SendTritium.c -#ifdef SENDTRITIUM_EXPOSE_VARS -EXPOSE_SETTER(bool, cruiseEnable) -EXPOSE_SETTER(bool, cruiseSet) -EXPOSE_SETTER(bool, onePedalEnable) -EXPOSE_SETTER(bool, regenEnable) -EXPOSE_SETTER(uint8_t, brakePedalPercent) -EXPOSE_SETTER(uint8_t, accelPedalPercent) -EXPOSE_SETTER(Gear_t, gear) -EXPOSE_SETTER(TritiumState_t, state) -EXPOSE_SETTER(float, velocityObserved) -EXPOSE_SETTER(float, cruiseVelSetpoint) -EXPOSE_SETTER(float, currentSetpoint) -EXPOSE_SETTER(float, velocitySetpoint) +// Setter functions for static variables +void SetCruiseEnable(bool value); +void SetCruiseSet(bool value); +void SetOnePedalEnable(bool value); +void SetRegenEnable(bool value); +void SetBrakePedalPercent(uint8_t value); +void SetAccelPedalPercent(uint8_t value); +void SetGear(Gear value); +void SetState(TritiumState value); +void SetVelocityObserved(float value); +void SetCruiseVelSetpoint(float value); +void SetCurrentSetpoint(float value); +void SetVelocitySetpoint(float value); #endif #endif - /* @} */ diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index ad052d3d3..595a3d2b8 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -1,20 +1,19 @@ /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file Tasks.h - * @brief - * + * @brief + * * @defgroup Tasks * @addtogroup Tasks * @{ */ - -#ifndef __TASKS_H -#define __TASKS_H +#ifndef TASKS_H +#define TASKS_H #include "common.h" -#include "os.h" #include "config.h" +#include "os.h" /** * Task initialization macro @@ -26,162 +25,155 @@ /** * Priority Definitions - */ -#define TASK_INIT_PRIO 2 -#define TASK_READ_TRITIUM_PRIO 3 -#define TASK_SEND_TRITIUM_PRIO 4 -#define TASK_READ_CAR_CAN_PRIO 5 -#define TASK_SEND_CAR_CAN_PRIO 6 -#define TASK_PUT_IOSTATE_PRIO 7 -#define TASK_UPDATE_DISPLAY_PRIO 8 -#define TASK_DEBUG_DUMP_PRIO 9 -#define TASK_COMMAND_LINE_PRIO 10 + */ +#define TASK_INIT_PRIO 2 +#define TASK_READ_TRITIUM_PRIO 3 +#define TASK_SEND_TRITIUM_PRIO 4 +#define TASK_READ_CAR_CAN_PRIO 5 +#define TASK_SEND_CAR_CAN_PRIO 6 +#define TASK_PUT_IOSTATE_PRIO 7 +#define TASK_UPDATE_DISPLAY_PRIO 8 +#define TASK_DEBUG_DUMP_PRIO 9 +#define TASK_COMMAND_LINE_PRIO 10 /** * Stack Sizes */ -#define DEFAULT_STACK_SIZE 256 -#define WATERMARK_STACK_LIMIT DEFAULT_STACK_SIZE/2 - -#define TASK_INIT_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_SEND_TRITIUM_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_READ_CAR_CAN_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_UPDATE_DISPLAY_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_READ_TRITIUM_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_SEND_CAR_CAN_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_DEBUG_DUMP_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_COMMAND_LINE_STACK_SIZE DEFAULT_STACK_SIZE +#define DEFAULT_STACK_SIZE 256 +#define WATERMARK_STACK_LIMIT (DEFAULT_STACK_SIZE / 2) + +#define TASK_INIT_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_SEND_TRITIUM_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_READ_CAR_CAN_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_UPDATE_DISPLAY_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_READ_TRITIUM_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_SEND_CAR_CAN_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_DEBUG_DUMP_STACK_SIZE DEFAULT_STACK_SIZE +#define TASK_COMMAND_LINE_STACK_SIZE DEFAULT_STACK_SIZE /** * Task error variable type -*/ -typedef uint16_t error_code_t; + */ +typedef uint16_t ErrorCode; /** * Task Prototypes */ -void Task_Init(void* p_arg); - -void Task_SendTritium(void* p_arg); - -void Task_ReadCarCAN(void* p_arg); - -void Task_UpdateDisplay(void* p_arg); - -void Task_ReadTritium(void* p_arg); - -void Task_SendCarCAN(void* p_arg); - -void Task_DebugDump(void *p_arg); - -void Task_CommandLine(void* p_arg); - - +void TaskInit(void* p_arg); +void TaskSendTritium(void* p_arg); +void TaskReadCarCan(void* p_arg); +void TaskUpdateDisplay(void* p_arg); +void TaskReadTritium(void* p_arg); +void TaskSendCarCan(void* p_arg); +void TaskDebugDump(void* p_arg); +void TaskCommandLine(void* p_arg); /** * TCBs */ -extern OS_TCB Init_TCB; -extern OS_TCB SendTritium_TCB; -extern OS_TCB ReadCarCAN_TCB; -extern OS_TCB UpdateDisplay_TCB; -extern OS_TCB ReadTritium_TCB; -extern OS_TCB SendCarCAN_TCB; -extern OS_TCB DebugDump_TCB; -extern OS_TCB CommandLine_TCB; - +extern OS_TCB init_tcb; +extern OS_TCB send_tritium_tcb; +extern OS_TCB read_car_can_tcb; +extern OS_TCB update_display_tcb; +extern OS_TCB read_tritium_tcb; +extern OS_TCB send_car_can_tcb; +extern OS_TCB debug_dump_tcb; +extern OS_TCB command_line_tcb; /** * Stacks */ -extern CPU_STK Init_Stk[TASK_INIT_STACK_SIZE]; -extern CPU_STK SendTritium_Stk[TASK_SEND_TRITIUM_STACK_SIZE]; -extern CPU_STK ReadCarCAN_Stk[TASK_READ_CAR_CAN_STACK_SIZE]; -extern CPU_STK UpdateDisplay_Stk[TASK_UPDATE_DISPLAY_STACK_SIZE]; -extern CPU_STK ReadTritium_Stk[TASK_READ_TRITIUM_STACK_SIZE]; -extern CPU_STK SendCarCAN_Stk[TASK_SEND_CAR_CAN_STACK_SIZE]; -extern CPU_STK DebugDump_Stk[TASK_DEBUG_DUMP_STACK_SIZE]; -extern CPU_STK CommandLine_Stk[TASK_COMMAND_LINE_STACK_SIZE]; +extern CPU_STK init_stk[TASK_INIT_STACK_SIZE]; +extern CPU_STK send_tritium_stk[TASK_SEND_TRITIUM_STACK_SIZE]; +extern CPU_STK read_car_can_stk[TASK_READ_CAR_CAN_STACK_SIZE]; +extern CPU_STK update_display_stk[TASK_UPDATE_DISPLAY_STACK_SIZE]; +extern CPU_STK read_tritium_stk[TASK_READ_TRITIUM_STACK_SIZE]; +extern CPU_STK send_car_can_stk[TASK_SEND_CAR_CAN_STACK_SIZE]; +extern CPU_STK debug_dump_stk[TASK_DEBUG_DUMP_STACK_SIZE]; +extern CPU_STK command_line_stk[TASK_COMMAND_LINE_STACK_SIZE]; /** * Queues */ -extern OS_Q CANBus_MsgQ; +extern OS_Q can_bus_msg_q; /** * @brief Initialize the task switch hook * Registers the hook with the RTOS */ -void TaskSwHook_Init(void); +void TaskSwHookInit(void); /** * Task trace - * + * * Stores the last TASK_TRACE_LENGTH tasks that were run * The most recent task is at tasks[index], the one before at tasks[index-1], * wrapping back around at the beginnning - * + * */ #define TASK_TRACE_LENGTH 8 typedef struct { - OS_TCB *tasks[TASK_TRACE_LENGTH]; + OS_TCB* tasks[TASK_TRACE_LENGTH]; uint32_t index; -} task_trace_t; +} TaskTrace; -extern task_trace_t PrevTasks; +extern TaskTrace prev_tasks; // Store error codes that are set in task error assertion functions -extern error_code_t Error_ReadTritium; -extern error_code_t Error_ReadCarCAN; -extern error_code_t Error_UpdateDisplay; +extern ErrorCode error_read_tritium; +extern ErrorCode error_read_car_can; +extern ErrorCode error_update_display; /** * Error-handling option enums -*/ + */ // Scheduler lock parameter option for asserting a task error -typedef enum { - OPT_NO_LOCK_SCHED, - OPT_LOCK_SCHED -} error_scheduler_lock_opt_t; +typedef enum { kOptNoLockSched, kOptLockSched } ErrorSchedulerLockOpt; // Recoverable/nonrecoverable parameter option for asserting a task error -typedef enum { - OPT_RECOV, - OPT_NONRECOV -} error_recov_opt_t; +typedef enum { kOptRecov, kOptNonrecov } ErrorRecovOpt; /** - * @brief For use in error handling: opens array and motor precharge bypass contactor - * and turns on additional brakelight to signal that a critical error happened. -*/ + * @brief For use in error handling: opens array and motor precharge bypass + * contactor and turns on additional brakelight to signal that a critical error + * happened. + */ void EmergencyContactorOpen(); /** - * @brief Assert a task error by setting the location variable and optionally locking the scheduler, - * displaying a fault screen (if nonrecoverable), jumping to a callback function, and entering an infinite loop. - * Called by task-specific error-assertion functions that are also responsible for setting the error variable. + * @brief Assert a task error by setting the location variable and optionally + * locking the scheduler, displaying a fault screen (if nonrecoverable), jumping + * to a callback function, and entering an infinite loop. Called by + * task-specific error-assertion functions that are also responsible for setting + * the error variable. * @param errorCode the enum for the specific error that happened - * @param errorCallback a callback function to a handler for that specific error, - * @param lockSched whether or not to lock the scheduler to ensure the error is handled immediately - * @param nonrecoverable whether or not to kill the motor, display the fault screen, and enter an infinite while loop -*/ -void throwTaskError(error_code_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable); + * @param errorCallback a callback function to a handler for that specific + * error, + * @param lockSched whether or not to lock the scheduler to ensure the error is + * handled immediately + * @param nonrecoverable whether or not to kill the motor, display the fault + * screen, and enter an infinite while loop + */ +void ThrowTaskError(ErrorCode error_code, Callback error_callback, + ErrorSchedulerLockOpt lock_sched, + ErrorRecovOpt nonrecoverable); /** * @brief Assert Error if OS function call fails * @param err OS Error that occurred */ -void _assertOSError (OS_ERR err); //TODO: This should be changed to enforce only enum usage +void AssertOsError(OS_ERR err); #if DEBUG == 1 -#define assertOSError(err) \ - if (err != OS_ERR_NONE) { \ - printf("Error asserted at %s, line %d: %d\n\r", __FILE__, __LINE__, err); \ - } \ - _assertOSError(err); +#define ASSERT_OS_ERROR(err) \ + if (err != OS_ERR_NONE) { \ + printf("Error asserted at %s, line %d: %d\n\r", __FILE__, __LINE__, \ + err); \ + } \ + AssertOsError(err); #else -#define assertOSError(err) _assertOSError(err); +#define ASSERT_OS_ERROR(err) AssertOsError(err); #endif #endif diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index 12cb5ca99..07b0ebf79 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -2,140 +2,134 @@ * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file UpdateDisplay.h * @brief Function prototypes for the display application. - * + * * This contains function prototypes relevant to the UpdateDisplay * application. Call assertUpdateDisplayError after calling any of the * functions in this application. - * - * + * + * * @defgroup UpdateDisplay * @addtogroup UpdateDisplay * @{ */ -#ifndef __UPDATE_DISPLAY_H -#define __UPDATE_DISPLAY_H - -#include "os.h" -#include "common.h" -#include "Tasks.h" +#ifndef UPDATE_DISPLAY_H +#define UPDATE_DISPLAY_H #include "Display.h" -#include "Contactors.h" +#include "common.h" /** * Error types */ -typedef enum{ - UPDATEDISPLAY_ERR_NONE, - UPDATEDISPLAY_ERR_FIFO_PUT, // Error putting command in fifo - UPDATEDISPLAY_ERR_FIFO_POP, // Error popping command from fifo - UPDATEDISPLAY_ERR_PARSE_COMP, // Error parsing component/val in SetComponent - UPDATEDISPLAY_ERR_DRIVER // Driver call returned an error -} UpdateDisplayError_t; +typedef enum { + kUpdateDisplayErrNone, + kUpdateDisplayErrFifoPut, // Error putting command in fifo + kUpdateDisplayErrFifoPop, // Error popping command from fifo + kUpdateDisplayErrParseComp, // Error parsing component/val in SetComponent + kUpdateDisplayErrDriver // Driver call returned an error +} UpdateDisplayError; /** * For display elements with three states */ -typedef enum{ - STATE_0 =0, - STATE_1 =1, - STATE_2 =2 -} TriState_t; +typedef enum { kState0 = 0, kState1 = 1, kState2 = 2 } TriState; // For cruise control and regen -#define DISP_DISABLED STATE_0 -#define DISP_ENABLED STATE_1 // Able to be used -#define DISP_ACTIVE STATE_2 // Actively being used right now +#define DISP_DISABLED kState0 +#define DISP_ENABLED kState1 // Able to be used +#define DISP_ACTIVE kState2 // Actively being used right now // For gear changes -#define DISP_NEUTRAL STATE_0 -#define DISP_FORWARD STATE_1 -#define DISP_REVERSE STATE_2 +#define DISP_NEUTRAL kState0 +#define DISP_FORWARD kState1 +#define DISP_REVERSE kState2 /** * @brief Initializes UpdateDisplay application * @returns UpdateDisplayError_t */ -UpdateDisplayError_t UpdateDisplay_Init(); +UpdateDisplayError UpdateDisplayInit(); /** * @brief Selects visible page on the display * @param page which page to select * @returns UpdateDisplayError_t */ -UpdateDisplayError_t UpdateDisplay_SetPage(Page_t page); +UpdateDisplayError UpdateDisplaySetPage(Page page); /** * @brief Sets the state of charge value on the display * @param percent charge as a percent (0 digits of precision) * @returns UpdateDisplayError_t */ -UpdateDisplayError_t UpdateDisplay_SetSOC(uint8_t percent); +UpdateDisplayError UpdateDisplaySetSoc(uint8_t percent); /** * @brief Sets the supplemental battery pack voltage value on the display * @param mv supplemental battery pack voltage in millivolts * @returns UpdateDisplayError_t */ -UpdateDisplayError_t UpdateDisplay_SetSBPV(uint32_t mv); +UpdateDisplayError UpdateDisplaySetSbpv(uint32_t mv); /** * @brief Sets the velocity of the vehicle on the display - * @param mphTenths velocity of the vehicle in tenths of mph (1 digit of precision) + * @param mphTenths velocity of the vehicle in tenths of mph (1 digit of + * precision) * @returns UpdateDisplayError_t */ -UpdateDisplayError_t UpdateDisplay_SetVelocity(uint32_t mphTenths); +UpdateDisplayError UpdateDisplaySetVelocity(uint32_t mph_tenths); /** * @brief Sets the accelerator slider value on the display * @param percent pressure on accelerator in percent * @returns UpdateDisplayError_t */ -UpdateDisplayError_t UpdateDisplay_SetAccel(uint8_t percent); +UpdateDisplayError UpdateDisplaySetAccel(uint8_t percent); /** * @brief Sets the array indicator state on the display * @param state array contactor on (true) or off (false) * @returns UpdateDisplayError_t */ -UpdateDisplayError_t UpdateDisplay_SetArray(bool state); +UpdateDisplayError UpdateDisplaySetArray(bool state); /** * @brief Sets the motor contactor indicator state on the display * @param state motor contactor on (true) or off (false) * @returns UpdateDisplayError_t */ -UpdateDisplayError_t UpdateDisplay_SetMotor(bool state); +UpdateDisplayError UpdateDisplaySetMotor(bool state); /** * @brief Sets the gear selection state on the display * @param gear DISABLED=N, ENABLED=F, ACTIVE=R * @returns UpdateDisplayError_t */ -UpdateDisplayError_t UpdateDisplay_SetGear(TriState_t gear); +UpdateDisplayError UpdateDisplaySetGear(TriState gear); /** * @brief Sets the regenerative braking indicator state on the display * @param state DISABLED, ENABLED, or ACTIVE * @returns UpdateDisplayError_t */ -UpdateDisplayError_t UpdateDisplay_SetRegenState(TriState_t state); +UpdateDisplayError UpdateDisplaySetRegenState(TriState state); /** * @brief Sets the cruise control indicator state on the display * @param state DISABLED, ENABLED, or ACTIVE * @returns UpdateDisplayError_t */ -UpdateDisplayError_t UpdateDisplay_SetCruiseState(TriState_t state); +UpdateDisplayError UpdateDisplaySetCruiseState(TriState state); /** - * @brief Clears the display message queue and sets the message counter semaphore value to 0 + * @brief Clears the display message queue and sets the message counter + * semaphore value to 0 * @param none * @returns none -*/ -void UpdateDisplay_ClearQueue(void); + */ +void UpdateDisplayClearQueue(void); #endif /* @} */ diff --git a/Apps/Inc/common.h b/Apps/Inc/common.h index 3c5d7722e..df1f928aa 100644 --- a/Apps/Inc/common.h +++ b/Apps/Inc/common.h @@ -1,66 +1,43 @@ /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file common.h - * @brief - * + * @brief + * * @defgroup common * @addtogroup common * @{ */ -#ifndef __COMMON_H -#define __COMMON_H +#ifndef COMMON_H +#define COMMON_H #include -#include +#include #include +#include #include -#include #include -#include +#include + #include "config.h" /* Used for generating ENUMS */ #define GENERATE_ENUM(ENUM) ENUM #define GENERATE_STRING(STRING) #STRING -/** - * Used for creating getter functions (returns the value based on given inputs) - * - * GETTER is used for creating the function and EXPOSE_GETTER is used for creating the declaration in the header file - */ -#define GETTER(type, name) \ - type get_##name(void){ \ - return name; \ - } \ - -#define EXPOSE_GETTER(type, name) \ - type get_##name(void); \ +typedef void (*Callback)(void); -/** - * Used for creating setter functions (sets the value based on given inputs) - * - * SETTER is used for creating the function and EXPOSE_SETTER is used for creating the declaration in the header file - */ -#define SETTER(type, name) \ - void set_##name(type val){ \ - name = val; \ - } \ +void PrintFloat(char *str, float value); -#define EXPOSE_SETTER(type, name) \ - void set_##name(type val); \ - -typedef void (*callback_t)(void); - -void print_float(char *str, float f); +#define SEC_PER_MIN 60 /** * @brief Meters per second to rpm conversion * @param velocity_mps velocity in meters per second * @returns rpm -*/ -inline float mpsToRpm(float velocity_mps){ - return (velocity_mps * 60) / WHEEL_CIRCUMFERENCE; + */ +inline float MpsToRpm(float velocity_mps) { + return (float)((velocity_mps * SEC_PER_MIN) / WHEEL_CIRCUMFERENCE); } #endif diff --git a/Apps/Inc/fifo.h b/Apps/Inc/fifo.h index 2f821c91d..94ed8b18d 100644 --- a/Apps/Inc/fifo.h +++ b/Apps/Inc/fifo.h @@ -1,8 +1,8 @@ /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file fifo.h - * @brief - * + * @brief + * * @defgroup fifo * @addtogroup fifo * @{ @@ -10,10 +10,10 @@ /* * This file implements a fifo. - * - * In order to use it in another file, you must import it in + * + * In order to use it in another file, you must import it in * a particular way. - * + * * 1. Define your data type, like so * #define FIFO_TYPE int * 2. Define your fifo size, like so @@ -22,26 +22,28 @@ * #define FIFO_NAME my_fifo * 4. Import this file * #include "fifo.h" - * + * * This file includes some defaults, but they might not work for * your case! - * + * * Also, this file undef's everything at the end, so you can import * multiple times if you need. - * + * * If FIFO_NAME == my_fifo, then your new data structure will be * called my_fifo_t. - * + * * NOTE: importantly, this does not currently support usage from * header files. That is, all these types/functions are statically * declared, so there cannot be a non-static fifo at the moment. */ // The header guard only guard the import, -// since this file can be imported multiple times -#ifndef __FIFO_H -#define __FIFO_H +// since this file can be imported multiple times +#ifndef FIFO_H +#define FIFO_H #include +#include +#include #endif // The type of the fifo @@ -60,12 +62,12 @@ #endif // Utility definitions -#define _CONCAT(A, B) A ## B +#define _CONCAT(A, B) A##B #define CONCAT(A, B) _CONCAT(A, B) // Type names -#define FIFO_STRUCT_NAME CONCAT(FIFO_NAME, _s) -#define FIFO_TYPE_NAME CONCAT(FIFO_NAME, _t) +#define FIFO_STRUCT_NAME FIFO_NAME +#define FIFO_TYPE_NAME FIFO_NAME // The actual structure typedef struct FIFO_STRUCT_NAME { @@ -75,25 +77,24 @@ typedef struct FIFO_STRUCT_NAME { } FIFO_TYPE_NAME; // Define some names for our functions -#define IS_EMPTY CONCAT(FIFO_NAME, _is_empty) -#define IS_FULL CONCAT(FIFO_NAME, _is_full) -#define GET CONCAT(FIFO_NAME, _get) -#define PUT CONCAT(FIFO_NAME, _put) -#define NEW CONCAT(FIFO_NAME, _new) -#define PEEK CONCAT(FIFO_NAME, _peek) -#define POPBACK CONCAT(FIFO_NAME, _popback) -#define RENEW CONCAT(FIFO_NAME, _renew) +#define IS_EMPTY CONCAT(FIFO_NAME, IsEmpty) +#define IS_FULL CONCAT(FIFO_NAME, IsFull) +#define GET CONCAT(FIFO_NAME, Get) +#define PUT CONCAT(FIFO_NAME, Put) +#define NEW CONCAT(FIFO_NAME, New) +#define PEEK CONCAT(FIFO_NAME, Peek) +#define POPBACK CONCAT(FIFO_NAME, PopBack) +#define RENEW CONCAT(FIFO_NAME, Renew) /** * @brief Initialize a new fifo - * + * * If the type of the fifo is myfifo_t, then this function - * will be called myfifo_new(). - * + * will be called myfifoNew(). + * * @return an empty fifo */ -static inline FIFO_TYPE_NAME __attribute__((unused)) -NEW () { +static inline FIFO_TYPE_NAME __attribute__((unused)) NEW() { FIFO_TYPE_NAME fifo; memset(&fifo, 0, sizeof(fifo)); return fifo; @@ -101,62 +102,56 @@ NEW () { /** * @brief Initialize a fifo by reference. - * - * This is going to be faster than _new(). + * + * This is going to be faster than New(). * This does not erase all of the contents of the fifo, but * rather marks it as "empty". */ -static inline void __attribute__((unused)) -RENEW (FIFO_TYPE_NAME * fifo) { - if(fifo != NULL) { +static inline void __attribute__((unused)) RENEW(FIFO_TYPE_NAME *fifo) { + if (fifo != NULL) { fifo->get = fifo->put; } } /** * @brief Determine whether the fifo is empty. - * + * * If the type of the fifo is myfifo_t, then this function - * will be called myfifo_is_empty(). - * + * will be called myfifoIsEmpty(). + * * @param fifo A pointer to the fifo * @return true If empty * @return false If not empty */ -static bool -IS_EMPTY (FIFO_TYPE_NAME *fifo) { - return fifo->put == fifo->get; -} +static bool IS_EMPTY(FIFO_TYPE_NAME *fifo) { return fifo->put == fifo->get; } /** * @brief Determine whether the fifo is full. - * + * * If the type of the fifo is myfifo_t, then this function - * will be called myfifio_is_full(). - * + * will be called myfifioIsFull(). + * * @param fifo A pointer to the fifo * @return true If full * @return false If not full */ -static bool -IS_FULL (FIFO_TYPE_NAME *fifo) { +static bool IS_FULL(FIFO_TYPE_NAME *fifo) { return (fifo->put + 1) % FIFO_SIZE == fifo->get; } /** * @brief Get the next element from the fifo - * + * * If the type of the fifo is myfifo_t, then this function - * will be called myfifo_get(). - * + * will be called myfifoGet(). + * * @param fifo A pointer to the fifo * @param elem A pointer to an element to use for storage * @return true if successful * @return false if unsuccessful */ -static bool __attribute__((unused)) -GET (FIFO_TYPE_NAME *fifo, FIFO_TYPE *elem) { - if(!IS_EMPTY(fifo)) { +static bool __attribute__((unused)) GET(FIFO_TYPE_NAME *fifo, FIFO_TYPE *elem) { + if (!IS_EMPTY(fifo)) { *elem = fifo->buffer[fifo->get]; fifo->get = (fifo->get + 1) % FIFO_SIZE; return true; @@ -167,18 +162,17 @@ GET (FIFO_TYPE_NAME *fifo, FIFO_TYPE *elem) { /** * @brief Put an element into the fifo - * + * * If the type of the fifo is myfifo_t, then this function - * will be called myfifo_put(). - * + * will be called myfifoPut(). + * * @param fifo A pointer to the fifo * @param elem The element to put * @return true if successful * @return false if unsuccessful */ -static bool __attribute__((unused)) -PUT (FIFO_TYPE_NAME *fifo, FIFO_TYPE elem) { - if(!IS_FULL(fifo)) { +static bool __attribute__((unused)) PUT(FIFO_TYPE_NAME *fifo, FIFO_TYPE elem) { + if (!IS_FULL(fifo)) { fifo->buffer[fifo->put] = elem; fifo->put = (fifo->put + 1) % FIFO_SIZE; return true; @@ -189,18 +183,18 @@ PUT (FIFO_TYPE_NAME *fifo, FIFO_TYPE elem) { /** * @brief Peek into the fifo - * + * * If the type of the fifo is myfifo_t, then this function - * will be called myfifo_peek(). - * + * will be called myfifoPeek(). + * * @param fifo A pointer to the fifo * @param elem A pointer to space where the next element will be put * @return true if successful * @return false if unsuccessful */ static bool __attribute__((unused)) -PEEK (FIFO_TYPE_NAME *fifo, FIFO_TYPE *elem) { - if(!IS_EMPTY(fifo)) { +PEEK(FIFO_TYPE_NAME *fifo, FIFO_TYPE *elem) { + if (!IS_EMPTY(fifo)) { *elem = fifo->buffer[fifo->get]; return true; } @@ -210,18 +204,18 @@ PEEK (FIFO_TYPE_NAME *fifo, FIFO_TYPE *elem) { /** * @brief Take the last element of the fifo (most recent) - * + * * If the type of the fifo is myfifo_t, then this function - * will be called myfifo_popback(). - * + * will be called myfifoPopBack(). + * * @param fifo A pointer to the fifo * @param elem A pointer to space to put the element * @return true if successful * @return false if unsuccessful */ static bool __attribute__((unused)) -POPBACK (FIFO_TYPE_NAME *fifo, FIFO_TYPE *elem) { - if(!IS_EMPTY(fifo)) { +POPBACK(FIFO_TYPE_NAME *fifo, FIFO_TYPE *elem) { + if (!IS_EMPTY(fifo)) { fifo->put = (fifo->put + FIFO_SIZE - 1) % FIFO_SIZE; *elem = fifo->buffer[fifo->put]; return true; diff --git a/Apps/Src/CommandLine.c b/Apps/Src/CommandLine.c index 369759342..3d13b668d 100644 --- a/Apps/Src/CommandLine.c +++ b/Apps/Src/CommandLine.c @@ -2,348 +2,328 @@ #include #include #include -#include "os.h" -#include "Tasks.h" + #include "BSP_UART.h" -#include "CANbus.h" +#include "CanBus.h" #include "Contactors.h" #include "Minions.h" #include "Pedals.h" +#include "Tasks.h" +#include "os.h" + +#define MAX_BUFFER_SIZE 128 // defined from BSP_UART_Read function + +#define CAN_DIAG_ID 0x0582 -#define MAX_BUFFER_SIZE 128 // defined from BSP_UART_Read function +#define TAB 0x09 +#define LF 0x0A +#define FF 0x0C +#define CR 0x0D +#define SPACE 0x20 // Represents a command that the command line understands struct Command { - const char *name; - bool (*action)(void); + const char *name; + bool (*action)(void); }; -static bool cmd_help(void); - -static bool cmd_CANbus_Send(void); - -static bool cmd_CANbus_Read(void); - -static bool cmd_Contactors_Get(void); - -static bool cmd_Contactors_Set(void); - -static bool cmd_Minions_Read(void); - -static bool cmd_Minions_Write(void); - -static bool cmd_Pedals_Read(void); - - -const struct Command cmdline_commands[] = { - {.name = "help", .action = cmd_help}, - {.name = "CANbus_Send", .action = cmd_CANbus_Send}, - {.name = "CANbus_Read", .action = cmd_CANbus_Read}, - {.name = "Contactors_Get", .action = cmd_Contactors_Get}, - {.name = "Contactors_Set", .action = cmd_Contactors_Set}, - {.name = "Minions_Read", .action = cmd_Minions_Read}, - {.name = "Minions_Write", .action = cmd_Minions_Write}, - {.name = "Pedals_Read", .action = cmd_Pedals_Read}, - {.name = NULL, .action = NULL} -}; +static bool cmdHelp(void); +static bool cmdCanBusSend(void); +static bool cmdCanBusRead(void); +static bool cmdContactorsGet(void); +static bool cmdContactorsSet(void); +static bool cmdMinionsRead(void); +static bool cmdMinionsWrite(void); +static bool cmdPedalsRead(void); + +const struct Command kCmdlineCommands[] = { + {.name = "help", .action = cmdHelp}, + {.name = "CANbus_Send", .action = cmdCanBusSend}, + {.name = "CANbus_Read", .action = cmdCanBusRead}, + {.name = "Contactors_Get", .action = cmdContactorsGet}, + {.name = "Contactors_Set", .action = cmdContactorsSet}, + {.name = "Minions_Read", .action = cmdMinionsRead}, + {.name = "Minions_Write", .action = cmdMinionsWrite}, + {.name = "Pedals_Read", .action = cmdPedalsRead}, + {.name = NULL, .action = NULL}}; static char input[MAX_BUFFER_SIZE]; -char *save; // Save pointer for strtok_r +char *save; // Save pointer for strtok_r char *help = { - "LHRS Controls Command Line:\n\r" - " For help, enter [help]\n\r" - " Format is: cmd [param, ...]\n\r" - " Commands and their params are as follows:\n\r" - " CANbus_Send (non)blocking motor/car 'string' - Sends a CAN\n\r" - "message with the string data as is on the determined line\n\r" - " CANbus_Read (non)blocking motor/car - Reads a CAN message\n\r" - "on the detemined line\n\r" - " Contactors_Get array_c/array_p/motor_c - Gets the status of\n\r" - "determined contactor\n\r" - " Contactors_Set array_c/array_p/motor_c on/off (non)blocking -\n\r" - "Sets the determined contactor\n\r" - " Contactors_Enable array_c/array_p/motor_c - Enables the determined\n\r" - "contactor\n\r" - " Contactors_Disable array_c/array_p/motor_c - Disables the determined\n\r" - "contactor\n\r" - " Minions_Read 'input' - Reads the current status of the input\n\r" - " Minions_Write `output` on/off - Sets the current state of the output\n\r" - " Pedals_Read accel/brake - Reads the current status of the pedal\n\r" -}; - -static inline bool isWhiteSpace(char character){ - switch (character) { - case 0x09: - case 0x0A: - case 0x0C: - case 0x0D: - case 0x20: return true; - default: return false; - } + "LHRS Controls Command Line:\n\r" + " For help, enter [help]\n\r" + " Format is: cmd [param, ...]\n\r" + " Commands and their params are as follows:\n\r" + " CANbus_Send (non)blocking motor/car 'string' - Sends a CAN\n\r" + "message with the string data as is on the determined line\n\r" + " CANbus_Read (non)blocking motor/car - Reads a CAN message\n\r" + "on the detemined line\n\r" + " Contactors_Get array_c/array_p/motor_c - Gets the status of\n\r" + "determined contactor\n\r" + " Contactors_Set array_c/array_p/motor_c on/off (non)blocking -\n\r" + "Sets the determined contactor\n\r" + " Contactors_Enable array_c/array_p/motor_c - Enables the determined\n\r" + "contactor\n\r" + " Contactors_Disable array_c/array_p/motor_c - Disables the " + "determined\n\r" + "contactor\n\r" + " Minions_Read 'input' - Reads the current status of the input\n\r" + " Minions_Write `output` on/off - Sets the current state of the " + "output\n\r" + " Pedals_Read accel/brake - Reads the current status of the pedal\n\r"}; + +static inline bool isWhiteSpace(char character) { + switch (character) { + case TAB: + case LF: + case FF: + case CR: + case SPACE: + return true; + default: + return false; + } } static bool executeCommand(char *input) { - // The first word in the input should be a valid command - char *command = strtok_r(input, " ", &save); - // Iterate through all valid commands and check if the input matches (exits if the action is NULL (acts as a sentinal)) - for (int i=0; cmdline_commands[i].action; i++) { - if (!strcmp(command, cmdline_commands[i].name)) { - return cmdline_commands[i].action(); // Execute the command - } - } - return false; // Didn't find a valid command! + // The first word in the input should be a valid command + char *command = strtok_r(input, " ", &save); + // Iterate through all valid commands and check if the input matches (exits + // if the action is NULL (acts as a sentinal)) + for (int i = 0; kCmdlineCommands[i].action; i++) { + if (!strcmp(command, kCmdlineCommands[i].name)) { + return kCmdlineCommands[i].action(); // Execute the command + } + } + return false; // Didn't find a valid command! } // *********** Command line (shell) ************ -void Task_CommandLine(void* p_arg) { - OS_ERR err; - - // output welcome/help screen - printf(help); - - while(1){ - printf("> "); - BSP_UART_Read(UART_2, input); - printf("\n\r"); - - if (!executeCommand(input)) { // If command failed, error - printf("Bad cmd. Please try again\n\r"); - } - } +void TaskCommandLine(void *p_arg) { + OS_ERR err = 0; + + // output welcome/help screen + printf("%s", help); + + while (1) { + printf("> "); + BspUartRead(kUart2, input); + printf("\n\r"); + + if (!executeCommand(input)) { // If command failed, error + printf("Bad cmd. Please try again\n\r"); + } + } // Delay of 1 seconds OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); - if (err != OS_ERR_NONE){ - assertOSError(err); + if (err != OS_ERR_NONE) { + ASSERT_OS_ERROR(err); } } // Function Implementations // ------------------------------------------------------------------------ -static inline bool cmd_help(void) { - printf(help); - return true; +static inline bool cmdHelp(void) { + printf("%s", help); + return true; } -/* This has not been tested and not sure if this implementation is correct (not sure -if we want to just transmit string data from serial) */ -static bool cmd_CANbus_Send(void){ - char *data = strtok_r(NULL, " ", &save); - CANDATA_t msg = {.ID=0x0582, .idx=0}; // this would change in the future (don't assume char as data) - for(int i = 0; i < 8 && i < strlen(data); i++){ - msg.data[i] = data[i]; - } - - char *blockInput = strtok_r(NULL, " ", &save); - bool blocking; - if(strcmp(blockInput, "blocking") == 0){ - blocking = CAN_BLOCKING; - } - else if(strcmp(blockInput, "nonblocking") == 0){ - blocking = CAN_NON_BLOCKING; - } - else{ - return false; - } - - char *busInput = strtok_r(NULL, " ", &save); - CAN_t bus; - if(strcmp(busInput, "motor") == 0){ - bus = CAN_1; - } - else if(strcmp(busInput, "car") == 0){ - bus = CAN_3; - } - else{ - return false; - } - - if(CANbus_Send(msg, blocking, bus)){ - printf("msg sent on %s (%s)\n\r", "can", blockInput); - }else{ - printf("msg sent failed\n\r"); - } - return true; +/* This has not been tested and not sure if this implementation is correct (not +sure if we want to just transmit string data from serial) */ +static bool cmdCanBusSend(void) { + char *data = strtok_r(NULL, " ", &save); + CanData msg = { + .id = CAN_DIAG_ID, + .idx = + 0}; // this would change in the future (don't assume char as data) + for (int i = 0; i < BSP_CAN_DATA_LENGTH && i < strlen(data); i++) { + msg.data[i] = data[i]; + } + + char *block_input = strtok_r(NULL, " ", &save); + bool blocking = false; + if (strcmp(block_input, "blocking") == 0) { + blocking = CAN_BLOCKING; + } else if (strcmp(block_input, "nonblocking") == 0) { + blocking = CAN_NON_BLOCKING; + } else { + return false; + } + + char *bus_input = strtok_r(NULL, " ", &save); + Can bus = 0; + if (strcmp(bus_input, "motor") == 0) { + bus = kCan1; + } else if (strcmp(bus_input, "car") == 0) { + bus = kCan3; + } else { + return false; + } + + if (CanBusSend(msg, blocking, bus)) { + printf("msg sent on %s (%s)\n\r", "can", block_input); + } else { + printf("msg sent failed\n\r"); + } + return true; } -static bool cmd_CANbus_Read(void){ - CANDATA_t msg; - - char *blockInput = strtok_r(NULL, " ", &save); - bool blocking; - if(strcmp(blockInput, "blocking") == 0){ - blocking = CAN_BLOCKING; - } - else if(strcmp(blockInput, "nonblocking") == 0){ - blocking = CAN_NON_BLOCKING; - } - else{ - return false; - } - - char *busInput = strtok_r(NULL, " ", &save); - CAN_t bus; - if(strcmp(busInput, "motor") == 0){ - bus = CAN_1; - } - else if(strcmp(busInput, "car") == 0){ - bus = CAN_3; - } - else{ - return false; - } - - if(CANbus_Read(&msg, blocking, bus) == SUCCESS){ - printf("msg received on %s (%s)\n\r", busInput, blockInput); - printf("ID: %d, Data: ", msg.ID); - for(int i = 0; i < 8; i++){ - printf("[%d] %x \n\r", i, msg.data[i]); - } - }else{ - printf("read failed on %s (%s)\n\r", busInput, blockInput); - } - return true; +static bool cmdCanBusRead(void) { + CanData msg; + + char *block_input = strtok_r(NULL, " ", &save); + bool blocking = false; + if (strcmp(block_input, "blocking") == 0) { + blocking = CAN_BLOCKING; + } else if (strcmp(block_input, "nonblocking") == 0) { + blocking = CAN_NON_BLOCKING; + } else { + return false; + } + + char *bus_input = strtok_r(NULL, " ", &save); + Can bus = 0; + if (strcmp(bus_input, "motor") == 0) { + bus = kCan1; + } else if (strcmp(bus_input, "car") == 0) { + bus = kCan3; + } else { + return false; + } + + if (CanBusRead(&msg, blocking, bus) == SUCCESS) { + printf("msg received on %s (%s)\n\r", bus_input, block_input); + printf("ID: %d, Data: ", msg.id); + for (int i = 0; i < CAN_DIAG_ID; i++) { + printf("[%d] %x \n\r", i, msg.data[i]); + } + } else { + printf("read failed on %s (%s)\n\r", bus_input, block_input); + } + return true; } -static bool cmd_Contactors_Get(void){ - char *contactorInput = strtok_r(NULL, " ", &save); - contactor_t contactor; - if(strcmp(contactorInput, "array_p") == 0){ - contactor = ARRAY_PRECHARGE_BYPASS_CONTACTOR; - } - else if(strcmp(contactorInput, "motor_p") == 0){ - contactor = MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR; - } - else{ - return false; - } - - printf("%s state: %s\n\r", contactorInput, Contactors_Get(contactor) == ON ? "on" : "off"); - return true; +static bool cmdContactorsGet(void) { + char *contactor_input = strtok_r(NULL, " ", &save); + Contactor contactor = 0; + if (strcmp(contactor_input, "array_p") == 0) { + contactor = kArrayPrechargeBypassContactor; + } else if (strcmp(contactor_input, "motor_p") == 0) { + contactor = kMotorControllerPrechargeBypassContactor; + } else { + return false; + } + + printf("%s state: %s\n\r", contactor_input, + ContactorsGet(contactor) == ON ? "on" : "off"); + return true; } -static bool cmd_Contactors_Set(void){ - char *contactorInput = strtok_r(NULL, " ", &save); - contactor_t contactor; - if(strcmp(contactorInput, "array_p") == 0){ - contactor = ARRAY_PRECHARGE_BYPASS_CONTACTOR; - } - else if(strcmp(contactorInput, "motor_p") == 0){ - contactor = MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR; - } - else{ - return false; - } - - char *stateInput = strtok_r(NULL, " ", &save); - bool state; - if(strcmp(stateInput, "on") == 0){ - state = true; - } - else if(strcmp(stateInput, "off") == 0){ - state = false; - } - else{ - return false; - } - - char *blockingInput = strtok_r(NULL, " ", &save); - bool blocking; - if(strcmp(blockingInput, "blocking") == 0){ - blocking = true; - } - else if(strcmp(blockingInput, "nonblocking") == 0){ - blocking = false; - } - else{ - return false; - } - - if(Contactors_Set(contactor, state, blocking)){ - printf("%s set to %s (%s)\n\r", contactorInput, stateInput, blockingInput); - }else{ - printf("set failed\n\r"); - } - return true; +static bool cmdContactorsSet(void) { + char *contactor_input = strtok_r(NULL, " ", &save); + Contactor contactor = 0; + if (strcmp(contactor_input, "array_p") == 0) { + contactor = kArrayPrechargeBypassContactor; + } else if (strcmp(contactor_input, "motor_p") == 0) { + contactor = kMotorControllerPrechargeBypassContactor; + } else { + return false; + } + + char *state_input = strtok_r(NULL, " ", &save); + bool state = false; + if (strcmp(state_input, "on") == 0) { + state = true; + } else if (strcmp(state_input, "off") == 0) { + state = false; + } else { + return false; + } + + char *blocking_input = strtok_r(NULL, " ", &save); + bool blocking = false; + if (strcmp(blocking_input, "blocking") == 0) { + blocking = true; + } else if (strcmp(blocking_input, "nonblocking") == 0) { + blocking = false; + } else { + return false; + } + + if (ContactorsSet(contactor, state, blocking)) { + printf("%s set to %s (%s)\n\r", contactor_input, state_input, + blocking_input); + } else { + printf("set failed\n\r"); + } + return true; } -static bool cmd_Minions_Read(void){ - char *pinInput = strtok_r(NULL, " ", &save); - pin_t pin; - if(strcmp(pinInput, "ign_1") == 0){ - pin = IGN_1; - } - else if(strcmp(pinInput, "ign_2") == 0){ - pin = IGN_2; - } - else if(strcmp(pinInput, "regen_sw") == 0){ - pin = REGEN_SW; - } - else if(strcmp(pinInput, "for_sw") == 0){ - pin = FOR_SW; - } - else if(strcmp(pinInput, "rev_sw") == 0){ - pin = REV_SW; - } - else if(strcmp(pinInput, "cruz_en") == 0){ - pin = CRUZ_EN; - } - else if(strcmp(pinInput, "cruz_st") == 0){ - pin = CRUZ_ST; - } - else if(strcmp(pinInput, "brakelight") == 0){ - pin = BRAKELIGHT; - } - else{ - return false; - } - - printf("%s is %s\n\r", pinInput, Minions_Read(pin) ? "on" : "off"); - return true; +static bool cmdMinionsRead(void) { + char *pin_input = strtok_r(NULL, " ", &save); + Pin pin = 0; + if (strcmp(pin_input, "ign_1") == 0) { + pin = kIgn1; + } else if (strcmp(pin_input, "ign_2") == 0) { + pin = kIgn2; + } else if (strcmp(pin_input, "kRegenSw") == 0) { + pin = kRegenSw; + } else if (strcmp(pin_input, "kForSw") == 0) { + pin = kForSw; + } else if (strcmp(pin_input, "kRevSw") == 0) { + pin = kRevSw; + } else if (strcmp(pin_input, "kCruzEn") == 0) { + pin = kCruzEn; + } else if (strcmp(pin_input, "kCruzSt") == 0) { + pin = kCruzSt; + } else if (strcmp(pin_input, "brakelight") == 0) { + pin = kBrakeLight; + } else { + return false; + } + + printf("%s is %s\n\r", pin_input, MinionsRead(pin) ? "on" : "off"); + return true; } -static bool cmd_Minions_Write(void){ - char *pinInput = strtok_r(NULL, " ", &save); - pin_t pin; - if(strcmp(pinInput, "brakelight") == 0){ - pin = BRAKELIGHT; - } - else{ - return false; - } - - char *stateInput = strtok_r(NULL, " ", &save); - bool state; - if(strcmp(stateInput, "on") == 0){ - state = true; - } - else if(strcmp(stateInput, "off") == 0){ - state = false; - } - else{ - return false; - } - - Minions_Write(pin, state); - printf("%s set to %s\n\r", pinInput, stateInput); - return true; +static bool cmdMinionsWrite(void) { + char *pin_input = strtok_r(NULL, " ", &save); + Pin pin = 0; + if (strcmp(pin_input, "brakelight") == 0) { + pin = kBrakeLight; + } else { + return false; + } + + char *state_input = strtok_r(NULL, " ", &save); + bool state = false; + if (strcmp(state_input, "on") == 0) { + state = true; + } else if (strcmp(state_input, "off") == 0) { + state = false; + } else { + return false; + } + + MinionsWrite(pin, state); + printf("%s set to %s\n\r", pin_input, state_input); + return true; } -static bool cmd_Pedals_Read(void){ - char *pedalInput = strtok_r(NULL, " ", &save); - pedal_t pedal; - if(strcmp(pedalInput, "accel") == 0){ - pedal = ACCELERATOR; - } - else if(strcmp(pedalInput, "brake") == 0){ - pedal = BRAKE; - } - else{ - return false; - } - - printf("%s: %d\n\r", pedalInput, Pedals_Read(pedal)); - return true; +static bool cmdPedalsRead(void) { + char *pedal_input = strtok_r(NULL, " ", &save); + Pedal pedal = 0; + if (strcmp(pedal_input, "accel") == 0) { + pedal = kAccelerator; + } else if (strcmp(pedal_input, "brake") == 0) { + pedal = kBrake; + } else { + return false; + } + + printf("%s: %d\n\r", pedal_input, PedalsRead(pedal)); + return true; } diff --git a/Apps/Src/DebugDump.c b/Apps/Src/DebugDump.c index 15cd48e98..362015776 100644 --- a/Apps/Src/DebugDump.c +++ b/Apps/Src/DebugDump.c @@ -1,27 +1,18 @@ -#include "os.h" +#include + +#include "CanBus.h" +#include "Contactors.h" +#include "Minions.h" +#include "Pedals.h" +#include "SendTritium.h" #include "Tasks.h" #include "bsp.h" -#include "CANbus.h" -#include "Pedals.h" -#include "Minions.h" -#include "Contactors.h" #include "common.h" -#include -#include "Tasks.h" -#include "SendTritium.h" - - -static const char *MINIONPIN_STRING[] = { - FOREACH_PIN(GENERATE_STRING) -}; - -static const char *CONTACTOR_STRING[] = { - FOREACH_contactor(GENERATE_STRING) -}; +#include "os.h" -static const char *GEAR_STRING[] = { - FOREACH_Gear(GENERATE_STRING) -}; +static const char *minionpin_string[] = {FOREACH_PIN(GENERATE_STRING)}; +static const char *contactor_string[] = {FOREACH_CONTACTOR(GENERATE_STRING)}; +static const char *gear_string[] = {FOREACH_GEAR(GENERATE_STRING)}; // Need to keep this in sync with Task.h /*----------------------------------------------*/ @@ -29,47 +20,50 @@ static const char *GEAR_STRING[] = { /*----------------------------------------------*/ -void Task_DebugDump(void* p_arg) { - OS_ERR err; - - while(1){ +void TaskDebugDump(void *p_arg) { + OS_ERR err = 0; + while (1) { // Get pedal information - int8_t accelPedal = Pedals_Read(ACCELERATOR); - printf("ACCELERATOR: %d\n\r", accelPedal); + int8_t accel_pedal = PedalsRead(kAccelerator); + printf("kAccelerator: %d\n\r", accel_pedal); - int8_t brakePedal = Pedals_Read(BRAKE); - printf("BRAKE: %d\n\r", brakePedal); + int8_t brake_pedal = PedalsRead(kBrake); + printf("kBrake: %d\n\r", brake_pedal); // Get minion information - for(pin_t pin = 0; pin < NUM_PINS; pin++){ - bool pinState = Minions_Read(pin); + for (Pin pin = 0; pin < kNumPins; pin++) { + bool pin_state = MinionsRead(pin); // Ignition pins are negative logic, special-case them - printf("%s: %s\n\r", MINIONPIN_STRING[pin], pinState ^ (pin == IGN_1 || pin == IGN_2) ? "on" : "off"); + printf("%s: %s\n\r", minionpin_string[pin], + pin_state ^ (pin == kIgn1 || pin == kIgn2) ? "on" : "off"); } // Get contactor info - for(contactor_t contactor = 0; contactor < NUM_CONTACTORS; contactor++){ - bool contactorState = Contactors_Get(contactor) == ON ? true : false; - printf("%s: %s\n\r", CONTACTOR_STRING[contactor], contactorState ? "on" : "off"); - } + for (Contactor contactor = 0; contactor < kNumContactors; contactor++) { + bool contactor_state = + ContactorsGet(contactor) == ON ? true : false; + printf("%s: %s\n\r", contactor_string[contactor], + contactor_state ? "on" : "off"); + } // Send Tritium variables - printf("Cruise Enable: %s\n\r", get_cruiseEnable() ? "true" : "false"); - printf("Cruise Set: %s\n\r", get_cruiseSet() ? "true" : "false"); - printf("One Pedal Enable: %s\n\r", get_onePedalEnable() ? "true" : "false"); - printf("Regen Enable: %s\n\r", get_regenEnable() ? "true" : "false"); - printf("Pedal Brake Percent: %d\n\r", get_brakePedalPercent()); - printf("Pedal Accel Percent: %d\n\r", get_accelPedalPercent()); - printf("Current Gear: %s\n\r", GEAR_STRING[get_gear()]); - print_float("Current Setpoint: ", get_currentSetpoint()); + printf("Cruise Enable: %s\n\r", GetCruiseEnable() ? "true" : "false"); + printf("Cruise Set: %s\n\r", GetCruiseSet() ? "true" : "false"); + printf("One Pedal Enable: %s\n\r", + GetOnePedalEnable() ? "true" : "false"); + printf("Regen Enable: %s\n\r", GetRegenEnable() ? "true" : "false"); + printf("Pedal Brake Percent: %d\n\r", GetBrakePedalPercent()); + printf("Pedal Accel Percent: %d\n\r", GetAccelPedalPercent()); + printf("Current Gear: %s\n\r", gear_string[GetGear()]); + PrintFloat("Current Setpoint: ", GetCurrentSetpoint()); printf("\n\r"); // Delay of 5 seconds - OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_HMSM_STRICT, &err); - if (err != OS_ERR_NONE){ - assertOSError(err); + OSTimeDlyHMSM(0, 0, 5, 0, OS_OPT_TIME_HMSM_STRICT, &err); // NOLINT + if (err != OS_ERR_NONE) { + ASSERT_OS_ERROR(err); } } } \ No newline at end of file diff --git a/Apps/Src/PedalToPercent.c b/Apps/Src/PedalToPercent.c index 87646432a..53a87970a 100644 --- a/Apps/Src/PedalToPercent.c +++ b/Apps/Src/PedalToPercent.c @@ -1,111 +1,20 @@ /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file PedalToPercent.c - * @brief - * + * @brief + * */ /* Converts accelerator pedal percentage to a decimal */ -const float pedalToPercent[] = { - 0.00f, - 0.01f, - 0.02f, - 0.03f, - 0.04f, - 0.05f, - 0.06f, - 0.07f, - 0.08f, - 0.09f, - 0.1f, - 0.11f, - 0.12f, - 0.13f, - 0.14f, - 0.15f, - 0.16f, - 0.17f, - 0.18f, - 0.19f, - 0.2f, - 0.21f, - 0.22f, - 0.23f, - 0.24f, - 0.25f, - 0.26f, - 0.27f, - 0.28f, - 0.29f, - 0.3f, - 0.31f, - 0.32f, - 0.33f, - 0.34f, - 0.35f, - 0.36f, - 0.37f, - 0.38f, - 0.39f, - 0.4f, - 0.41f, - 0.42f, - 0.43f, - 0.44f, - 0.45f, - 0.46f, - 0.47f, - 0.48f, - 0.49f, - 0.5f, - 0.51f, - 0.52f, - 0.53f, - 0.54f, - 0.55f, - 0.56f, - 0.57f, - 0.58f, - 0.59f, - 0.6f, - 0.61f, - 0.62f, - 0.63f, - 0.64f, - 0.65f, - 0.66f, - 0.67f, - 0.68f, - 0.69f, - 0.7f, - 0.71f, - 0.72f, - 0.73f, - 0.74f, - 0.75f, - 0.76f, - 0.77f, - 0.78f, - 0.79f, - 0.8f, - 0.81f, - 0.82f, - 0.83f, - 0.84f, - 0.85f, - 0.86f, - 0.87f, - 0.88f, - 0.89f, - 0.9f, - 0.91f, - 0.92f, - 0.93f, - 0.94f, - 0.95f, - 0.96f, - 0.97f, - 0.98f, - 0.99f, - 1.0f, +const float kPedalToPercent[] = { + 0.00F, 0.01F, 0.02F, 0.03F, 0.04F, 0.05F, 0.06F, 0.07F, 0.08F, 0.09F, 0.1F, + 0.11F, 0.12F, 0.13F, 0.14F, 0.15F, 0.16F, 0.17F, 0.18F, 0.19F, 0.2F, 0.21F, + 0.22F, 0.23F, 0.24F, 0.25F, 0.26F, 0.27F, 0.28F, 0.29F, 0.3F, 0.31F, 0.32F, + 0.33F, 0.34F, 0.35F, 0.36F, 0.37F, 0.38F, 0.39F, 0.4F, 0.41F, 0.42F, 0.43F, + 0.44F, 0.45F, 0.46F, 0.47F, 0.48F, 0.49F, 0.5F, 0.51F, 0.52F, 0.53F, 0.54F, + 0.55F, 0.56F, 0.57F, 0.58F, 0.59F, 0.6F, 0.61F, 0.62F, 0.63F, 0.64F, 0.65F, + 0.66F, 0.67F, 0.68F, 0.69F, 0.7F, 0.71F, 0.72F, 0.73F, 0.74F, 0.75F, 0.76F, + 0.77F, 0.78F, 0.79F, 0.8F, 0.81F, 0.82F, 0.83F, 0.84F, 0.85F, 0.86F, 0.87F, + 0.88F, 0.89F, 0.9F, 0.91F, 0.92F, 0.93F, 0.94F, 0.95F, 0.96F, 0.97F, 0.98F, + 0.99F, 1.0F, }; diff --git a/Apps/Src/ReadCarCAN.c b/Apps/Src/ReadCarCAN.c deleted file mode 100644 index 64897dd4b..000000000 --- a/Apps/Src/ReadCarCAN.c +++ /dev/null @@ -1,489 +0,0 @@ -/** - * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar - * @file ReadCarCAN.c - * @brief - * - */ - -#include "ReadCarCAN.h" -#include "UpdateDisplay.h" -#include "Contactors.h" -#include "Minions.h" -#include "os.h" -#include "os_cfg_app.h" -#include "Display.h" - -// Length of the array and motor PBC saturation buffers -#define SAT_BUF_LENGTH 5 - -// The Array/Motor Controller Saturation Threshold is used to determine if Controls has -// received a sufficient number of BPS's HV Array/Plus-Minus Enable Messages. -// BPS Array and Plus/Minus saturation threshold is halfway between 0 and max saturation value. -#define ARRAY_SATURATION_THRESHOLD (((SAT_BUF_LENGTH + 1) * SAT_BUF_LENGTH) / 4) -#define PLUS_MINUS_SATURATION_THRESHOLD (((SAT_BUF_LENGTH + 1) * SAT_BUF_LENGTH) / 4) - -// Timer delay constants -#define CAN_WATCH_TMR_DLY_MS 500u // 500 ms -#define CAN_WATCH_TMR_DLY_TMR_TS ((CAN_WATCH_TMR_DLY_MS * OS_CFG_TMR_TASK_RATE_HZ) / (1000u)) // 1000 for ms -> s conversion - -// Precharge Delay times in milliseconds -#define PRECHARGE_PLUS_MINUS_DELAY 100u // 100 ms, as this the smallest time delay that the RTOS can work with -#define PRECHARGE_ARRAY_DELAY 100u // 100 ms -#define ARRAY_PRECHARGE_BYPASS_DLY_TMR_TS ((PRECHARGE_ARRAY_DELAY * OS_CFG_TMR_TASK_RATE_HZ) / (1000u)) -#define MOTOR_CONTROLLER_PRECHARGE_BYPASS_DLY_TMR_TS ((PRECHARGE_PLUS_MINUS_DELAY * OS_CFG_TMR_TASK_RATE_HZ) / (1000u)) - -// High Voltage BPS Contactor bit mapping -#define HV_ARRAY_CONTACTOR_BIT 1 //0b001 -#define HV_MINUS_CONTACTOR_BIT 2 //0b010 -#define HV_PLUS_CONTACTOR_BIT 4 //0b100 - -// Saturation messages -#define DISABLE_SATURATION_MSG -1 -#define ENABLE_SATURATION_MSG 1 - -// State of Charge scalar to scale it to correct fixed point -#define SOC_SCALER 1000000 - -// CAN watchdog timer variable -static OS_TMR canWatchTimer; - -// Array precharge bypass contactor delay timer variable -static OS_TMR arrayPBCDlyTimer; - -// Motor controller precharge bypass contactor delay timer variable -static OS_TMR motorControllerPBCDlyTimer; - -// NOTE: This should not be written to anywhere other than ReadCarCAN. If the need arises, a mutex to protect it must be added. -// Indicates whether or not regenerative braking / charging is enabled. -static bool chargeEnable = false; // Enable (High message) of BPS high voltage (HV) array contactor - -// BPS HV Array saturation buffer variables -static int8_t HVArrayChargeMsgBuffer[SAT_BUF_LENGTH]; -static int8_t HVArrayMsgSaturation = 0; -static uint8_t HVArrayOldestMsgIdx = 0; - -// BPS HV Motor Controller saturation buffer variables -static int8_t HVPlusMinusChargeMsgBuffer[SAT_BUF_LENGTH]; -static int8_t HVPlusMinusChargeMsgSaturation = 0; -static uint8_t HVPlusMinusMotorOldestMsgIdx = 0; - -// Array ignition (IGN_1) and Motor Controller ignition (IGN_2) pin status -static bool arrIgnStatus = false; -static bool mcIgnStatus = false; - -// Boolean to indicate precharge status for Array Precharge Bypass Contactor (PBC) and Motor Controller PBC -static bool arrPBCComplete = false; -static bool mcPBCComplete = false; - -// State of Charge (SOC) and supplemental battery pack voltage (SBPV) value intialization -static uint8_t SOC = 0; -static uint32_t SBPV = 0; - -// Error assertion function prototype -static void assertReadCarCANError(ReadCarCAN_error_code_t rcc_err); - -// Getter function for charge enable, indicating that battery charging is allowed -bool ChargeEnable_Get(void){ - return chargeEnable; -} - -/** - * @brief Nested function as the same function needs to be executed however the timer requires different parameters - * @param p_tmr pointer to the timer that calls this function, passed by timer - * @param p_arg pointer to the argument passed by timer -*/ -static void callbackCANWatchdog(void *p_tmr, void *p_arg){ - assertReadCarCANError(READCARCAN_ERR_MISSED_MSG); -} - -/** - * @brief Callback function for the precharge delay timer. Waits for precharge and then sets arrPBCComplete to true. - * @param p_tmr pointer to the timer that calls this function, passed by timer - * @param p_arg pointer to the argument passed by timer -*/ -static void setArrayBypassPrechargeComplete(void *p_tmr, void *p_arg){ - arrPBCComplete = true; -}; - -/** - * @brief Callback function for the precharge delay timer. Waits for precharge and then sets mcPBCComplete to true. - * @param p_tmr pointer to the timer that calls this function, passed by timer - * @param p_arg pointer to the argument passed by timer -*/ -static void setMotorControllerBypassPrechargeComplete(void *p_tmr, void *p_arg){ - mcPBCComplete = true; -}; - -/** - * @brief Disables Array Precharge Bypass Contactor (PBC) by asserting an error. Also updates display for Array PBC to be open. - * @param None -*/ -static void disableArrayPrechargeBypassContactor(void){ - // Assert error to disable regen and update saturation in callback function - assertReadCarCANError(READCARCAN_ERR_CHARGE_DISABLE); - // Turn off the array contactor display light - UpdateDisplay_SetArray(false); // Can assume contactor turned off or else this won't be reached -} - -/** - * @brief Turns array PBC on if conditional meets ignition status, saturation threshold, array PCB to be off, - * and a non-running precharge delay timer. - * @param None -*/ -static void updateArrayPrechargeBypassContactor(void){ - OS_ERR err = OS_ERR_NONE; - if((arrIgnStatus || mcIgnStatus) // Ignition is ON - && HVArrayMsgSaturation >= ARRAY_SATURATION_THRESHOLD // Saturation Threshold has be met - && (Contactors_Get(ARRAY_PRECHARGE_BYPASS_CONTACTOR) == OFF) - // Array PBC is OFF - && (OSTmrStateGet(&arrayPBCDlyTimer, &err) != OS_TMR_STATE_RUNNING)){ // and precharge is currently not happening - // Asserts error for OS timer state above if conditional was met - assertOSError(err); - // Wait to make sure precharge is finished and then restart array - OSTmrStart(&arrayPBCDlyTimer, &err); - } - // Asserts error for OS timer state above if conditional was not met - assertOSError(err); -} - - -/** - * @brief Turns array PBC on if conditional meets ignition status, saturation threshold, motor PBC to be off, - * and a non-running precharge delay timer. - * @param None -*/ -static void updateMCPBC(void){ - OS_ERR err = OS_ERR_NONE; - if(mcIgnStatus // Ignition is ON - && HVPlusMinusChargeMsgSaturation >= PLUS_MINUS_SATURATION_THRESHOLD // Saturation Threshold has be met - &&(Contactors_Get(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR) == OFF) // Motor Controller PBC is OFF - && (OSTmrStateGet(&motorControllerPBCDlyTimer, &err) != OS_TMR_STATE_RUNNING)){ // and precharge is currently not happening - // Asserts error for OS timer state above if conditional was met - assertOSError(err); - // Wait to make sure precharge is finished and then restart array - OSTmrStart(&motorControllerPBCDlyTimer, &err); - } - // Asserts error for OS timer start above if conditional was not met - assertOSError(err); -} - -/** - * @brief adds new messages by overwriting old messages in the saturation buffer and then updates saturation - * @param messageState whether bps message was enable (1) or disable (-1) -*/ -static void updateHVArraySaturation(int8_t messageState){ - - // Replace oldest message with new charge message and update index for oldest message - HVArrayChargeMsgBuffer[HVArrayOldestMsgIdx] = messageState; - HVArrayOldestMsgIdx = (HVArrayOldestMsgIdx + 1) % SAT_BUF_LENGTH; - - // Calculate the new saturation value by assigning weightings from 1 to buffer length - // in order of oldest to newest - int newSaturation = 0; - for (uint8_t i = 0; i < SAT_BUF_LENGTH; i++){ - newSaturation += HVArrayChargeMsgBuffer[(HVArrayOldestMsgIdx + i) % SAT_BUF_LENGTH] * (i + 1); - } - HVArrayMsgSaturation = newSaturation; - - if(messageState == -1){ - chargeEnable = false; - }else if(HVArrayMsgSaturation >= ARRAY_SATURATION_THRESHOLD){ - chargeEnable = true; - updateArrayPrechargeBypassContactor(); - } - -} - -/** - * @brief adds new messages by overwriting old messages in the saturation buffer and then updates saturation - * @param messageState whether bps message was enable (1) or disable (-1) -*/ -static void updateHVPlusMinusSaturation(int8_t messageState){ - - // Replace oldest message with new charge message and update index for oldest message - HVPlusMinusChargeMsgBuffer[HVPlusMinusMotorOldestMsgIdx] = messageState; - HVPlusMinusMotorOldestMsgIdx = (HVPlusMinusMotorOldestMsgIdx + 1) % SAT_BUF_LENGTH; - - // Calculate the new saturation value by assigning weightings from 1 to buffer length - // in order of oldest to newest - int newSaturation = 0; - for (uint8_t i = 0; i < SAT_BUF_LENGTH; i++){ - newSaturation += HVPlusMinusChargeMsgBuffer[(HVPlusMinusMotorOldestMsgIdx + i) % SAT_BUF_LENGTH] * (i + 1); - } - HVPlusMinusChargeMsgSaturation = newSaturation; - - if(messageState == 1){ - updateMCPBC(); - } -} - -/** - * @brief Helper to turn arrayPBCOn if arrayBypassPrecharge is completed and charging is enabled - * @param None -*/ - void attemptTurnArrayPBCOn(void){ - if(arrPBCComplete && chargeEnable){ - Contactors_Set(ARRAY_PRECHARGE_BYPASS_CONTACTOR, ON, true); // Turn on - UpdateDisplay_SetArray(true); - arrPBCComplete = false; - } - } - -/** - * @brief Helper to turn motorControllerPBCOn if motorControllerBypassPrecharge is completed and threshold is reached - * @param None -*/ - void attemptTurnMotorControllerPBCOn(void){ - if(mcPBCComplete){ - Contactors_Set(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR, ON, true); - UpdateDisplay_SetMotor(true); - } - } - -/** - * @brief Helper to turn motorControllerPBCOff if ignition is not turned to motor or motor controller threshold isn't reached. - * @param None -*/ - void turnMotorControllerPBCOff(void){ - Contactors_Set(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR, OFF, true); - UpdateDisplay_SetMotor(false); - } - - -/** - * @brief Turns array and motor controller PBC ON/OFF based on ignition and precharge status - * @param None -*/ - void updatePrechargeContactors(void){ - - arrIgnStatus = (!Minions_Read(IGN_1)); - mcIgnStatus = (!Minions_Read(IGN_2)); - - // Logic helper in cases both are off or (impossible) on - bool bothStatusOff = !mcIgnStatus && !arrIgnStatus; - bool bothStatusOn = mcIgnStatus && arrIgnStatus; - - if(bothStatusOff || bothStatusOn){ - assertReadCarCANError(READCARCAN_ERR_DISABLE_CONTACTORS_MSG); // Turn Array and Motor Controller PBC off using error assert - - }else if(!mcIgnStatus && arrIgnStatus){ - attemptTurnArrayPBCOn(); // Turn Array PBC On, if permitted - turnMotorControllerPBCOff(); // Turn Motor Controller PBC Off - - }else if(mcIgnStatus && !arrIgnStatus){ - attemptTurnArrayPBCOn(); // Turn Array PBC On, if permitted - if(HVPlusMinusChargeMsgSaturation >= PLUS_MINUS_SATURATION_THRESHOLD){ // Turn Motor Controller PBC On, if threshold is reached - attemptTurnMotorControllerPBCOn(); - }else{ - turnMotorControllerPBCOff(); - } - } - - // Set precharge complete variable to false if precharge happens again - arrPBCComplete = false; - mcPBCComplete = false; -} - -void Task_ReadCarCAN(void *p_arg){ - OS_ERR err; - - // data struct for CAN message - CANDATA_t dataBuf; - - // Create the CAN Watchdog (periodic) timer, which disconnects the array and disables regenerative braking - // if we do not get a CAN message with the ID Charge_Enable within the desired interval. - OSTmrCreate( - &canWatchTimer, - "CAN Watch Timer", - CAN_WATCH_TMR_DLY_TMR_TS, // Initial delay equal to the period since 0 doesn't seem to work - CAN_WATCH_TMR_DLY_TMR_TS, - OS_OPT_TMR_PERIODIC, - callbackCANWatchdog, - NULL, - &err - ); - assertOSError(err); - - OSTmrCreate( - &arrayPBCDlyTimer, - "Array Bypass Precharge Delay Timer", - 0, - ARRAY_PRECHARGE_BYPASS_DLY_TMR_TS, - OS_OPT_TMR_ONE_SHOT, - setArrayBypassPrechargeComplete, - NULL, - &err - ); - assertOSError(err); - - OSTmrCreate( - &motorControllerPBCDlyTimer, - "Motor Controller Bypass Precharge Delay Timer", - 0, - MOTOR_CONTROLLER_PRECHARGE_BYPASS_DLY_TMR_TS, - OS_OPT_TMR_ONE_SHOT, - setMotorControllerBypassPrechargeComplete, - NULL, - &err - ); - assertOSError(err); - - // Start CAN Watchdog timer - OSTmrStart(&canWatchTimer, &err); - assertOSError(err); - - // Fills buffers with disable messages - // NOTE: If the buffer becomes bigger than of type int8_t, memset will not work and - // would need to be reimplemented. - memset(HVArrayChargeMsgBuffer, DISABLE_SATURATION_MSG, sizeof(HVArrayChargeMsgBuffer)); - memset(HVPlusMinusChargeMsgBuffer, DISABLE_SATURATION_MSG, sizeof(HVPlusMinusChargeMsgBuffer)); - - while(1){ - - updatePrechargeContactors(); // Sets array and motor controller PBC if all conditions (PBC Status, Threshold, Precharge Complete) permit - - // BPS sent a message - ErrorStatus status = CANbus_Read(&dataBuf, true, CARCAN); - if(status != SUCCESS){ - continue; - } - - switch(dataBuf.ID){ // Switch case based on BPS msg received - case BPS_TRIP: { // BPS has a fault and we need to enter fault state - - // kill contactors and enter a nonrecoverable fault - assertReadCarCANError(READCARCAN_ERR_BPS_TRIP); - } - case BPS_CONTACTOR: { - - OSTmrStart(&canWatchTimer, &err); // Restart CAN Watchdog timer for BPS Contactor msg - assertOSError(err); - - // Retrieving HV contactor statuses using bit mapping - // Bitwise to get HV Plus and Minus, and then &&ing to ensure both are on - bool HVPlusMinusStatus = (bool)((dataBuf.data[0] & HV_PLUS_CONTACTOR_BIT) && (dataBuf.data[0] & HV_MINUS_CONTACTOR_BIT)); - // Bitwise to get HV Array - bool HVArrayStatus = (bool)(dataBuf.data[0] & HV_ARRAY_CONTACTOR_BIT); - - // Update HV Array and HV Plus/Minus saturations based on the respective statuses - HVArrayStatus ? updateHVArraySaturation(ENABLE_SATURATION_MSG) : disableArrayPrechargeBypassContactor(); - HVPlusMinusStatus ? updateHVPlusMinusSaturation(ENABLE_SATURATION_MSG) : updateHVPlusMinusSaturation(DISABLE_SATURATION_MSG); - - break; // End of BPS Contactor Status Updates - } - - case SUPPLEMENTAL_VOLTAGE: { - SBPV = (*(uint16_t *) &dataBuf.data); - UpdateDisplay_SetSBPV(SBPV); // Receive value in mV - break; - } - case STATE_OF_CHARGE:{ - SOC = (*(uint32_t*) &dataBuf.data)/(SOC_SCALER); // Convert to integer percent - UpdateDisplay_SetSOC(SOC); - break; - } - default: { - break; // Unhandled CAN message IDs, do nothing - } - } - } -} - -/** - * @brief error handler callback for disabling charging, - * kills contactor and turns off display - */ -static void handler_ReadCarCAN_chargeDisable(void) { - // Fills buffers with disable messages - memset(HVArrayChargeMsgBuffer, DISABLE_SATURATION_MSG, sizeof(HVArrayChargeMsgBuffer)); - - // mark regen as disabled and update saturation - updateHVArraySaturation(DISABLE_SATURATION_MSG); - - // Kill contactor using a direct write to avoid blocking calls when the scheduler is locked - BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_PRECHARGE_BYPASS_PIN, false); - - // Check that the contactor was successfully turned off - bool ret = (bool)Contactors_Get(ARRAY_PRECHARGE_BYPASS_CONTACTOR); - - if(ret) { // Contactor failed to turn off; display the evac screen and infinite loop - Display_Evac(SOC, SBPV); - while(1){;} - } -} - -/** - * @brief error handler callback for disabling charging, - * kills contactor and turns off display - */ -static void handler_ReadCarCAN_contactorsDisable(void) { - - // Mark regen as disabled and update saturation - updateHVArraySaturation(DISABLE_SATURATION_MSG); - updateHVPlusMinusSaturation(DISABLE_SATURATION_MSG); - - // Kill contactor using a direct write to avoid blocking calls when the scheduler is locked - BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_PRECHARGE_BYPASS_PIN, false); - BSP_GPIO_Write_Pin(CONTACTORS_PORT, MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN, false); - - // Fills buffers with disable messages - memset(HVArrayChargeMsgBuffer, DISABLE_SATURATION_MSG, sizeof(HVArrayChargeMsgBuffer)); - memset(HVPlusMinusChargeMsgBuffer, DISABLE_SATURATION_MSG, sizeof(HVPlusMinusChargeMsgBuffer)); - - // Updates the saturation with disable - updateHVArraySaturation(DISABLE_SATURATION_MSG); - updateHVPlusMinusSaturation(DISABLE_SATURATION_MSG); - - // Check that the contactor was successfully turned off - bool ret = (bool)Contactors_Get(ARRAY_PRECHARGE_BYPASS_CONTACTOR) || (bool)Contactors_Get(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR); - - if(ret) { // Contactor failed to turn off; display the evac screen and infinite loop - Display_Evac(SOC, SBPV); - while(1){;} - } -} - -/** - * @brief error handler function to display the evac screen if we get a BPS trip message. - * Callbacks happen after displaying the fault, so this screen won't get overwritten - */ -static void handler_ReadCarCAN_BPSTrip(void) { - chargeEnable = false; // Not really necessary but makes inspection less confusing - Display_Evac(SOC, SBPV); // Display evacuation screen -} - - -/** - * @brief error assertion function for ReadCarCAN, used to disable charging and handle BPS trip messages - * Stores the error code and calls assertTaskError with the appropriate parameters and callback handler - * @param rcc_err error code to specify the issue encountered - */ -static void assertReadCarCANError(ReadCarCAN_error_code_t rcc_err){ - Error_ReadCarCAN = (error_code_t) rcc_err; // Store error code for inspection - - switch (rcc_err) { - case READCARCAN_ERR_NONE: - break; - - case READCARCAN_ERR_CHARGE_DISABLE: // Received a charge disable msg and need to turn off array contactor - throwTaskError(Error_ReadCarCAN, handler_ReadCarCAN_chargeDisable, OPT_LOCK_SCHED, OPT_RECOV); - break; - - case READCARCAN_ERR_MISSED_MSG: // Missed message- turn off array and motor controller PBC - throwTaskError(Error_ReadCarCAN, handler_ReadCarCAN_contactorsDisable, OPT_LOCK_SCHED, OPT_RECOV); - break; - - case READCARCAN_ERR_DISABLE_CONTACTORS_MSG: // Ignition turned to off or turned to last two simultaneously - throwTaskError(Error_ReadCarCAN, handler_ReadCarCAN_contactorsDisable, OPT_LOCK_SCHED, OPT_RECOV); - break; - - case READCARCAN_ERR_BPS_TRIP: // Received a BPS trip msg (0 or 1), need to shut down car and infinite loop - throwTaskError(Error_ReadCarCAN, handler_ReadCarCAN_BPSTrip, OPT_LOCK_SCHED, OPT_NONRECOV); - break; - - default: - break; - } - - Error_ReadCarCAN = READCARCAN_ERR_NONE; // Clear the error after handling it -} \ No newline at end of file diff --git a/Apps/Src/ReadCarCan.c b/Apps/Src/ReadCarCan.c new file mode 100644 index 000000000..5617fce2b --- /dev/null +++ b/Apps/Src/ReadCarCan.c @@ -0,0 +1,548 @@ +/** + * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar + * @file ReadCarCAN.c + * @brief + * + */ + +#include "ReadCarCan.h" + +#include "CanBus.h" +#include "Contactors.h" +#include "Display.h" +#include "Minions.h" +#include "Tasks.h" +#include "UpdateDisplay.h" +#include "common.h" +#include "os.h" +#include "os_cfg_app.h" + +// Length of the array and motor PBC saturation buffers +#define SAT_BUF_LENGTH 5 + +// The Array/Motor Controller Saturation Threshold is used to determine if +// Controls has +// received a sufficient number of BPS's HV Array/Plus-Minus Enable +// Messages. BPS Array and Plus/Minus saturation threshold is halfway +// between 0 and max saturation value. +#define ARRAY_SATURATION_THRESHOLD (((SAT_BUF_LENGTH + 1) * SAT_BUF_LENGTH) / 4) +#define PLUS_MINUS_SATURATION_THRESHOLD \ + (((SAT_BUF_LENGTH + 1) * SAT_BUF_LENGTH) / 4) + +// Timer delay constants +#define CAN_WATCH_TMR_DLY_MS 500u // 500 ms +#define CAN_WATCH_TMR_DLY_TMR_TS \ + ((CAN_WATCH_TMR_DLY_MS * OS_CFG_TMR_TASK_RATE_HZ) / \ + (1000u)) // 1000 for ms -> s conversion + +// Precharge Delay times in milliseconds +#define PRECHARGE_PLUS_MINUS_DELAY \ + 100u // 100 ms, as this the smallest time delay that the RTOS can work with +#define PRECHARGE_ARRAY_DELAY 100u // 100 ms +#define ARRAY_PRECHARGE_BYPASS_DLY_TMR_TS \ + ((PRECHARGE_ARRAY_DELAY * OS_CFG_TMR_TASK_RATE_HZ) / (1000u)) +#define MOTOR_CONTROLLER_PRECHARGE_BYPASS_DLY_TMR_TS \ + ((PRECHARGE_PLUS_MINUS_DELAY * OS_CFG_TMR_TASK_RATE_HZ) / (1000u)) + +// High Voltage BPS Contactor bit mapping +#define HV_ARRAY_CONTACTOR_BIT 1 // 0b001 +#define HV_MINUS_CONTACTOR_BIT 2 // 0b010 +#define HV_PLUS_CONTACTOR_BIT 4 // 0b100 + +// Saturation messages +#define DISABLE_SATURATION_MSG (-1) +#define ENABLE_SATURATION_MSG 1 + +// State of Charge scalar to scale it to correct fixed point +#define SOC_SCALER 1000000 + +// CAN watchdog timer variable +static OS_TMR can_watch_timer; + +// Array precharge bypass contactor delay timer variable +static OS_TMR array_pbc_dly_timer; + +// Motor controller precharge bypass contactor delay timer variable +static OS_TMR motor_controller_pbc_dly_timer; + +// NOTE: This should not be written to anywhere other than ReadCarCAN. If the +// need arises, a mutex to protect it must be added. Indicates whether or not +// regenerative braking / charging is enabled. +static bool charge_enable = + false; // Enable (High message) of BPS high voltage (HV) array contactor + +// BPS HV Array saturation buffer variables +static int8_t hv_array_charge_msg_buffer[SAT_BUF_LENGTH]; +static int8_t hv_array_msg_saturation = 0; +static uint8_t hv_array_oldest_msg_idx = 0; + +// BPS HV Motor Controller saturation buffer variables +static int8_t hv_plus_minus_charge_msg_buffer[SAT_BUF_LENGTH]; +static int8_t hv_plus_minus_charge_msg_saturation = 0; +static uint8_t hv_plus_minus_motor_oldest_msg_idx = 0; + +// Array ignition (kIgn1) and Motor Controller ignition (kIgn2) pin status +static bool arr_ign_status = false; +static bool mc_ign_status = false; + +// Boolean to indicate precharge status for Array Precharge Bypass Contactor +// (PBC) and Motor Controller PBC +static bool arr_pbc_complete = false; +static bool mc_pbc_complete = false; + +// State of Charge (SOC) and supplemental battery pack voltage (SBPV) value +// intialization +static uint8_t soc = 0; +static uint32_t sbpv = 0; + +// Error assertion function prototype +static void assertReadCarCANError(ReadCarCanErrorCode rcc_err); + +// Getter function for charge enable, indicating that battery charging is +// allowed +bool ChargeEnableGet(void) { return charge_enable; } + +/** + * @brief Nested function as the same function needs to be executed however the + * timer requires different parameters + * @param p_tmr pointer to the timer that calls this function, passed by timer + * @param p_arg pointer to the argument passed by timer + */ +static void callbackCANWatchdog(void *p_tmr, void *p_arg) { + assertReadCarCANError(kReadCarCanErrMissedMsg); +} + +/** + * @brief Callback function for the precharge delay timer. Waits for precharge + * and then sets arrPBCComplete to true. + * @param p_tmr pointer to the timer that calls this function, passed by timer + * @param p_arg pointer to the argument passed by timer + */ +static void setArrayBypassPrechargeComplete(void *p_tmr, void *p_arg) { + arr_pbc_complete = true; +}; + +/** + * @brief Callback function for the precharge delay timer. Waits for precharge + * and then sets mcPBCComplete to true. + * @param p_tmr pointer to the timer that calls this function, passed by timer + * @param p_arg pointer to the argument passed by timer + */ +static void setMotorControllerBypassPrechargeComplete(void *p_tmr, + void *p_arg) { + mc_pbc_complete = true; +}; + +/** + * @brief Disables Array Precharge Bypass Contactor (PBC) by asserting an error. + * Also updates display for Array PBC to be open. + * @param None + */ +static void disableArrayPrechargeBypassContactor(void) { + // Assert error to disable regen and update saturation in callback function + assertReadCarCANError(kReadCarCanErrChargeDisable); + // Turn off the array contactor display light + UpdateDisplaySetArray(false); // Can assume contactor turned off or else + // this won't be reached +} + +/** + * @brief Turns array PBC on if conditional meets ignition status, saturation + * threshold, array PCB to be off, and a non-running precharge delay timer. + * @param None + */ +static void updateArrayPrechargeBypassContactor(void) { + OS_ERR err = OS_ERR_NONE; + if ((arr_ign_status || mc_ign_status) // Ignition is ON + && hv_array_msg_saturation >= + ARRAY_SATURATION_THRESHOLD // Saturation Threshold has be met + && (ContactorsGet(kArrayPrechargeBypassContactor) == OFF) + // Array PBC is OFF + && + (OSTmrStateGet(&array_pbc_dly_timer, &err) != + OS_TMR_STATE_RUNNING)) { // and precharge is currently not happening + // Asserts error for OS timer state above if conditional was met + ASSERT_OS_ERROR(err); + // Wait to make sure precharge is finished and then restart array + OSTmrStart(&array_pbc_dly_timer, &err); + } + // Asserts error for OS timer state above if conditional was not met + ASSERT_OS_ERROR(err); +} + +/** + * @brief Turns array PBC on if conditional meets ignition status, saturation + * threshold, motor PBC to be off, and a non-running precharge delay timer. + * @param None + */ +static void updateMCPBC(void) { + OS_ERR err = OS_ERR_NONE; + if (mc_ign_status // Ignition is ON + && + hv_plus_minus_charge_msg_saturation >= + PLUS_MINUS_SATURATION_THRESHOLD // Saturation Threshold has be met + && (ContactorsGet(kMotorControllerPrechargeBypassContactor) == + OFF) // Motor Controller PBC is OFF + && + (OSTmrStateGet(&motor_controller_pbc_dly_timer, &err) != + OS_TMR_STATE_RUNNING)) { // and precharge is currently not happening + // Asserts error for OS timer state above if conditional was met + ASSERT_OS_ERROR(err); + // Wait to make sure precharge is finished and then restart array + OSTmrStart(&motor_controller_pbc_dly_timer, &err); + } + // Asserts error for OS timer start above if conditional was not met + ASSERT_OS_ERROR(err); +} + +/** + * @brief adds new messages by overwriting old messages in the saturation buffer + * and then updates saturation + * @param messageState whether bps message was enable (1) or disable (-1) + */ +static void updateHVArraySaturation(int8_t message_state) { + // Replace oldest message with new charge message and update index for + // oldest message + hv_array_charge_msg_buffer[hv_array_oldest_msg_idx] = message_state; + hv_array_oldest_msg_idx = (hv_array_oldest_msg_idx + 1) % SAT_BUF_LENGTH; + + // Calculate the new saturation value by assigning weightings from 1 to + // buffer length in order of oldest to newest + int new_saturation = 0; + for (uint8_t i = 0; i < SAT_BUF_LENGTH; i++) { + new_saturation += + hv_array_charge_msg_buffer[(hv_array_oldest_msg_idx + i) % + SAT_BUF_LENGTH] * + (i + 1); + } + hv_array_msg_saturation = (int8_t)new_saturation; + + if (message_state == -1) { + charge_enable = false; + } else if (hv_array_msg_saturation >= ARRAY_SATURATION_THRESHOLD) { + charge_enable = true; + updateArrayPrechargeBypassContactor(); + } +} + +/** + * @brief adds new messages by overwriting old messages in the saturation buffer + * and then updates saturation + * @param messageState whether bps message was enable (1) or disable (-1) + */ +static void updateHVPlusMinusSaturation(int8_t message_state) { + // Replace oldest message with new charge message and update index for + // oldest message + hv_plus_minus_charge_msg_buffer[hv_plus_minus_motor_oldest_msg_idx] = + message_state; + hv_plus_minus_motor_oldest_msg_idx = + (hv_plus_minus_motor_oldest_msg_idx + 1) % SAT_BUF_LENGTH; + + // Calculate the new saturation value by assigning weightings from 1 to + // buffer length in order of oldest to newest + int new_saturation = 0; + for (uint8_t i = 0; i < SAT_BUF_LENGTH; i++) { + new_saturation += + hv_plus_minus_charge_msg_buffer + [(hv_plus_minus_motor_oldest_msg_idx + i) % SAT_BUF_LENGTH] * + (i + 1); + } + hv_plus_minus_charge_msg_saturation = (int8_t)new_saturation; + + if (message_state == 1) { + updateMCPBC(); + } +} + +/** + * @brief Helper to turn arrayPBCOn if arrayBypassPrecharge is completed and + * charging is enabled + * @param None + */ +void AttemptTurnArrayPbcOn(void) { + if (arr_pbc_complete && charge_enable) { + ContactorsSet(kArrayPrechargeBypassContactor, ON, true); // Turn on + UpdateDisplaySetArray(true); + arr_pbc_complete = false; + } +} + +/** + * @brief Helper to turn motorControllerPBCOn if motorControllerBypassPrecharge + * is completed and threshold is reached + * @param None + */ +void AttemptTurnMotorControllerPbcOn(void) { + if (mc_pbc_complete) { + ContactorsSet(kMotorControllerPrechargeBypassContactor, ON, true); + UpdateDisplaySetMotor(true); + } +} + +/** + * @brief Helper to turn motorControllerPBCOff if ignition is not turned to + * motor or motor controller threshold isn't reached. + * @param None + */ +void TurnMotorControllerPbcOff(void) { + ContactorsSet(kMotorControllerPrechargeBypassContactor, OFF, true); + UpdateDisplaySetMotor(false); +} + +/** + * @brief Turns array and motor controller PBC ON/OFF based on ignition and + * precharge status + * @param None + */ +void UpdatePrechargeContactors(void) { + arr_ign_status = (!MinionsRead(kIgn1)); + mc_ign_status = (!MinionsRead(kIgn2)); + + // Logic helper in cases both are off or (impossible) on + bool both_status_off = !mc_ign_status && !arr_ign_status; + bool both_status_on = mc_ign_status && arr_ign_status; + + if (both_status_off || both_status_on) { + assertReadCarCANError( + kReadCarCanErrDisableContactorsMsg); // Turn Array and Motor + // Controller PBC off using + // error assert + + } else if (!mc_ign_status && arr_ign_status) { + AttemptTurnArrayPbcOn(); // Turn Array PBC On, if permitted + TurnMotorControllerPbcOff(); // Turn Motor Controller PBC Off + + } else if (mc_ign_status && !arr_ign_status) { + AttemptTurnArrayPbcOn(); // Turn Array PBC On, if permitted + if (hv_plus_minus_charge_msg_saturation >= + PLUS_MINUS_SATURATION_THRESHOLD) { // Turn Motor Controller PBC On, + // if threshold is reached + AttemptTurnMotorControllerPbcOn(); + } else { + TurnMotorControllerPbcOff(); + } + } + + // Set precharge complete variable to false if precharge happens again + arr_pbc_complete = false; + mc_pbc_complete = false; +} + +void TaskReadCarCan(void *p_arg) { + OS_ERR err = 0; + + // data struct for CAN message + CanData data_buf; + + // Create the CAN Watchdog (periodic) timer, which disconnects the array and + // disables regenerative braking if we do not get a CAN message with the ID + // Charge_Enable within the desired interval. + OSTmrCreate(&can_watch_timer, "CAN Watch Timer", + CAN_WATCH_TMR_DLY_TMR_TS, // Initial delay equal to the period + // since 0 doesn't seem to work + CAN_WATCH_TMR_DLY_TMR_TS, OS_OPT_TMR_PERIODIC, + callbackCANWatchdog, NULL, &err); + ASSERT_OS_ERROR(err); + + OSTmrCreate(&array_pbc_dly_timer, "Array Bypass Precharge Delay Timer", 0, + ARRAY_PRECHARGE_BYPASS_DLY_TMR_TS, OS_OPT_TMR_ONE_SHOT, + setArrayBypassPrechargeComplete, NULL, &err); + ASSERT_OS_ERROR(err); + + OSTmrCreate(&motor_controller_pbc_dly_timer, + "Motor Controller Bypass Precharge Delay Timer", 0, + MOTOR_CONTROLLER_PRECHARGE_BYPASS_DLY_TMR_TS, + OS_OPT_TMR_ONE_SHOT, setMotorControllerBypassPrechargeComplete, + NULL, &err); + ASSERT_OS_ERROR(err); + + // Start CAN Watchdog timer + OSTmrStart(&can_watch_timer, &err); + ASSERT_OS_ERROR(err); + + // Fills buffers with disable messages + // NOTE: If the buffer becomes bigger than of type int8_t, memset will not + // work and would need to be reimplemented. + memset(hv_array_charge_msg_buffer, DISABLE_SATURATION_MSG, + sizeof(hv_array_charge_msg_buffer)); + memset(hv_plus_minus_charge_msg_buffer, DISABLE_SATURATION_MSG, + sizeof(hv_plus_minus_charge_msg_buffer)); + + while (1) { + UpdatePrechargeContactors(); // Sets array and motor controller PBC if + // all conditions (PBC Status, Threshold, + // Precharge Complete) permit + + // BPS sent a message + ErrorStatus status = CanBusRead(&data_buf, true, CARCAN); + if (status != SUCCESS) { + continue; + } + + switch (data_buf.id) { // Switch case based on BPS msg received + case kBpsTrip: { // BPS has a fault and we need to enter fault + // state + + // kill contactors and enter a nonrecoverable fault + assertReadCarCANError(kReadCarCanErrBpsTrip); + } + case kBpsContactor: { + OSTmrStart( + &can_watch_timer, + &err); // Restart CAN Watchdog timer for BPS Contactor msg + ASSERT_OS_ERROR(err); + + // Retrieving HV contactor statuses using bit mapping + // Bitwise to get HV Plus and Minus, and then &&ing to ensure + // both are on + bool hv_plus_minus_status = + (bool)((data_buf.data[0] & HV_PLUS_CONTACTOR_BIT) && + (data_buf.data[0] & HV_MINUS_CONTACTOR_BIT)); + // Bitwise to get HV Array + bool hv_array_status = + (bool)(data_buf.data[0] & HV_ARRAY_CONTACTOR_BIT); + + // Update HV Array and HV Plus/Minus saturations based on the + // respective statuses + hv_array_status ? updateHVArraySaturation(ENABLE_SATURATION_MSG) + : disableArrayPrechargeBypassContactor(); + hv_plus_minus_status + ? updateHVPlusMinusSaturation(ENABLE_SATURATION_MSG) + : updateHVPlusMinusSaturation(DISABLE_SATURATION_MSG); + + break; // End of BPS Contactor Status Updates + } + + case kSupplementalVoltage: { + sbpv = (*(uint16_t *)&data_buf.data); + UpdateDisplaySetSbpv(sbpv); // Receive value in mV + break; + } + case kStateOfCharge: { + soc = (*(uint32_t *)&data_buf.data) / + (SOC_SCALER); // Convert to integer percent + UpdateDisplaySetSoc(soc); + break; + } + default: { + break; // Unhandled CAN message IDs, do nothing + } + } + } +} + +/** + * @brief error handler callback for disabling charging, + * kills contactor and turns off display + */ +static void handlerReadCarCanChargeDisable(void) { + // Fills buffers with disable messages + memset(hv_array_charge_msg_buffer, DISABLE_SATURATION_MSG, + sizeof(hv_array_charge_msg_buffer)); + + // mark regen as disabled and update saturation + updateHVArraySaturation(DISABLE_SATURATION_MSG); + + // Kill contactor using a direct write to avoid blocking calls when the + // scheduler is locked + BspGpioWritePin(CONTACTORS_PORT, ARRAY_PRECHARGE_BYPASS_PIN, false); + + // Check that the contactor was successfully turned off + bool ret = (bool)ContactorsGet(kArrayPrechargeBypassContactor); + + if (ret) { // Contactor failed to turn off; display the evac screen and + // infinite loop + DisplayEvac(soc, sbpv); + while (1) {} + } +} + +/** + * @brief error handler callback for disabling charging, + * kills contactor and turns off display + */ +static void handlerReadCarCanContactorsDisable(void) { + // Mark regen as disabled and update saturation + updateHVArraySaturation(DISABLE_SATURATION_MSG); + updateHVPlusMinusSaturation(DISABLE_SATURATION_MSG); + + // Kill contactor using a direct write to avoid blocking calls when the + // scheduler is locked + BspGpioWritePin(CONTACTORS_PORT, ARRAY_PRECHARGE_BYPASS_PIN, false); + BspGpioWritePin(CONTACTORS_PORT, MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN, + false); + + // Fills buffers with disable messages + memset(hv_array_charge_msg_buffer, DISABLE_SATURATION_MSG, + sizeof(hv_array_charge_msg_buffer)); + memset(hv_plus_minus_charge_msg_buffer, DISABLE_SATURATION_MSG, + sizeof(hv_plus_minus_charge_msg_buffer)); + + // Updates the saturation with disable + updateHVArraySaturation(DISABLE_SATURATION_MSG); + updateHVPlusMinusSaturation(DISABLE_SATURATION_MSG); + + // Check that the contactor was successfully turned off + bool ret = (bool)ContactorsGet(kArrayPrechargeBypassContactor) || + (bool)ContactorsGet(kMotorControllerPrechargeBypassContactor); + + if (ret) { // Contactor failed to turn off; display the evac screen and + // infinite loop + DisplayEvac(soc, sbpv); + while (1) {} + } +} + +/** + * @brief error handler function to display the evac screen if we get a BPS trip + * message. Callbacks happen after displaying the fault, so this screen won't + * get overwritten + */ +static void handlerReadCarCanBpsTrip(void) { + charge_enable = + false; // Not really necessary but makes inspection less confusing + DisplayEvac(soc, sbpv); // Display evacuation screen +} + +/** + * @brief error assertion function for ReadCarCAN, used to disable charging and + * handle BPS trip messages Stores the error code and calls assertTaskError with + * the appropriate parameters and callback handler + * @param rcc_err error code to specify the issue encountered + */ +static void assertReadCarCANError(ReadCarCanErrorCode rcc_err) { + error_read_car_can = (ErrorCode)rcc_err; // Store error code for inspection + + switch (rcc_err) { + case kReadCarCanErrNone: + break; + + case kReadCarCanErrChargeDisable: // Received a charge disable msg and + // need to turn off array contactor + ThrowTaskError(error_read_car_can, handlerReadCarCanChargeDisable, + kOptLockSched, kOptRecov); + break; + + case kReadCarCanErrDisableContactorsMsg: + case kReadCarCanErrMissedMsg: // Missed message- turn off array and + // motor controller PBC Ignition turned + // to off or turned to last two + // simultaneously + ThrowTaskError(error_read_car_can, + handlerReadCarCanContactorsDisable, kOptLockSched, + kOptRecov); + break; + + case kReadCarCanErrBpsTrip: // Received a BPS trip msg (0 or 1), need + // to shut down car and infinite loop + ThrowTaskError(error_read_car_can, handlerReadCarCanBpsTrip, + kOptLockSched, kOptRecov); + break; + + default: + break; + } + + error_read_car_can = + kReadCarCanErrNone; // Clear the error after handling it +} \ No newline at end of file diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c old mode 100755 new mode 100644 index 6b1055ce6..a583679ee --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -1,169 +1,190 @@ /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file ReadTritium.c - * @brief - * + * @brief + * */ #include "ReadTritium.h" -#include "CANbus.h" + +#include + +#include "CanBus.h" +#include "SendCarCan.h" #include "UpdateDisplay.h" -#include "SendCarCAN.h" #include "os_cfg_app.h" -#include -//status limit flag masks -#define MASK_MOTOR_TEMP_LIMIT (1<<6) //check if motor temperature is limiting the motor +// status limit flag masks +#define MASK_MOTOR_TEMP_LIMIT \ + (1 << 6) // check if motor temperature is limiting the motor #define MAX_CAN_LEN 8 -#define RESTART_THRESHOLD 3 // Number of times to restart before asserting a nonrecoverable error -#define MOTOR_TIMEOUT_SECS 1 // Timeout for several missed motor messages +#define RESTART_THRESHOLD \ + 3 // Number of times to restart before asserting a nonrecoverable error +#define MOTOR_TIMEOUT_SECS 1 // Timeout for several missed motor messages #define MOTOR_TIMEOUT_TICKS (MOTOR_TIMEOUT_SECS * OS_CFG_TMR_TASK_RATE_HZ) +TritiumErrorCode motor_fault_bitmap = + kNone; // initialized to no error, changed when the motor asserts an error +static float motor_rpm = 0; +static float motor_velocity = 0; -tritium_error_code_t Motor_FaultBitmap = T_NONE; //initialized to no error, changed when the motor asserts an error -static float Motor_RPM = 0; -static float Motor_Velocity = 0; - -static OS_TMR MotorWatchdog; +static OS_TMR motor_watchdog; // Function prototypes -static void assertTritiumError(tritium_error_code_t motor_err); +static void assertTritiumError(TritiumErrorCode motor_err); // Callback for motor watchdog static void motorWatchdog(void *tmr, void *p_arg) { // Attempt to restart 3 times, then fail - assertTritiumError(T_MOTOR_WATCHDOG_TRIP); + assertTritiumError(kMotorWatchdogTrip); } +void TaskReadTritium(void *p_arg) { + OS_ERR err = 0; + CanData data_buf = {0}; -void Task_ReadTritium(void *p_arg){ - OS_ERR err; - CANDATA_t dataBuf = {0}; + // Timer doesn't seem to trigger without initial delay? Might be an RTOS bug + static bool watchdog_created = false; - static bool watchdogCreated = false; + while (1) { + ErrorStatus status = CanBusRead(&data_buf, true, MOTORCAN); - while (1){ - ErrorStatus status = CANbus_Read(&dataBuf, true, MOTORCAN); + if (status == SUCCESS) { + if (!watchdog_created) { + OSTmrCreate(&motor_watchdog, "Motor watchdog", + MOTOR_TIMEOUT_TICKS, MOTOR_TIMEOUT_TICKS, + OS_OPT_TMR_PERIODIC, motorWatchdog, NULL, &err); + ASSERT_OS_ERROR(err); - if (status == SUCCESS){ - if(!watchdogCreated){ // Timer doesn't seem to trigger without initial delay? Might be an RTOS bug - OSTmrCreate(&MotorWatchdog, "Motor watchdog", MOTOR_TIMEOUT_TICKS, MOTOR_TIMEOUT_TICKS, OS_OPT_TMR_PERIODIC, motorWatchdog, NULL, &err); - assertOSError(err); + OSTmrStart(&motor_watchdog, &err); + ASSERT_OS_ERROR(err); - OSTmrStart(&MotorWatchdog, &err); - assertOSError(err); + watchdog_created = true; + } - watchdogCreated = true; + switch (data_buf.id) { + case kMotorStatus: { + // motor status error flags is in bytes 4-5 + motor_fault_bitmap = *( + (uint16_t *)(&data_buf + .data[4])); // Storing error flags + // into Motor_FaultBitmap + assertTritiumError(motor_fault_bitmap); + break; + } + + case kVelocity: { + OSTmrStart(&motor_watchdog, &err); // Reset the watchdog + ASSERT_OS_ERROR(err); + memcpy(&motor_rpm, &data_buf.data[0], sizeof(float)); + memcpy(&motor_velocity, &data_buf.data[4], sizeof(float)); + + // Motor RPM is in bytes 0-3 + motor_rpm = *((float *)(&data_buf.data[0])); + + // Car kVelocity (in m/s) is in bytes 4-7 + motor_velocity = *((float *)(&data_buf.data[4])); + uint32_t car_velocity = (uint32_t)motor_velocity; + + car_velocity = + ((car_velocity * 100) * + 3600); // Converting from m/s to m/h, // NOLINT + // using fixed point factor of 100 + car_velocity = ((car_velocity / 160934) * // NOLINT + 10); // NOLINT // Converting from m/h to + // mph, multiplying by 10 to make + // value "larger" for displaying + + UpdateDisplaySetVelocity(car_velocity); + } + + default: { + break; // for cases not handled currently + } } - switch(dataBuf.ID){ - case MOTOR_STATUS:{ - // motor status error flags is in bytes 4-5 - Motor_FaultBitmap = *((uint16_t*)(&dataBuf.data[4])); //Storing error flags into Motor_FaultBitmap - assertTritiumError(Motor_FaultBitmap); - break; - } - - case VELOCITY:{ - OSTmrStart(&MotorWatchdog, &err); // Reset the watchdog - assertOSError(err); - memcpy(&Motor_RPM, &dataBuf.data[0], sizeof(float)); - memcpy(&Motor_Velocity, &dataBuf.data[4], sizeof(float)); - - //Motor RPM is in bytes 0-3 - Motor_RPM = *((float*)(&dataBuf.data[0])); - - //Car Velocity (in m/s) is in bytes 4-7 - Motor_Velocity = *((float*)(&dataBuf.data[4])); - uint32_t Car_Velocity = Motor_Velocity; - - Car_Velocity = ((Car_Velocity * 100) * 3600); //Converting from m/s to m/h, using fixed point factor of 100 - Car_Velocity = ((Car_Velocity / 160934) * 10); //Converting from m/h to mph, multiplying by 10 to make value "larger" for displaying - - UpdateDisplay_SetVelocity(Car_Velocity); - - } - - default:{ - break; //for cases not handled currently - } - - } - - SendCarCAN_Put(dataBuf); // Forward message on CarCAN for telemetry - } - } + SendCarCanPut(data_buf); // Forward message on CarCAN for telemetry + } + } } -static void restartMotorController(void){ - CANDATA_t resetmsg = {0}; - resetmsg.ID = MOTOR_RESET; - CANbus_Send(resetmsg, true, MOTORCAN); +static void restartMotorController(void) { + CanData resetmsg = {0}; + resetmsg.id = kMotorReset; + CanBusSend(resetmsg, true, MOTORCAN); } - -float Motor_RPM_Get(){ //getter function for motor RPM - return Motor_RPM; +float MotorRpmGet() { // getter function for motor RPM + return motor_rpm; } -float Motor_Velocity_Get(){ //getter function for motor velocity - return Motor_Velocity; +float MotorVelocityGet() { // getter function for motor velocity + return motor_velocity; } - /** * Error handler functions - * Passed as callback functions to the main throwTaskError function by assertTritiumError -*/ + * Passed as callback functions to the main ThrowTaskError function by + * assertTritiumError + */ /** - * @brief A callback function to be run by the main throwTaskError function for hall sensor errors - * restart the motor if the number of hall errors is still less than the MOTOR_RESTART_THRESHOLD. - */ -static inline void handler_ReadTritium_HallError(void) { - restartMotorController(); + * @brief A callback function to be run by the main ThrowTaskError function for + * hall sensor errors restart the motor if the number of hall errors is still + * less than the MOTOR_RESTART_THRESHOLD. + */ +static inline void handlerReadTritiumHallError(void) { + restartMotorController(); } - /** * @brief Assert a Tritium error by checking Motor_FaultBitmap * and asserting the error with its handler callback if one exists. - * Can result in restarting the motor (for hall sensor errors while less than MOTOR_RESTART_THRESHOLD) - * or locking the scheduler and entering a nonrecoverable fault (all other cases) + * Can result in restarting the motor (for hall sensor errors while less than + * MOTOR_RESTART_THRESHOLD) or locking the scheduler and entering a + * nonrecoverable fault (all other cases) * @param motor_err Bitmap with motor error codes to check */ -static void assertTritiumError(tritium_error_code_t motor_err){ - static uint8_t hall_fault_cnt = 0; //trip counter, doesn't ever reset - static uint8_t motor_fault_cnt = 0; - - Error_ReadTritium = (error_code_t)motor_err; // Store error codes for inspection info - if(motor_err == T_NONE) return; // No error, return - // NOTE: If we had >1 recoverable errors, - // Hall sensor error is the only recoverable error, so any other error // make sure a combination of them wouldn't - // or combination of errors includes at least one that is nonrecoverable // accidentally fall into this nonrecoverable bucket - if(motor_err != T_HALL_SENSOR_ERR && motor_err != T_MOTOR_WATCHDOG_TRIP){ - // Assert a nonrecoverable error with no callback function- nonrecoverable will kill the motor and infinite loop - throwTaskError(Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); - return; - } - - // If it's purely a hall sensor error, try to restart the motor a few times and then fail out - - if(motor_err == T_HALL_SENSOR_ERR && ++hall_fault_cnt > RESTART_THRESHOLD){ // Threshold has been exceeded - // Assert a nonrecoverable error that will kill the motor, display a fault screen, and infinite loop - throwTaskError(Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); - return; - } - - //try to restart the motor a few times and then fail out - if(motor_err == T_MOTOR_WATCHDOG_TRIP && ++motor_fault_cnt > RESTART_THRESHOLD){ - // Assert a nonrecoverable error that will kill the motor, display a fault screen, and infinite loop - throwTaskError(Error_ReadTritium, NULL, OPT_LOCK_SCHED, OPT_NONRECOV); - return; - } - - // Threshold hasn't been exceeded, so assert a recoverable error with the motor restart callback function - throwTaskError(Error_ReadTritium, handler_ReadTritium_HallError, OPT_NO_LOCK_SCHED, OPT_RECOV); - - Error_ReadTritium = T_NONE; // Clear the error after handling it +static void assertTritiumError(TritiumErrorCode motor_err) { + static uint8_t hall_fault_cnt = 0; // trip counter, doesn't ever reset + static uint8_t motor_fault_cnt = 0; + + error_read_tritium = + (ErrorCode)motor_err; // Store error codes for inspection info + if (motor_err == kNone) { + return; // No error, return + } + if (motor_err != kHallSensorErr && motor_err != kMotorWatchdogTrip) { + // Assert a nonrecoverable error with no callback function- + // nonrecoverable will kill the motor and infinite loop + ThrowTaskError(error_read_tritium, NULL, kOptLockSched, kOptNonrecov); + return; + } + + // If it's purely a hall sensor error, try to restart the motor a few times + // and then fail out + + if (motor_err == kHallSensorErr && + ++hall_fault_cnt > RESTART_THRESHOLD) { // Threshold has been exceeded + // Assert a nonrecoverable error that will kill the motor, display a + // fault screen, and infinite loop + ThrowTaskError(error_read_tritium, NULL, kOptLockSched, kOptNonrecov); + return; + } + + // try to restart the motor a few times and then fail out + if (motor_err == kMotorWatchdogTrip && + ++motor_fault_cnt > RESTART_THRESHOLD) { + // Assert a nonrecoverable error that will kill the motor, display a + // fault screen, and infinite loop + ThrowTaskError(error_read_tritium, NULL, kOptLockSched, kOptNonrecov); + return; + } + + // Threshold hasn't been exceeded, so assert a recoverable error with the + // motor restart callback function + ThrowTaskError(error_read_tritium, handlerReadTritiumHallError, + kOptNoLockSched, kOptRecov); + + error_read_tritium = kNone; // Clear the error after handling it } diff --git a/Apps/Src/SendCarCAN.c b/Apps/Src/SendCarCAN.c deleted file mode 100644 index 0272b8b6d..000000000 --- a/Apps/Src/SendCarCAN.c +++ /dev/null @@ -1,179 +0,0 @@ -/** - * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar - * @file SendCarCAN.c - * @brief Function implementations for the SendCarCAN application. - * - * This contains functions relevant to placing CAN messages in a CarCAN queue and periodically sending - * those messages in the SendCarCAN task. - * - */ - -#include "common.h" -#include "os_cfg_app.h" -#include "CANbus.h" -#include "Minions.h" -#include "Contactors.h" -#include "Pedals.h" -#include "Tasks.h" -#include "SendCarCAN.h" -#include "SendTritium.h" - -#define IO_STATE_DLY_MS 250u - -#define SENDCARCAN_MSG_SKIP_CTR 3 - -// Task_PutIOState -OS_TCB putIOState_TCB; -CPU_STK putIOState_Stk[TASK_SEND_CAR_CAN_STACK_SIZE]; - -//fifo -#define FIFO_TYPE CANDATA_t -#define FIFO_SIZE 50 -#define FIFO_NAME SendCarCAN_Q -#include "fifo.h" - -static SendCarCAN_Q_t CANFifo; - -static OS_SEM CarCAN_Sem4; -static OS_MUTEX CarCAN_Mtx; - -static void Task_PutIOState(void *p_arg); - -/** - * @brief return the space left in SendCarCAN_Q for debug purposes -*/ -#ifdef DEBUG -uint8_t get_SendCarCAN_Q_Space(void) { - return (CANFifo.get - CANFifo.put - 1) % (sizeof CANFifo.buffer / sizeof CANFifo.buffer[0]); -} -#endif - -/** - * @brief Wrapper to put new message in the CAN queue -*/ -void SendCarCAN_Put(CANDATA_t message){ - OS_ERR err; - CPU_TS ticks; - bool success = false; - - static uint8_t carcan_ctr = 0; - - if(carcan_ctr > SENDCARCAN_MSG_SKIP_CTR){ - OSMutexPend(&CarCAN_Mtx, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); - assertOSError(err); - - success = SendCarCAN_Q_put(&CANFifo, message); - - OSMutexPost(&CarCAN_Mtx, OS_OPT_POST_NONE, &err); - assertOSError(err); - - carcan_ctr = 0; - } - carcan_ctr++; - - - if(success) { - OSSemPost(&CarCAN_Sem4, OS_OPT_POST_1, &err); - assertOSError(err); - } -} - -/** - * @brief Initialize SendCarCAN -*/ -void SendCarCAN_Init(void) { - OS_ERR err; - - OSMutexCreate(&CarCAN_Mtx, "CarCAN_Mtx", &err); - assertOSError(err); - - OSSemCreate(&CarCAN_Sem4, "CarCAN_Sem4", 0, &err); - assertOSError(err); - - SendCarCAN_Q_renew(&CANFifo); -} - -/** - * @brief Grabs the latest messages from the queue and sends over CarCAN -*/ -void Task_SendCarCAN(void *p_arg){ - OS_ERR err; - CPU_TS ticks; - - CANDATA_t message; - memset(&message, 0, sizeof message); - - // PutIOState - OSTaskCreate( - (OS_TCB*)&putIOState_TCB, - (CPU_CHAR*)"PutIOState", - (OS_TASK_PTR)Task_PutIOState, - (void*)NULL, - (OS_PRIO)TASK_PUT_IOSTATE_PRIO, - (CPU_STK*)putIOState_Stk, - (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, - (CPU_STK_SIZE)TASK_SEND_CAR_CAN_STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)0, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR), - (OS_ERR*)&err - ); - assertOSError(err); - - while (1) { - - // Check if there's something to send in the queue (either IOState or Car state from sendTritium) - OSSemPend(&CarCAN_Sem4, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); - assertOSError(err); - - OSMutexPend(&CarCAN_Mtx, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); - assertOSError(err); - - bool res = SendCarCAN_Q_get(&CANFifo, &message); - - OSMutexPost(&CarCAN_Mtx, OS_OPT_POST_NONE, &err); - assertOSError(err); - - if(res) CANbus_Send(message, true, CARCAN); - } -} - -static void putIOState(void){ - CANDATA_t message; - memset(&message, 0, sizeof message); - message.ID = IO_STATE; - - // Get pedal information - message.data[0] = Pedals_Read(ACCELERATOR); - message.data[1] = Pedals_Read(BRAKE); - - // Get minion information - for(pin_t pin = 0; pin < NUM_PINS; pin++){ - bool pinState = Minions_Read(pin); - message.data[2] |= pinState << pin; - } - - // Get contactor info - for(contactor_t contactor = 0; contactor < NUM_CONTACTORS; contactor++){ - bool contactorState = (Contactors_Get(contactor) == ON) ? true : false; - message.data[3] |= contactorState << contactor; - } - - // Tell BPS if the array contactor should be on - message.data[3] |= (!Minions_Read(IGN_1) || !Minions_Read(IGN_2)) << 2; - - CANbus_Send(message, true, CARCAN); -} - -/** - * @brief sends IO information over CarCAN every IO_STATE_DLY_MS -*/ -static void Task_PutIOState(void *p_arg) { - OS_ERR err; - while (1) { - putIOState(); - OSTimeDlyHMSM(0, 0, 0, IO_STATE_DLY_MS, OS_OPT_TIME_HMSM_STRICT, &err); - assertOSError(err); - } -} diff --git a/Apps/Src/SendCarCan.c b/Apps/Src/SendCarCan.c new file mode 100644 index 000000000..086a0a70b --- /dev/null +++ b/Apps/Src/SendCarCan.c @@ -0,0 +1,176 @@ +/** + * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar + * @file SendCarCAN.c + * @brief Function implementations for the SendCarCAN application. + * + * This contains functions relevant to placing CAN messages in a CarCAN queue + * and periodically sending those messages in the SendCarCAN task. This contains + * functions relevant to placing CAN messages in a CarCAN queue and periodically + * sending those messages in the SendCarCAN task. + * + */ + +#include "SendCarCan.h" + +#include "CanBus.h" +#include "Contactors.h" +#include "Minions.h" +#include "Pedals.h" +#include "SendTritium.h" +#include "Tasks.h" +#include "common.h" +#include "os_cfg_app.h" + +#define IO_STATE_DLY_MS 250u + +#define SENDCARCAN_MSG_SKIP_CTR 3 + +// Task_PutIOState +OS_TCB put_io_state_tcb; +CPU_STK put_io_state_stk[TASK_SEND_CAR_CAN_STACK_SIZE]; + +// fifo +#define FIFO_TYPE CanData +#define FIFO_SIZE 50 +#define FIFO_NAME Queue +#include "fifo.h" + +static Queue can_fifo; + +static OS_SEM car_can_sem4; +static OS_MUTEX car_can_mtx; + +static void taskPutIoState(void *p_arg); + +/** + * @brief return the space left in Queue for debug purposes + */ +#ifdef DEBUG +uint8_t GetSendCarCanQueueSpace(void) { + return (can_fifo.get - can_fifo.put - 1) % + (sizeof can_fifo.buffer / sizeof can_fifo.buffer[0]); +} +#endif + +/** + * @brief Wrapper to put new message in the CAN queue + */ +void SendCarCanPut(CanData message) { + OS_ERR err = OS_ERR_NONE; + CPU_TS ticks = 0; + bool success = false; + + static uint8_t carcan_ctr = 0; + + if (carcan_ctr > SENDCARCAN_MSG_SKIP_CTR) { + OSMutexPend(&car_can_mtx, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); + ASSERT_OS_ERROR(err); + + success = QueuePut(&can_fifo, message); + + OSMutexPost(&car_can_mtx, OS_OPT_POST_NONE, &err); + ASSERT_OS_ERROR(err); + + carcan_ctr = 0; + } + carcan_ctr++; + + if (success) { + OSSemPost(&car_can_sem4, OS_OPT_POST_1, &err); + ASSERT_OS_ERROR(err); + } +} + +/** + * @brief Initialize SendCarCAN + */ +void SendCarCanInit(void) { + OS_ERR err = 0; + + OSMutexCreate(&car_can_mtx, "CarCAN_Mtx", &err); + ASSERT_OS_ERROR(err); + + OSSemCreate(&car_can_sem4, "CarCAN_Sem4", 0, &err); + ASSERT_OS_ERROR(err); + + QueueRenew(&can_fifo); +} + +/** + * @brief Grabs the latest messages from the queue and sends over CarCAN + */ +void TaskSendCarCan(void *p_arg) { + OS_ERR err = 0; + CPU_TS ticks = 0; + + CanData message; + memset(&message, 0, sizeof message); + + // PutIOState + OSTaskCreate((OS_TCB *)&put_io_state_tcb, (CPU_CHAR *)"PutIOState", + (OS_TASK_PTR)taskPutIoState, (void *)NULL, + (OS_PRIO)TASK_PUT_IOSTATE_PRIO, (CPU_STK *)put_io_state_stk, + (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, + (CPU_STK_SIZE)TASK_SEND_CAR_CAN_STACK_SIZE, (OS_MSG_QTY)0, + (OS_TICK)0, (void *)NULL, (OS_OPT)(OS_OPT_TASK_STK_CLR), + (OS_ERR *)&err); + ASSERT_OS_ERROR(err); + + while (1) { + // Check if there's something to send in the queue (either IOState or + // Car state from sendTritium) + OSSemPend(&car_can_sem4, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); + ASSERT_OS_ERROR(err); + + OSMutexPend(&car_can_mtx, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); + ASSERT_OS_ERROR(err); + + bool res = QueueGet(&can_fifo, &message); + + OSMutexPost(&car_can_mtx, OS_OPT_POST_NONE, &err); + ASSERT_OS_ERROR(err); + + if (res) { + CanBusSend(message, true, CARCAN); + } + } +} + +static void putIOState(void) { + CanData message; + memset(&message, 0, sizeof message); + message.id = kIoState; + + // Get pedal information + message.data[0] = PedalsRead(kAccelerator); + message.data[1] = PedalsRead(kBrake); + + // Get minion information + for (Pin pin = 0; pin < kNumPins; pin++) { + bool pin_state = MinionsRead(pin); + message.data[2] |= pin_state << pin; + } + + // Get contactor info + for (Contactor contactor = 0; contactor < kNumContactors; contactor++) { + bool contactor_state = (ContactorsGet(contactor) == ON) ? true : false; + message.data[3] |= contactor_state << contactor; + } + + // Tell BPS if the array contactor should be on + message.data[3] |= (!MinionsRead(kIgn1) || !MinionsRead(kIgn2)) << 2; + + CanBusSend(message, true, CARCAN); +} + +/** + * @brief sends IO information over CarCAN every IO_STATE_DLY_MS + */ +static void taskPutIoState(void *p_arg) { + OS_ERR err = 0; + while (1) { + putIOState(); + OSTimeDlyHMSM(0, 0, 0, IO_STATE_DLY_MS, OS_OPT_TIME_HMSM_STRICT, &err); + ASSERT_OS_ERROR(err); + } +} diff --git a/Apps/Src/SendTritium.c b/Apps/Src/SendTritium.c index 9f6f85307..e91c47608 100644 --- a/Apps/Src/SendTritium.c +++ b/Apps/Src/SendTritium.c @@ -2,149 +2,151 @@ * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file SendTritium.c * @brief Function implementations for the SendTritium application. - * - * This contains functions relevant to updating the velocity and current setpoitns - * of the Tritium motor controller. The implementation includes a normal current - * controlled mode, a one-pedal driving mode (with regenerative braking), and cruise control. - * The logic is determined through a finite state machine implementation. - * - * If the macro SENDTRITIUM_EXPOSE_VARS is defined prior to including SendTritium.h, - * relevant setters will be exposed as externs for unit testing - * and hardware inputs won't be read and motor commands won't be sent over MotorCAN. - * If the macro SENDTRITIUM_PRINT_MES is also defined prior to including SendTritium.h, - * debug info will be printed via UART. + * + * This contains functions relevant to updating the velocity and current + * setpoitns of the Tritium motor controller. The implementation includes a + * normal current controlled mode, a one-pedal driving mode (with regenerative + * braking), and cruise control. The logic is determined through a finite state + * machine implementation. + * + * If the macro SENDTRITIUM_EXPOSE_VARS is defined prior to including + * SendTritium.h, relevant setters will be exposed as externs for unit testing + * and hardware inputs won't be read and motor commands won't be sent over + * MotorCAN. If the macro SENDTRITIUM_PRINT_MES is also defined prior to + * including SendTritium.h, debug info will be printed via UART. */ -#include "Pedals.h" -#include "ReadCarCAN.h" -#include "Minions.h" #include "SendTritium.h" + +#include "CanBus.h" +#include "CanConfig.h" +#include "Minions.h" +#include "Pedals.h" +#include "ReadCarCan.h" #include "ReadTritium.h" -#include "SendCarCAN.h" -#include "CANbus.h" +#include "SendCarCan.h" #include "UpdateDisplay.h" -#include "CANConfig.h" #include "common.h" // Macros -#define MAX_VELOCITY 20000.0f // rpm (unobtainable value) +#define MAX_VELOCITY 20000.0f // rpm (unobtainable value) -#define MIN_CRUISE_VELOCITY mpsToRpm(20.0f) // rpm -#define MAX_GEARSWITCH_VELOCITY mpsToRpm(8.0f) // rpm +#define MIN_CRUISE_VELOCITY MpsToRpm(20.0f) // rpm +#define MAX_GEARSWITCH_VELOCITY MpsToRpm(8.0f) // rpm #define BRAKE_PEDAL_THRESHOLD 50 // percent -#define ACCEL_PEDAL_THRESHOLD 10 // percent +#define ACCEL_PEDAL_THRESHOLD 10 // percent -#define ONEPEDAL_BRAKE_THRESHOLD 25 // percent -#define ONEPEDAL_NEUTRAL_THRESHOLD 35 // percent +#define ONEPEDAL_BRAKE_THRESHOLD 25 // percent +#define ONEPEDAL_NEUTRAL_THRESHOLD 35 // percent -#define PEDAL_MIN 0 // percent -#define PEDAL_MAX 100 // percent -#define CURRENT_SP_MIN 0 // percent -#define CURRENT_SP_MAX 100 // percent +#define PEDAL_MIN 0 // percent +#define PEDAL_MAX 100 // percent +#define CURRENT_SP_MIN 0 // percent +#define CURRENT_SP_MAX 100 // percent -#define GEAR_FAULT_THRESHOLD 3 // number of times gear fault can occur before it is considered a fault +#define GEAR_FAULT_THRESHOLD \ + 3 // number of times gear fault can occur before it is considered a fault // Inputs -static bool cruiseEnable = false; -static bool cruiseSet = false; -static bool onePedalEnable = false; -static bool regenEnable = false; +static bool cruise_enable = false; +static bool cruise_set = false; +static bool one_pedal_enable = false; +static bool regen_enable = false; -static uint8_t brakePedalPercent = 0; -static uint8_t accelPedalPercent = 0; +static uint8_t brake_pedal_percent = 0; +static uint8_t accel_pedal_percent = 0; -static Gear_t gear = NEUTRAL_GEAR; +static Gear gear = kNeutralGear; // Outputs -float currentSetpoint = 0; -float velocitySetpoint = 0; -float cruiseVelSetpoint = 0; +float current_setpoint = 0; +float velocity_setpoint = 0; +float cruise_vel_setpoint = 0; // Current observed velocity -static float velocityObserved = 0; +static float velocity_observed = 0; +#ifndef SENDTRITIUM_EXPOSE_VARS // Counter for sending setpoints to motor -static uint8_t motorMsgCounter = 0; +static uint8_t motor_msg_counter = 0; // Debouncing counters -static uint8_t onePedalCounter = 0; -static uint8_t cruiseEnableCounter = 0; -static uint8_t cruiseSetCounter = 0; +static uint8_t one_pedal_counter = 0; +static uint8_t cruise_enable_counter = 0; +static uint8_t cruise_set_counter = 0; // Button states -static bool onePedalButton = false; -static bool onePedalPrevious = false; +static bool one_pedal_button = false; +static bool one_pedal_previous = false; -static bool cruiseEnableButton = false; -static bool cruiseEnablePrevious = false; +static bool cruise_enable_button = false; +static bool cruise_enable_previous = false; +#endif // FSM -static TritiumState_t prevState; // Previous state -static TritiumState_t state; // Current state - -// Getter functions for local variables in SendTritium.c -GETTER(bool, cruiseEnable) -GETTER(bool, cruiseSet) -GETTER(bool, onePedalEnable) -GETTER(bool, regenEnable) -GETTER(uint8_t, brakePedalPercent) -GETTER(uint8_t, accelPedalPercent) -GETTER(Gear_t, gear) -GETTER(TritiumState_t, state) -GETTER(float, velocityObserved) -GETTER(float, cruiseVelSetpoint) -GETTER(float, currentSetpoint) -GETTER(float, velocitySetpoint) - -// Setter functions for local variables in SendTritium.c +static TritiumState prev_state; // Previous state +static TritiumState state; // Current state + +bool GetCruiseEnable(void) { return cruise_enable; } +bool GetCruiseSet(void) { return cruise_set; } +bool GetOnePedalEnable(void) { return one_pedal_enable; } +bool GetRegenEnable(void) { return regen_enable; } +uint8_t GetBrakePedalPercent(void) { return brake_pedal_percent; } +uint8_t GetAccelPedalPercent(void) { return accel_pedal_percent; } +Gear GetGear(void) { return gear; } +TritiumState GetState(void) { return state; } +float GetVelocityObserved(void) { return velocity_observed; } +float GetCruiseVelSetpoint(void) { return cruise_vel_setpoint; } +float GetCurrentSetpoint(void) { return current_setpoint; } +float GetVelocitySetpoint(void) { return velocity_setpoint; } + #ifdef SENDTRITIUM_EXPOSE_VARS -SETTER(bool, cruiseEnable) -SETTER(bool, cruiseSet) -SETTER(bool, onePedalEnable) -SETTER(bool, regenEnable) -SETTER(uint8_t, brakePedalPercent) -SETTER(uint8_t, accelPedalPercent) -SETTER(Gear_t, gear) -SETTER(TritiumState_t, state) -SETTER(float, velocityObserved) -SETTER(float, cruiseVelSetpoint) -SETTER(float, currentSetpoint) -SETTER(float, velocitySetpoint) +void SetCruiseEnable(bool value) { cruise_enable = value; } +void SetCruiseSet(bool value) { cruise_set = value; } +void SetOnePedalEnable(bool value) { one_pedal_enable = value; } +void SetRegenEnable(bool value) { regen_enable = value; } +void SetBrakePedalPercent(uint8_t value) { brake_pedal_percent = value; } +void SetAccelPedalPercent(uint8_t value) { accel_pedal_percent = value; } +void SetGear(Gear value) { gear = value; } +void SetState(TritiumState value) { state = value; } +void SetVelocityObserved(float value) { velocity_observed = value; } +void SetCruiseVelSetpoint(float value) { cruise_vel_setpoint = value; } +void SetCurrentSetpoint(float value) { current_setpoint = value; } +void SetVelocitySetpoint(float value) { velocity_setpoint = value; } #endif // Handler & Decider Declarations -static void ForwardDriveHandler(void); -static void ForwardDriveDecider(void); -static void NeutralDriveHandler(void); -static void NeutralDriveDecider(void); -static void ReverseDriveHandler(void); -static void ReverseDriveDecider(void); -static void RecordVelocityHandler(void); -static void RecordVelocityDecider(void); -static void PoweredCruiseHandler(void); -static void PoweredCruiseDecider(void); -static void CoastingCruiseHandler(void); -static void CoastingCruiseDecider(void); -static void BrakeHandler(void); -static void BrakeDecider(void); -static void OnePedalDriveHandler(void); -static void OnePedalDriveDecider(void); -static void AccelerateCruiseHandler(void); -static void AccelerateCruiseDecider(void); +static void forwardDriveHandler(void); +static void forwardDriveDecider(void); +static void neutralDriveHandler(void); +static void neutralDriveDecider(void); +static void reverseDriveHandler(void); +static void reverseDriveDecider(void); +static void recordVelocityHandler(void); +static void recordVelocityDecider(void); +static void poweredCruiseHandler(void); +static void poweredCruiseDecider(void); +static void coastingCruiseHandler(void); +static void coastingCruiseDecider(void); +static void brakeHandler(void); +static void brakeDecider(void); +static void onePedalDriveHandler(void); +static void onePedalDriveDecider(void); +static void accelerateCruiseHandler(void); +static void accelerateCruiseDecider(void); // FSM -static const TritiumState_t FSM[9] = { - {FORWARD_DRIVE, &ForwardDriveHandler, &ForwardDriveDecider}, - {NEUTRAL_DRIVE, &NeutralDriveHandler, &NeutralDriveDecider}, - {REVERSE_DRIVE, &ReverseDriveHandler, &ReverseDriveDecider}, - {RECORD_VELOCITY, &RecordVelocityHandler, &RecordVelocityDecider}, - {POWERED_CRUISE, &PoweredCruiseHandler, &PoweredCruiseDecider}, - {COASTING_CRUISE, &CoastingCruiseHandler, &CoastingCruiseDecider}, - {BRAKE_STATE, &BrakeHandler, &BrakeDecider}, - {ONEPEDAL, &OnePedalDriveHandler, &OnePedalDriveDecider}, - {ACCELERATE_CRUISE, &AccelerateCruiseHandler, &AccelerateCruiseDecider} -}; +static const TritiumState kFsm[9] = { + {kForwardDrive, &forwardDriveHandler, &forwardDriveDecider}, + {kNeutralDrive, &neutralDriveHandler, &neutralDriveDecider}, + {kReverseDrive, &reverseDriveHandler, &reverseDriveDecider}, + {kRecordVelocity, &recordVelocityHandler, &recordVelocityDecider}, + {kPoweredCruise, &poweredCruiseHandler, &poweredCruiseDecider}, + {kCoastingCruise, &coastingCruiseHandler, &coastingCruiseDecider}, + {kBrakeState, &brakeHandler, &brakeDecider}, + {kOnePedal, &onePedalDriveHandler, &onePedalDriveDecider}, + {kAccelerateCruise, &accelerateCruiseHandler, &accelerateCruiseDecider}}; // Helper Functions @@ -152,69 +154,71 @@ static const TritiumState_t FSM[9] = { * @brief Converts integer percentage to float percentage * @param percent integer percentage from 0-100 * @returns float percentage from 0.0-1.0 -*/ -extern const float pedalToPercent[]; -static float percentToFloat(uint8_t percent){ - if(percent > 100){ - return 1.0f; + */ +extern const float kPedalToPercent[]; +static float percentToFloat(uint8_t percent) { + if (percent > 100) { + return 1.0F; } - return pedalToPercent[percent]; + return kPedalToPercent[percent]; } #ifdef SENDTRITIUM_PRINT_MES + +#define STATE_NAME_STR_SIZE 20 + /** * @brief Dumps info to UART during testing -*/ -static void getName(char* nameStr, uint8_t stateNameNum){ - switch(stateNameNum){ - case FORWARD_DRIVE: - strcpy(nameStr, "FORWARD_DRIVE"); + */ +static void getName(char* name_str, uint8_t state_name_num) { + switch (state_name_num) { + case kForwardDrive: + strcpy(name_str, "FORWARD_DRIVE"); break; - case NEUTRAL_DRIVE: - strcpy(nameStr, "NEUTRAL_DRIVE"); + case kNeutralDrive: + strcpy(name_str, "NEUTRAL_DRIVE"); break; - case REVERSE_DRIVE: - strcpy(nameStr, "REVERSE_DRIVE"); + case kReverseDrive: + strcpy(name_str, "REVERSE_DRIVE"); break; - case RECORD_VELOCITY: - strcpy(nameStr, "RECORD_VELOCITY"); + case kRecordVelocity: + strcpy(name_str, "RECORD_VELOCITY"); break; - case POWERED_CRUISE: - strcpy(nameStr, "POWERED_CRUISE"); + case kPoweredCruise: + strcpy(name_str, "POWERED_CRUISE"); break; - case COASTING_CRUISE: - strcpy(nameStr, "COASTING_CRUISE"); + case kCoastingCruise: + strcpy(name_str, "COASTING_CRUISE"); break; - case BRAKE_STATE: - strcpy(nameStr, "BRAKE_STATE"); + case kBrakeState: + strcpy(name_str, "BRAKE_STATE"); break; - case ONEPEDAL: - strcpy(nameStr, "ONEPEDAL"); + case kOnePedal: + strcpy(name_str, "ONEPEDAL"); break; - case ACCELERATE_CRUISE: - strcpy(nameStr, "ACCELERATE_CRUISE"); + case kAccelerateCruise: + strcpy(name_str, "ACCELERATE_CRUISE"); break; default: - strcpy(nameStr, "UNKNOWN"); + strcpy(name_str, "UNKNOWN"); break; } - return; } -static void dumpInfo(){ +static void dumpInfo() { printf("-------------------\n\r"); - char stateName[20]; - getName(stateName, state.name); - printf("State: %s\n\r", stateName); - printf("cruiseEnable: %d\n\r", cruiseEnable); - printf("cruiseSet: %d\n\r", cruiseSet); - printf("onePedalEnable: %d\n\r", onePedalEnable); - printf("brakePedalPercent: %d\n\r", brakePedalPercent); - printf("accelPedalPercent: %d\n\r", accelPedalPercent); + char state_name[STATE_NAME_STR_SIZE]; + getName(state_name, state.name); + printf("State: %s\n\r", state_name); + printf("cruiseEnable: %d\n\r", cruise_enable); + printf("cruiseSet: %d\n\r", cruise_set); + printf("onePedalEnable: %d\n\r", one_pedal_enable); + printf("brakePedalPercent: %d\n\r", brake_pedal_percent); + printf("accelPedalPercent: %d\n\r", accel_pedal_percent); printf("gear: %d\n\r", (uint8_t)gear); - print_float("currentSetpoint: ", currentSetpoint); - print_float("velocitySetpoint: ", velocitySetpoint); - print_float("velocityObserved: ", velocityObserved); + PrintFloat("currentSetpoint: ", current_setpoint); + PrintFloat("velocitySetpoint: ", velocity_setpoint); + PrintFloat("velocityObserved: ", velocity_observed); printf("-------------------\n\r"); } #endif @@ -222,416 +226,472 @@ static void dumpInfo(){ #ifndef SENDTRITIUM_EXPOSE_VARS /** * @brief Reads inputs from the system -*/ -static void readInputs(){ - + */ +static void readInputs() { // Update pedals - brakePedalPercent = Pedals_Read(BRAKE); - accelPedalPercent = Pedals_Read(ACCELERATOR); - + brake_pedal_percent = PedalsRead(kBrake); + accel_pedal_percent = PedalsRead(kAccelerator); + // Update regen enable - regenEnable = ChargeEnable_Get(); + regen_enable = ChargeEnableGet(); // Update buttons - if(Minions_Read(REGEN_SW) && onePedalCounter < DEBOUNCE_PERIOD){onePedalCounter++;} - else if(onePedalCounter > 0){onePedalCounter--;} + if (MinionsRead(kRegenSw) && one_pedal_counter < DEBOUNCE_PERIOD) { + one_pedal_counter++; + } else if (one_pedal_counter > 0) { + one_pedal_counter--; + } + + if (MinionsRead(kCruzEn) && cruise_enable_counter < DEBOUNCE_PERIOD) { + cruise_enable_counter++; + } else if (cruise_enable_counter > 0) { + cruise_enable_counter--; + } - if(Minions_Read(CRUZ_EN) && cruiseEnableCounter < DEBOUNCE_PERIOD){cruiseEnableCounter++;} - else if(cruiseEnableCounter > 0){cruiseEnableCounter--;} + if (MinionsRead(kCruzSt) && cruise_set_counter < DEBOUNCE_PERIOD) { + cruise_set_counter++; + } else if (cruise_set_counter > 0) { + cruise_set_counter--; + } - if(Minions_Read(CRUZ_ST) && cruiseSetCounter < DEBOUNCE_PERIOD){cruiseSetCounter++;} - else if(cruiseSetCounter > 0){cruiseSetCounter--;} - // Update gears - bool forwardSwitch = Minions_Read(FOR_SW); - bool reverseSwitch = Minions_Read(REV_SW); - bool forwardGear = (forwardSwitch && !reverseSwitch); - bool reverseGear = (!forwardSwitch && reverseSwitch); - bool neutralGear = (!forwardSwitch && !reverseSwitch); + bool forward_switch = MinionsRead(kForSw); + bool reverse_switch = MinionsRead(kRevSw); + bool forward_gear = (forward_switch && !reverse_switch); + bool reverse_gear = (!forward_switch && reverse_switch); + bool neutral_gear = (!forward_switch && !reverse_switch); - uint8_t gearFault = (uint8_t) forwardGear + (uint8_t) reverseGear + (uint8_t) neutralGear; - static uint8_t gearFaultCnt = 0; + uint8_t gear_fault = + (uint8_t)forward_gear + (uint8_t)reverse_gear + (uint8_t)neutral_gear; + static uint8_t gear_fault_cnt = 0; - if(gearFault != 1){ + if (gear_fault != 1) { // Fault behavior - if(gearFaultCnt > GEAR_FAULT_THRESHOLD) state = FSM[NEUTRAL_DRIVE]; - else gearFaultCnt++; - } - else{ - gearFaultCnt = 0; + if (gear_fault_cnt > GEAR_FAULT_THRESHOLD) { + state = kFsm[kNeutralDrive]; + } else { + gear_fault_cnt++; + } + } else { + gear_fault_cnt = 0; } - if(neutralGear) gear = NEUTRAL_GEAR; - else if(forwardGear) gear = FORWARD_GEAR; - else if(reverseGear) gear = REVERSE_GEAR; - else gear = NEUTRAL_GEAR; + if (forward_gear) { + gear = kForwardGear; + } else if (reverse_gear) { + gear = kReverseGear; + } else { + gear = kNeutralGear; + } // Debouncing - if(onePedalCounter == DEBOUNCE_PERIOD){onePedalButton = true;} - else if(onePedalCounter == 0){onePedalButton = false;} + if (one_pedal_counter == DEBOUNCE_PERIOD) { + one_pedal_button = true; + } else if (one_pedal_counter == 0) { + one_pedal_button = false; + } - if(cruiseEnableCounter == DEBOUNCE_PERIOD){cruiseEnableButton = true;} - else if(cruiseEnableCounter == 0){cruiseEnableButton = false;} + if (cruise_enable_counter == DEBOUNCE_PERIOD) { + cruise_enable_button = true; + } else if (cruise_enable_counter == 0) { + cruise_enable_button = false; + } - if(cruiseSetCounter == DEBOUNCE_PERIOD){cruiseSet = true;} - else if(cruiseSetCounter == 0){cruiseSet = false;} + if (cruise_set_counter == DEBOUNCE_PERIOD) { + cruise_set = true; + } else if (cruise_set_counter == 0) { + cruise_set = false; + } // Toggle - if(onePedalButton != onePedalPrevious && onePedalPrevious){onePedalEnable = !onePedalEnable;} - if(!regenEnable) onePedalEnable = false; - onePedalPrevious = onePedalButton; - - if(cruiseEnableButton != cruiseEnablePrevious && cruiseEnablePrevious){cruiseEnable = !cruiseEnable;} - cruiseEnablePrevious = cruiseEnableButton; - + if (one_pedal_button != one_pedal_previous && one_pedal_previous) { + one_pedal_enable = !one_pedal_enable; + } + if (!regen_enable) { + one_pedal_enable = false; + } + one_pedal_previous = one_pedal_button; + + if (cruise_enable_button != cruise_enable_previous && + cruise_enable_previous) { + cruise_enable = !cruise_enable; + } + cruise_enable_previous = cruise_enable_button; + // Get observed velocity - velocityObserved = Motor_RPM_Get(); + velocity_observed = MotorRpmGet(); } #endif /** - * @brief Linearly map range of integers to another range of integers. + * @brief Linearly map range of integers to another range of integers. * in_min to in_max is mapped to out_min to out_max. * @param input input integer value * @param in_min minimum value of input range * @param in_max maximum value of input range * @param out_min minimum value of output range - * @param out_max maximum value of output range + * @param out_max maximum value of output range * @returns integer value from out_min to out_max -*/ -static uint8_t map(uint8_t input, uint8_t in_min, uint8_t in_max, uint8_t out_min, uint8_t out_max){ - if(in_min >= in_max) in_max = in_min; // The minimum of the input range should never be greater than the maximum of the input range - - if(input <= in_min){ + */ +static uint8_t map(uint8_t input, uint8_t in_min, uint8_t in_max, + uint8_t out_min, uint8_t out_max) { + if (in_min >= in_max) { + in_max = in_min; // The minimum of the input range should never be + // greater than the maximum of the input range + } + + if (input <= in_min) { // Lower bound the input to the minimum possible output return out_min; - } else if(input >= in_max){ + } + if (input >= in_max) { // Upper bound the input to the maximum output return out_max; - } else{ - // Linear mapping between ranges - uint8_t offset_in = input - in_min; // If input went from A -> B, it now goes from 0 -> B-A - uint8_t in_range = in_max - in_min; // Input range - uint8_t out_range = out_max - out_min; // Output range - uint8_t offset_out = out_min; - return (offset_in * out_range)/in_range + offset_out; // slope = out_range/in_range. y=mx+b so output=slope*offset_in+offset_out - } + } // Linear mapping between ranges + uint8_t offset_in = + input - in_min; // If input went from A -> B, it now goes from 0 -> B-A + uint8_t in_range = in_max - in_min; // Input range + uint8_t out_range = out_max - out_min; // Output range + uint8_t offset_out = out_min; + return (offset_in * out_range) / in_range + + offset_out; // slope = out_range/in_range. y=mx+b so + // output=slope*offset_in+offset_out } - /** - * @brief Put the CONTROL_MODE message onto the CarCAN bus, detailing + * @brief Put the kControlMode message onto the CarCAN bus, detailing * the current mode of control. -*/ -static void putControlModeCAN(){ - CANDATA_t message; + */ +static void putControlModeCAN() { + CanData message; memset(&message, 0, sizeof(message)); - message.ID = CONTROL_MODE; + message.id = kControlMode; message.data[0] = state.name; - SendCarCAN_Put(message); + SendCarCanPut(message); } // State Handlers & Deciders /** - * @brief Forward Drive State Handler. Accelerator is mapped directly + * @brief Forward Drive State Handler. Accelerator is mapped directly * to current setpoint at positive velocity. -*/ -static void ForwardDriveHandler(){ - if(prevState.name != state.name){ - UpdateDisplay_SetCruiseState(DISP_DISABLED); - UpdateDisplay_SetRegenState(DISP_DISABLED); - UpdateDisplay_SetGear(DISP_FORWARD); - } - velocitySetpoint = MAX_VELOCITY; - currentSetpoint = percentToFloat(map(accelPedalPercent, ACCEL_PEDAL_THRESHOLD, PEDAL_MAX, CURRENT_SP_MIN, CURRENT_SP_MAX)); + */ +static void forwardDriveHandler() { + if (prev_state.name != state.name) { + UpdateDisplaySetCruiseState(DISP_DISABLED); + UpdateDisplaySetRegenState(DISP_DISABLED); + UpdateDisplaySetGear(DISP_FORWARD); + } + velocity_setpoint = MAX_VELOCITY; + current_setpoint = + percentToFloat(map(accel_pedal_percent, ACCEL_PEDAL_THRESHOLD, + PEDAL_MAX, CURRENT_SP_MIN, CURRENT_SP_MAX)); } /** * @brief Forward Drive State Decider. Determines transitions out of * forward drive state (brake, record velocity, one pedal, neutral drive). -*/ -static void ForwardDriveDecider(){ - if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ - state = FSM[BRAKE_STATE]; - }else if(cruiseSet && cruiseEnable && velocityObserved >= MIN_CRUISE_VELOCITY){ - state = FSM[RECORD_VELOCITY]; - }else if(onePedalEnable){ - state = FSM[ONEPEDAL]; - }else if(gear == NEUTRAL_GEAR || gear == REVERSE_GEAR){ - state = FSM[NEUTRAL_DRIVE]; + */ +static void forwardDriveDecider() { + if (brake_pedal_percent >= BRAKE_PEDAL_THRESHOLD) { + state = kFsm[kBrakeState]; + } else if (cruise_set && cruise_enable && + velocity_observed >= MIN_CRUISE_VELOCITY) { + state = kFsm[kRecordVelocity]; + } else if (one_pedal_enable) { + state = kFsm[kOnePedal]; + } else if (gear == kNeutralGear || gear == kReverseGear) { + state = kFsm[kNeutralDrive]; } } /** * @brief Neutral Drive State Handler. No current is sent to the motor. -*/ -static void NeutralDriveHandler(){ - if(prevState.name != state.name){ - UpdateDisplay_SetCruiseState(DISP_DISABLED); - UpdateDisplay_SetRegenState(DISP_DISABLED); - UpdateDisplay_SetGear(DISP_NEUTRAL); - } - velocitySetpoint = MAX_VELOCITY; - currentSetpoint = 0.0f; - - cruiseEnable = false; - onePedalEnable = false; + */ +static void neutralDriveHandler() { + if (prev_state.name != state.name) { + UpdateDisplaySetCruiseState(DISP_DISABLED); + UpdateDisplaySetRegenState(DISP_DISABLED); + UpdateDisplaySetGear(DISP_NEUTRAL); + } + velocity_setpoint = MAX_VELOCITY; + current_setpoint = 0.0F; + + cruise_enable = false; + one_pedal_enable = false; } /** * @brief Neutral Drive State Decider. Determines transitions out of * neutral drive state (brake, forward drive, reverse drive). -*/ -static void NeutralDriveDecider(){ - if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ - state = FSM[BRAKE_STATE]; - }else if(gear == FORWARD_GEAR && velocityObserved >= -MAX_GEARSWITCH_VELOCITY){ - state = FSM[FORWARD_DRIVE]; - }else if(gear == REVERSE_GEAR && velocityObserved <= MAX_GEARSWITCH_VELOCITY){ - state = FSM[REVERSE_DRIVE]; + */ +static void neutralDriveDecider() { + if (brake_pedal_percent >= BRAKE_PEDAL_THRESHOLD) { + state = kFsm[kBrakeState]; + } else if (gear == kForwardGear && + velocity_observed >= -MAX_GEARSWITCH_VELOCITY) { + state = kFsm[kForwardDrive]; + } else if (gear == kReverseGear && + velocity_observed <= MAX_GEARSWITCH_VELOCITY) { + state = kFsm[kReverseDrive]; } } /** - * @brief Reverse Drive State Handler. Accelerator is mapped directly to + * @brief Reverse Drive State Handler. Accelerator is mapped directly to * current setpoint (at negative velocity). -*/ -static void ReverseDriveHandler(){ - if(prevState.name != state.name){ - UpdateDisplay_SetCruiseState(DISP_DISABLED); - UpdateDisplay_SetRegenState(DISP_DISABLED); - UpdateDisplay_SetGear(DISP_REVERSE); - } - velocitySetpoint = -MAX_VELOCITY; - currentSetpoint = percentToFloat(map(accelPedalPercent, ACCEL_PEDAL_THRESHOLD, PEDAL_MAX, CURRENT_SP_MIN, CURRENT_SP_MAX)); - cruiseEnable = false; - onePedalEnable = false; + */ +static void reverseDriveHandler() { + if (prev_state.name != state.name) { + UpdateDisplaySetCruiseState(DISP_DISABLED); + UpdateDisplaySetRegenState(DISP_DISABLED); + UpdateDisplaySetGear(DISP_REVERSE); + } + velocity_setpoint = -MAX_VELOCITY; + current_setpoint = + percentToFloat(map(accel_pedal_percent, ACCEL_PEDAL_THRESHOLD, + PEDAL_MAX, CURRENT_SP_MIN, CURRENT_SP_MAX)); + cruise_enable = false; + one_pedal_enable = false; } /** * @brief Reverse Drive State Decider. Determines transitions out of * reverse drive state (brake, neutral drive). -*/ -static void ReverseDriveDecider(){ - if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ - state = FSM[BRAKE_STATE]; - } - else if(gear == NEUTRAL_GEAR || gear == FORWARD_GEAR){ - state = FSM[NEUTRAL_DRIVE]; + */ +static void reverseDriveDecider() { + if (brake_pedal_percent >= BRAKE_PEDAL_THRESHOLD) { + state = kFsm[kBrakeState]; + } else if (gear == kNeutralGear || gear == kForwardGear) { + state = kFsm[kNeutralDrive]; } } /** - * @brief Record Velocity State. While pressing the cruise set button, + * @brief Record kVelocity State. While pressing the cruise set button, * the car will record the observed velocity into velocitySetpoint. -*/ -static void RecordVelocityHandler(){ - if(prevState.name != state.name){ - UpdateDisplay_SetCruiseState(DISP_ACTIVE); - UpdateDisplay_SetRegenState(DISP_DISABLED); - UpdateDisplay_SetGear(DISP_FORWARD); + */ +static void recordVelocityHandler() { + if (prev_state.name != state.name) { + UpdateDisplaySetCruiseState(DISP_ACTIVE); + UpdateDisplaySetRegenState(DISP_DISABLED); + UpdateDisplaySetGear(DISP_FORWARD); } // put car in neutral while recording velocity (while button is held) - velocitySetpoint = MAX_VELOCITY; - currentSetpoint = 0; - cruiseVelSetpoint = velocityObserved; + velocity_setpoint = MAX_VELOCITY; + current_setpoint = 0; + cruise_vel_setpoint = velocity_observed; } /** - * @brief Record Velocity State Decider. Determines transitions out of record velocity - * state (brake, neutral drive, one pedal, forward drive, powered cruise). -*/ -static void RecordVelocityDecider(){ - if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ - state = FSM[BRAKE_STATE]; - }else if(gear == NEUTRAL_GEAR || gear == REVERSE_GEAR){ - state = FSM[NEUTRAL_DRIVE]; - }else if(onePedalEnable){ - cruiseEnable = false; - state = FSM[ONEPEDAL]; - }else if(!cruiseEnable){ - state = FSM[FORWARD_DRIVE]; - }else if(cruiseEnable && !cruiseSet){ - state = FSM[POWERED_CRUISE]; + * @brief Record kVelocity State Decider. Determines transitions out of record + * velocity state (brake, neutral drive, one pedal, forward drive, powered + * cruise). + */ +static void recordVelocityDecider() { + if (brake_pedal_percent >= BRAKE_PEDAL_THRESHOLD) { + state = kFsm[kBrakeState]; + } else if (gear == kNeutralGear || gear == kReverseGear) { + state = kFsm[kNeutralDrive]; + } else if (one_pedal_enable) { + cruise_enable = false; + state = kFsm[kOnePedal]; + } else if (!cruise_enable) { + state = kFsm[kForwardDrive]; + } else if (cruise_enable && !cruise_set) { + state = kFsm[kPoweredCruise]; } } /** - * @brief Powered Cruise State. Continue to travel at the recorded velocity as long as - * Observed Velocity <= Velocity Setpoint -*/ -static void PoweredCruiseHandler(){ - velocitySetpoint = cruiseVelSetpoint; - currentSetpoint = 1.0f; + * @brief Powered Cruise State. Continue to travel at the recorded velocity as + * long as Observed kVelocity <= kVelocity Setpoint + */ +static void poweredCruiseHandler() { + velocity_setpoint = cruise_vel_setpoint; + current_setpoint = 1.0F; } /** - * @brief Powered Cruise State Decider. Determines transitions out of powered - * cruise state (brake, neutral drive, one pedal, forward drive, record velocity, - * accelerate cruise, coasting cruise). -*/ -static void PoweredCruiseDecider(){ - if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ - state = FSM[BRAKE_STATE]; - }else if(gear == NEUTRAL_GEAR || gear == REVERSE_GEAR){ - state = FSM[NEUTRAL_DRIVE]; - }else if(onePedalEnable){ - cruiseEnable = false; - state = FSM[ONEPEDAL]; - }else if(!cruiseEnable){ - state = FSM[FORWARD_DRIVE]; - }else if(cruiseSet && velocityObserved >= MIN_CRUISE_VELOCITY){ - state = FSM[RECORD_VELOCITY]; - }else if(accelPedalPercent >= ACCEL_PEDAL_THRESHOLD){ - state = FSM[ACCELERATE_CRUISE]; - }else if(velocityObserved > cruiseVelSetpoint){ - state = FSM[COASTING_CRUISE]; + * @brief Powered Cruise State Decider. Determines transitions out of powered + * cruise state (brake, neutral drive, one pedal, forward drive, record + * velocity, accelerate cruise, coasting cruise). + */ +static void poweredCruiseDecider() { + if (brake_pedal_percent >= BRAKE_PEDAL_THRESHOLD) { + state = kFsm[kBrakeState]; + } else if (gear == kNeutralGear || gear == kReverseGear) { + state = kFsm[kNeutralDrive]; + } else if (one_pedal_enable) { + cruise_enable = false; + state = kFsm[kOnePedal]; + } else if (!cruise_enable) { + state = kFsm[kForwardDrive]; + } else if (cruise_set && velocity_observed >= MIN_CRUISE_VELOCITY) { + state = kFsm[kRecordVelocity]; + } else if (accel_pedal_percent >= ACCEL_PEDAL_THRESHOLD) { + state = kFsm[kAccelerateCruise]; + } else if (velocity_observed > cruise_vel_setpoint) { + state = kFsm[kCoastingCruise]; } } /** - * @brief Coasting Cruise State. We do not want to utilize motor braking - * in cruise control mode due to safety issues. Coast the motor (go into neutral) - * if we want to slow down. -*/ -static void CoastingCruiseHandler(){ - velocitySetpoint = cruiseVelSetpoint; - currentSetpoint = 0; + * @brief Coasting Cruise State. We do not want to utilize motor braking + * in cruise control mode due to safety issues. Coast the motor (go into + * neutral) if we want to slow down. + */ +static void coastingCruiseHandler() { + velocity_setpoint = cruise_vel_setpoint; + current_setpoint = 0; } /** - * @brief Coasting Cruise State Decider. Determines transitions out of coasting - * cruise state (brake, neutral drive, one pedal, forward drive, record velocity, - * accelerate cruise, powered cruise). -*/ -static void CoastingCruiseDecider(){ - if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ - state = FSM[BRAKE_STATE]; - }else if(gear == NEUTRAL_GEAR || gear == REVERSE_GEAR){ - state = FSM[NEUTRAL_DRIVE]; - }else if(onePedalEnable){ - cruiseEnable = false; - state = FSM[ONEPEDAL]; - }else if(!cruiseEnable){ - state = FSM[FORWARD_DRIVE]; - }else if(cruiseSet && velocityObserved >= MIN_CRUISE_VELOCITY){ - state = FSM[RECORD_VELOCITY]; - }else if(accelPedalPercent >= ACCEL_PEDAL_THRESHOLD){ - state = FSM[ACCELERATE_CRUISE]; - }else if(velocityObserved <= cruiseVelSetpoint){ - state = FSM[POWERED_CRUISE]; + * @brief Coasting Cruise State Decider. Determines transitions out of coasting + * cruise state (brake, neutral drive, one pedal, forward drive, record + * velocity, accelerate cruise, powered cruise). + */ +static void coastingCruiseDecider() { + if (brake_pedal_percent >= BRAKE_PEDAL_THRESHOLD) { + state = kFsm[kBrakeState]; + } else if (gear == kNeutralGear || gear == kReverseGear) { + state = kFsm[kNeutralDrive]; + } else if (one_pedal_enable) { + cruise_enable = false; + state = kFsm[kOnePedal]; + } else if (!cruise_enable) { + state = kFsm[kForwardDrive]; + } else if (cruise_set && velocity_observed >= MIN_CRUISE_VELOCITY) { + state = kFsm[kRecordVelocity]; + } else if (accel_pedal_percent >= ACCEL_PEDAL_THRESHOLD) { + state = kFsm[kAccelerateCruise]; + } else if (velocity_observed <= cruise_vel_setpoint) { + state = kFsm[kPoweredCruise]; } } /** - * @brief Accelerate Cruise State. In the event that the driver needs to accelerate in cruise - * mode, we will accelerate to the pedal percentage. Upon release of the accelerator - * pedal, we will return to cruise mode at the previously recorded velocity. -*/ -static void AccelerateCruiseHandler(){ - velocitySetpoint = MAX_VELOCITY; - currentSetpoint = percentToFloat(map(accelPedalPercent, ACCEL_PEDAL_THRESHOLD, PEDAL_MAX, CURRENT_SP_MIN, CURRENT_SP_MAX)); + * @brief Accelerate Cruise State. In the event that the driver needs to + * accelerate in cruise mode, we will accelerate to the pedal percentage. Upon + * release of the accelerator pedal, we will return to cruise mode at the + * previously recorded velocity. + */ +static void accelerateCruiseHandler() { + velocity_setpoint = MAX_VELOCITY; + current_setpoint = + percentToFloat(map(accel_pedal_percent, ACCEL_PEDAL_THRESHOLD, + PEDAL_MAX, CURRENT_SP_MIN, CURRENT_SP_MAX)); } /** - * @brief Accelerate Cruise State Decider. Determines transitions out of accelerate - * cruise state (brake, neutral drive, one pedal, forward drive, record velocity, - * coasting cruise). -*/ -static void AccelerateCruiseDecider(){ - if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ - state = FSM[BRAKE_STATE]; - }else if(gear == NEUTRAL_GEAR || gear == REVERSE_GEAR){ - state = FSM[NEUTRAL_DRIVE]; - }else if(onePedalEnable){ - cruiseEnable = false; - state = FSM[ONEPEDAL]; - }else if(!cruiseEnable){ - state = FSM[FORWARD_DRIVE]; - }else if(cruiseSet && velocityObserved >= MIN_CRUISE_VELOCITY){ - state = FSM[RECORD_VELOCITY]; - }else if(accelPedalPercent < ACCEL_PEDAL_THRESHOLD){ - state = FSM[COASTING_CRUISE]; + * @brief Accelerate Cruise State Decider. Determines transitions out of + * accelerate cruise state (brake, neutral drive, one pedal, forward drive, + * record velocity, coasting cruise). + */ +static void accelerateCruiseDecider() { + if (brake_pedal_percent >= BRAKE_PEDAL_THRESHOLD) { + state = kFsm[kBrakeState]; + } else if (gear == kNeutralGear || gear == kReverseGear) { + state = kFsm[kNeutralDrive]; + } else if (one_pedal_enable) { + cruise_enable = false; + state = kFsm[kOnePedal]; + } else if (!cruise_enable) { + state = kFsm[kForwardDrive]; + } else if (cruise_set && velocity_observed >= MIN_CRUISE_VELOCITY) { + state = kFsm[kRecordVelocity]; + } else if (accel_pedal_percent < ACCEL_PEDAL_THRESHOLD) { + state = kFsm[kCoastingCruise]; } } /** - * @brief One Pedal Drive State. When in one pedal drive, if the accelerator percentage is lower - * than ONEPEDAL_BRAKE_THRESHOLD, the car will utilize motor braking to slow down. If accelerator - * percentage is in the neutral zone, the car will coast. If accelerator percentage is above - * the NEUTRAL_THRESHOLD, the car will accelerate as normal. -*/ -static void OnePedalDriveHandler(){ - if(prevState.name != state.name){ - UpdateDisplay_SetCruiseState(DISP_DISABLED); - UpdateDisplay_SetGear(DISP_FORWARD); - } - if(accelPedalPercent <= ONEPEDAL_BRAKE_THRESHOLD){ + * @brief One Pedal Drive State. When in one pedal drive, if the accelerator + * percentage is lower than ONEPEDAL_BRAKE_THRESHOLD, the car will utilize motor + * braking to slow down. If accelerator percentage is in the neutral zone, the + * car will coast. If accelerator percentage is above the NEUTRAL_THRESHOLD, the + * car will accelerate as normal. + */ +static void onePedalDriveHandler() { + if (prev_state.name != state.name) { + UpdateDisplaySetCruiseState(DISP_DISABLED); + UpdateDisplaySetGear(DISP_FORWARD); + } + if (accel_pedal_percent <= ONEPEDAL_BRAKE_THRESHOLD) { // Regen brake: Map 0 -> brake to 100 -> 0 - velocitySetpoint = 0; - currentSetpoint = percentToFloat(map(accelPedalPercent, PEDAL_MIN, ONEPEDAL_BRAKE_THRESHOLD, CURRENT_SP_MAX, CURRENT_SP_MIN)); - Minions_Write(BRAKELIGHT, true); - UpdateDisplay_SetRegenState(DISP_ACTIVE); - }else if(ONEPEDAL_BRAKE_THRESHOLD < accelPedalPercent && accelPedalPercent <= ONEPEDAL_NEUTRAL_THRESHOLD){ + velocity_setpoint = 0; + current_setpoint = percentToFloat(map(accel_pedal_percent, PEDAL_MIN, + ONEPEDAL_BRAKE_THRESHOLD, + CURRENT_SP_MAX, CURRENT_SP_MIN)); + MinionsWrite(kBrakeLight, true); + UpdateDisplaySetRegenState(DISP_ACTIVE); + } else if (ONEPEDAL_BRAKE_THRESHOLD < accel_pedal_percent && + accel_pedal_percent <= ONEPEDAL_NEUTRAL_THRESHOLD) { // Neutral: coast - velocitySetpoint = MAX_VELOCITY; - currentSetpoint = 0; - Minions_Write(BRAKELIGHT, false); - UpdateDisplay_SetRegenState(DISP_ENABLED); - }else if(ONEPEDAL_NEUTRAL_THRESHOLD < accelPedalPercent){ + velocity_setpoint = MAX_VELOCITY; + current_setpoint = 0; + MinionsWrite(kBrakeLight, false); + UpdateDisplaySetRegenState(DISP_ENABLED); + } else if (ONEPEDAL_NEUTRAL_THRESHOLD < accel_pedal_percent) { // Accelerate: Map neutral -> 100 to 0 -> 100 - velocitySetpoint = MAX_VELOCITY; - currentSetpoint = percentToFloat(map(accelPedalPercent, ONEPEDAL_NEUTRAL_THRESHOLD, PEDAL_MAX, CURRENT_SP_MIN, CURRENT_SP_MAX)); - Minions_Write(BRAKELIGHT, false); - UpdateDisplay_SetRegenState(DISP_ENABLED); + velocity_setpoint = MAX_VELOCITY; + current_setpoint = + percentToFloat(map(accel_pedal_percent, ONEPEDAL_NEUTRAL_THRESHOLD, + PEDAL_MAX, CURRENT_SP_MIN, CURRENT_SP_MAX)); + MinionsWrite(kBrakeLight, false); + UpdateDisplaySetRegenState(DISP_ENABLED); } } /** - * @brief One Pedal Drive State Decider. Determines transitions out of one pedal + * @brief One Pedal Drive State Decider. Determines transitions out of one pedal * drive state (brake, record velocity, neutral drive). -*/ -static void OnePedalDriveDecider(){ - if(brakePedalPercent >= BRAKE_PEDAL_THRESHOLD){ - state = FSM[BRAKE_STATE]; - }else if(cruiseSet && cruiseEnable && velocityObserved >= MIN_CRUISE_VELOCITY){ - state = FSM[RECORD_VELOCITY]; - Minions_Write(BRAKELIGHT, false); - }else if(gear == NEUTRAL_GEAR || gear == REVERSE_GEAR){ - state = FSM[NEUTRAL_DRIVE]; - Minions_Write(BRAKELIGHT, false); + */ +static void onePedalDriveDecider() { + if (brake_pedal_percent >= BRAKE_PEDAL_THRESHOLD) { + state = kFsm[kBrakeState]; + } else if (cruise_set && cruise_enable && + velocity_observed >= MIN_CRUISE_VELOCITY) { + state = kFsm[kRecordVelocity]; + MinionsWrite(kBrakeLight, false); + } else if (gear == kNeutralGear || gear == kReverseGear) { + state = kFsm[kNeutralDrive]; + MinionsWrite(kBrakeLight, false); } } /** - * @brief Brake State. When brake pedal is pressed, physical brakes will be active. - * Put motor in neutral to prevent motor braking while physical brakes are engaged. - * Additionally, disable all cruise control and one pedal functionality. -*/ -static void BrakeHandler(){ - if(prevState.name != state.name){ - UpdateDisplay_SetCruiseState(DISP_DISABLED); - UpdateDisplay_SetRegenState(DISP_DISABLED); - UpdateDisplay_SetGear(DISP_FORWARD); - } - velocitySetpoint = MAX_VELOCITY; - currentSetpoint = 0; - cruiseEnable = false; - onePedalEnable = false; - Minions_Write(BRAKELIGHT, true); + * @brief Brake State. When brake pedal is pressed, physical brakes will be + * active. Put motor in neutral to prevent motor braking while physical brakes + * are engaged. Additionally, disable all cruise control and one pedal + * functionality. + */ +static void brakeHandler() { + if (prev_state.name != state.name) { + UpdateDisplaySetCruiseState(DISP_DISABLED); + UpdateDisplaySetRegenState(DISP_DISABLED); + UpdateDisplaySetGear(DISP_FORWARD); + } + velocity_setpoint = MAX_VELOCITY; + current_setpoint = 0; + cruise_enable = false; + one_pedal_enable = false; + MinionsWrite(kBrakeLight, true); } /** - * @brief Brake State Decider. Determines transitions out of brake state (forward drive, - * neutral drive). -*/ -static void BrakeDecider(){ - if(brakePedalPercent < BRAKE_PEDAL_THRESHOLD){ - if(gear == FORWARD_GEAR) state = FSM[FORWARD_DRIVE]; - else if(gear == NEUTRAL_GEAR || gear == REVERSE_GEAR) state = FSM[NEUTRAL_DRIVE]; - Minions_Write(BRAKELIGHT, false); + * @brief Brake State Decider. Determines transitions out of brake state + * (forward drive, neutral drive). + */ +static void brakeDecider() { + if (brake_pedal_percent < BRAKE_PEDAL_THRESHOLD) { + if (gear == kForwardGear) { + state = kFsm[kForwardDrive]; + } else if (gear == kNeutralGear || gear == kReverseGear) { + state = kFsm[kNeutralDrive]; + } + MinionsWrite(kBrakeLight, false); } } @@ -639,57 +699,58 @@ static void BrakeDecider(){ /** * @brief Follows the FSM to update the velocity of the car -*/ -void Task_SendTritium(void *p_arg){ - OS_ERR err; + */ +void TaskSendTritium(void* p_arg) { + OS_ERR err = 0; // Initialize current state to FORWARD_DRIVE - state = FSM[NEUTRAL_DRIVE]; - prevState = FSM[NEUTRAL_DRIVE]; - - #ifndef SENDTRITIUM_EXPOSE_VARS - CANDATA_t driveCmd = { - .ID=MOTOR_DRIVE, - .idx=0, - .data={0.0f, 0.0f}, + state = kFsm[kNeutralDrive]; + prev_state = kFsm[kNeutralDrive]; + +#ifndef SENDTRITIUM_EXPOSE_VARS + CanData drive_cmd = { + .id = kMotorDrive, + .idx = 0, + .data = {0}, }; - #endif +#endif - while(1){ - prevState = state; + while (1) { + prev_state = state; - state.stateHandler(); // do what the current state does - #ifndef SENDTRITIUM_EXPOSE_VARS - readInputs(); // read inputs from the system - UpdateDisplay_SetAccel(accelPedalPercent); - #endif - state.stateDecider(); // decide what the next state is + state.stateHandler(); // do what the current state does +#ifndef SENDTRITIUM_EXPOSE_VARS + readInputs(); // read inputs from the system + UpdateDisplaySetAccel(accel_pedal_percent); +#endif + state.stateDecider(); // decide what the next state is - // Disable velocity controlled mode by always overwriting velocity to the maximum - // in the appropriate direction. - velocitySetpoint = (velocitySetpoint>0)?MAX_VELOCITY:-MAX_VELOCITY; + // Disable velocity controlled mode by always overwriting velocity to + // the maximum in the appropriate direction. + velocity_setpoint = + (velocity_setpoint > 0) ? MAX_VELOCITY : -MAX_VELOCITY; - // Drive - #ifdef SENDTRITIUM_PRINT_MES +// Drive +#ifdef SENDTRITIUM_PRINT_MES dumpInfo(); - #endif - #ifndef SENDTRITIUM_EXPOSE_VARS - if(MOTOR_MSG_COUNTER_THRESHOLD == motorMsgCounter){ - memcpy(&driveCmd.data[4], ¤tSetpoint, sizeof(float)); - memcpy(&driveCmd.data[0], &velocitySetpoint, sizeof(float)); - CANbus_Send(driveCmd, CAN_NON_BLOCKING, MOTORCAN); - motorMsgCounter = 0; - }else{ - motorMsgCounter++; +#endif +#ifndef SENDTRITIUM_EXPOSE_VARS + if (MOTOR_MSG_COUNTER_THRESHOLD == motor_msg_counter) { + memcpy(&drive_cmd.data[4], ¤t_setpoint, sizeof(float)); + memcpy(&drive_cmd.data[0], &velocity_setpoint, sizeof(float)); + CanBusSend(drive_cmd, CAN_NON_BLOCKING, MOTORCAN); + motor_msg_counter = 0; + } else { + motor_msg_counter++; } - #endif +#endif - putControlModeCAN(); + putControlModeCAN(); // Delay of MOTOR_MSG_PERIOD ms OSTimeDlyHMSM(0, 0, 0, MOTOR_MSG_PERIOD, OS_OPT_TIME_HMSM_STRICT, &err); - if (err != OS_ERR_NONE){ - assertOSError(err); + if (err != OS_ERR_NONE) { + ASSERT_OS_ERROR(err); } } } diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index af6382e1d..383967958 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -1,171 +1,186 @@ /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file Tasks.c - * @brief - * + * @brief + * */ #include "Tasks.h" -#include "os.h" -#include "CANbus.h" + +#include "CanBus.h" #include "Contactors.h" #include "Display.h" #include "Minions.h" #include "Pedals.h" +#include "ReadCarCan.h" #include "ReadTritium.h" -#include "ReadCarCAN.h" #include "UpdateDisplay.h" - +#include "os.h" /** * TCBs */ -OS_TCB Init_TCB; -OS_TCB SendTritium_TCB; -OS_TCB ReadCarCAN_TCB; -OS_TCB UpdateDisplay_TCB; -OS_TCB ReadTritium_TCB; -OS_TCB SendCarCAN_TCB; -OS_TCB DebugDump_TCB; -OS_TCB CommandLine_TCB; +OS_TCB init_tcb; +OS_TCB send_tritium_tcb; +OS_TCB read_car_can_tcb; +OS_TCB update_display_tcb; +OS_TCB read_tritium_tcb; +OS_TCB send_car_can_tcb; +OS_TCB debug_dump_tcb; +OS_TCB command_line_tcb; -task_trace_t PrevTasks; +TaskTrace prev_tasks; /** * Stacks */ -CPU_STK Init_Stk[TASK_INIT_STACK_SIZE]; -CPU_STK SendTritium_Stk[TASK_SEND_TRITIUM_STACK_SIZE]; -CPU_STK ReadCarCAN_Stk[TASK_READ_CAR_CAN_STACK_SIZE]; -CPU_STK UpdateDisplay_Stk[TASK_UPDATE_DISPLAY_STACK_SIZE]; -CPU_STK ReadTritium_Stk[TASK_READ_TRITIUM_STACK_SIZE]; -CPU_STK SendCarCAN_Stk[TASK_SEND_CAR_CAN_STACK_SIZE]; -CPU_STK DebugDump_Stk[TASK_DEBUG_DUMP_STACK_SIZE]; -CPU_STK CommandLine_Stk[TASK_COMMAND_LINE_STACK_SIZE]; - -// Variables to store error codes, stored and cleared in task error assert functions -error_code_t Error_ReadCarCAN = /*READCARCAN_ERR_NONE*/ 0; // TODO: change this back to the error -error_code_t Error_ReadTritium = T_NONE; // Initialized to no error -error_code_t Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; - -extern const pinInfo_t PININFO_LUT[]; // For GPIO writes. Externed from Minions Driver C file. +CPU_STK init_stk[TASK_INIT_STACK_SIZE]; +CPU_STK send_tritium_stk[TASK_SEND_TRITIUM_STACK_SIZE]; +CPU_STK read_car_can_stk[TASK_READ_CAR_CAN_STACK_SIZE]; +CPU_STK update_display_stk[TASK_UPDATE_DISPLAY_STACK_SIZE]; +CPU_STK read_tritium_stk[TASK_READ_TRITIUM_STACK_SIZE]; +CPU_STK send_car_can_stk[TASK_SEND_CAR_CAN_STACK_SIZE]; +CPU_STK debug_dump_stk[TASK_DEBUG_DUMP_STACK_SIZE]; +CPU_STK command_line_stk[TASK_COMMAND_LINE_STACK_SIZE]; + +// Variables to store error codes, stored and cleared in task error assert +// functions +ErrorCode error_read_car_can = 0; // TODO: change this back to the error +ErrorCode error_read_tritium = kNone; // Initialized to no error +ErrorCode error_update_display = kUpdateDisplayErrNone; + +extern const PinInfo + kPininfoLut[]; // For GPIO writes. Externed from Minions Driver C file. /** * Error assertion-related functions -*/ - -void _assertOSError(OS_ERR err) -{ - if (err != OS_ERR_NONE) - { - EmergencyContactorOpen(); // Turn off contactors and turn on the brakelight to indicate an emergency - Display_Error(err); // Display the location and error code - while(1){;} //nonrecoverable + */ +void AssertOsError(volatile OS_ERR err) { + if (err != OS_ERR_NONE) { + EmergencyContactorOpen(); // Turn off contactors and turn on the + // brakelight to indicate an emergency + DisplayFault(err); // Display the location and error code + printf("%d\n\r", err); + while (1) {} // nonrecoverable } } /** - * @brief Assert a task error by locking the scheduler (if necessary), displaying a fault screen, - * and jumping to the error's specified callback function. - * Called by task-specific error-assertion functions that are also responsible for setting the error variable. + * @brief Assert a task error by locking the scheduler (if necessary), + * displaying a fault screen, and jumping to the error's specified callback + * function. Called by task-specific error-assertion functions that are also + * responsible for setting the error variable. * @param errorCode the enum for the specific error that happened - * @param errorCallback a callback function to a handler for that specific error, - * @param lockSched whether or not to lock the scheduler to ensure the error is handled immediately. Only applicable for recoverable errors- nonrecoverable errors will always lock - * @param nonrecoverable whether or not to kill the motor, display the fault screen, and enter an infinite while loop -*/ -void throwTaskError(error_code_t errorCode, callback_t errorCallback, error_scheduler_lock_opt_t lockSched, error_recov_opt_t nonrecoverable) { - OS_ERR err; - - if (errorCode == 0) { // Exit if there is no error + * @param errorCallback a callback function to a handler for that specific + * error, + * @param lockSched whether or not to lock the scheduler to ensure the error is + * handled immediately. Only applicable for recoverable errors- nonrecoverable + * errors will always lock + * @param nonrecoverable whether or not to kill the motor, display the fault + * screen, and enter an infinite while loop + */ +void ThrowTaskError(ErrorCode error_code, Callback error_callback, + ErrorSchedulerLockOpt lock_sched, + ErrorRecovOpt nonrecoverable) { + OS_ERR err = 0; + + if (error_code == 0) { // Exit if there is no error return; } - if (lockSched == OPT_LOCK_SCHED || nonrecoverable == OPT_NONRECOV) { // Prevent other tasks from interrupting the handling of important (includes all nonrecoverable) errors + if (lock_sched == kOptLockSched || + nonrecoverable == + kOptNonrecov) { // Prevent other tasks from interrupting the + // handling of important (includes all + // nonrecoverable) errors OSSchedLock(&err); - assertOSError(err); + ASSERT_OS_ERROR(err); } - if (nonrecoverable == OPT_NONRECOV) { + if (nonrecoverable == kOptNonrecov) { EmergencyContactorOpen(); - Display_Error(errorCode); // Needs to happen before callback so that tasks can change the screen + DisplayFault(error_code); // Needs to happen before callback so that + // tasks can change the screen // (ex: readCarCAN and evac screen for BPS trip) - UpdateDisplay_ClearQueue(); // Clear message queue to ensure no other commands overwrite the error screen + printf("%d\n\r", error_code); + UpdateDisplayClearQueue(); // Clear message queue to ensure no other + // commands overwrite the error screen } - - if (errorCallback != NULL) { - errorCallback(); // Run a handler for this error that was specified in another task file + if (error_callback != NULL) { + error_callback(); // Run a handler for this error that was specified in + // another task file } - - - if (nonrecoverable == OPT_NONRECOV) { // Enter an infinite while loop - while(1) { - - #if DEBUG == 1 - // Print the error that caused this fault - // printf("\n\rCurrent Error Code: 0x%04x\n\r", errorCode); - - // // Print the errors for each applications with error data - // printf("\n\rAll application errors:\n\r"); - // printf("Error_ReadCarCAN: 0x%04x\n\r", Error_ReadCarCAN); - // printf("Error_ReadTritium: 0x%04x\n\r", Error_ReadTritium); - // printf("Error_UpdateDisplay: 0x%04x\n\r", Error_UpdateDisplay); - - // // Delay so that we're not constantly printing - // for (int i = 0; i < 9999999; i++) { - // } - #endif - - } + + if (nonrecoverable == kOptNonrecov) { // Enter an infinite while loop + while (1) {} } - if (lockSched == OPT_LOCK_SCHED) { // Only happens on recoverable errors - OSSchedUnlock(&err); - // Don't err out if scheduler is still locked because of a timer callback - if (err != OS_ERR_SCHED_LOCKED || OSSchedLockNestingCtr > 1) { // But we don't plan to lock more than one level deep - assertOSError(err); + if (lock_sched == kOptLockSched) { // Only happens on recoverable errors + OSSchedUnlock(&err); + // Don't err out if scheduler is still locked because of a timer + // callback + if (err != OS_ERR_SCHED_LOCKED || + OSSchedLockNestingCtr > + 1) { // But we don't plan to lock more than one level deep + ASSERT_OS_ERROR(err); } - } } /** - * @brief For use in error handling: opens array and motor precharge bypass contactor - * and turns on additional brakelight to signal that a critical error happened. -*/ + * @brief For use in error handling: opens array and motor precharge bypass + * contactor and turns on additional brakelight to signal that a critical error + * happened. + */ void EmergencyContactorOpen() { // Array motor kill - BSP_GPIO_Write_Pin(CONTACTORS_PORT, MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN, OFF); - BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_PRECHARGE_BYPASS_PIN, OFF); + BspGpioWritePin(CONTACTORS_PORT, MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN, + OFF); + BspGpioWritePin(CONTACTORS_PORT, ARRAY_PRECHARGE_BYPASS_PIN, OFF); // Turn additional brakelight on to indicate critical error - BSP_GPIO_Write_Pin(PININFO_LUT[BRAKELIGHT].port, PININFO_LUT[BRAKELIGHT].pinMask, true); + BspGpioWritePin(kPininfoLut[kBrakeLight].port, + kPininfoLut[kBrakeLight].pin_mask, true); } /** * @brief Hook that's called every context switch - * - * This function will append the task being switched out to the task trace if and only if: + * + * This function will append the task being switched out to the task trace if + * and only if: * 1. It's not a task created automatically by the RTOS - * 2. It's not the previously recorded task (a long running task interrupted by the - * tick task will only show up once) - * This function will overwrite tasks that have been in the trace for a while, keeping only - * the 8 most recent tasks + * 2. It's not the previously recorded task (a long running task + * interrupted by the tick task will only show up once) This function will + * overwrite tasks that have been in the trace for a while, keeping only the 8 + * most recent tasks */ -void App_OS_TaskSwHook(void) { +void AppOsTaskSwHook(void) { OS_TCB *cur = OSTCBCurPtr; - uint32_t idx = PrevTasks.index; - if (cur == &OSTickTaskTCB) return; // Ignore the tick task - if (cur == &OSIdleTaskTCB) return; // Ignore the idle task - if (cur == &OSTmrTaskTCB ) return; // Ignore the timer task - if (cur == &OSStatTaskTCB) return; // Ignore the stat task - if (cur == PrevTasks.tasks[idx]) return; // Don't record the same task again - if (++idx == TASK_TRACE_LENGTH) idx = 0; - PrevTasks.tasks[idx] = cur; - PrevTasks.index = idx; + uint32_t idx = prev_tasks.index; + if (cur == &OSTickTaskTCB) { + return; // Ignore the tick task + } + if (cur == &OSIdleTaskTCB) { + return; // Ignore the idle task + } + if (cur == &OSTmrTaskTCB) { + return; // Ignore the timer task + } + if (cur == &OSStatTaskTCB) { + return; // Ignore the stat task + } + if (cur == prev_tasks.tasks[idx]) { + return; // Don't record the same task again + } + if (++idx == TASK_TRACE_LENGTH) { + idx = 0; + } + prev_tasks.tasks[idx] = cur; + prev_tasks.index = idx; } -void TaskSwHook_Init(void) { - PrevTasks.index = TASK_TRACE_LENGTH - 1; // List starts out empty - OS_AppTaskSwHookPtr = App_OS_TaskSwHook; +void TaskSwHookInit(void) { + prev_tasks.index = TASK_TRACE_LENGTH - 1; // List starts out empty + OS_AppTaskSwHookPtr = AppOsTaskSwHook; } diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 7da45f42b..534cf0bac 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -2,92 +2,94 @@ * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file UpdateDisplay.c * @brief Function implementations for the display application. - * + * * This contains functions relevant to modifying states of specific - * components on our HMI design. The HMI has the ability to indicate + * components on our HMI design. The HMI has the ability to indicate * relevant information about system status to the driver. - * + * */ #include "UpdateDisplay.h" -#include "Minions.h" + #include +#include "Contactors.h" +#include "Display.h" +#include "Minions.h" +#include "Tasks.h" +#include "common.h" +#include "os.h" + +#define NUM_COMP_STRINGS 15 + /** * Creates queue for display commands. */ #define DISP_Q_SIZE 10 -#define FIFO_TYPE DisplayCmd_t +#define FIFO_TYPE DisplayCmd #define FIFO_SIZE DISP_Q_SIZE -#define FIFO_NAME disp_fifo +#define FIFO_NAME DispFifo #include "fifo.h" // For fault handling -#define RESTART_THRESHOLD 3 // number of times to reset before displaying the fault screen - -disp_fifo_t msg_queue; +#define RESTART_THRESHOLD \ + 3 // number of times to reset before displaying the fault screen -static OS_SEM DisplayQ_Sem4; // counting semaphore for queue message availability -static OS_MUTEX DisplayQ_Mutex; // mutex to ensure thread safety when writing/reading to queue +DispFifo msg_queue; +static OS_SEM + display_q_sem4; // counting semaphore for queue message availability +static OS_MUTEX display_q_mutex; // mutex to ensure thread safety when + // writing/reading to queue /** * Function prototypes -*/ + */ // check for and assert errors in UpdateDisplay -static void assertUpdateDisplayError(UpdateDisplayError_t err); - +static void assertUpdateDisplayError(UpdateDisplayError err); /** * Enum and corresponding array for easy component selection. */ -typedef enum{ - // Boolean components - ARRAY=0, - MOTOR, - // Non-boolean components - VELOCITY, - ACCEL_METER, - SOC, - SUPP_BATT, - CRUISE_ST, - REGEN_ST, - GEAR, - // Fault code components - OS_CODE, - FAULT_CODE -} Component_t; - -const char* compStrings[15]= { - // Boolean components - "arr", - "mot", - // Non-boolean components - "vel", - "accel", - "soc", - "supp", - "cruiseSt", - "rbsSt", - "gear", - // Fault code components - "oserr", - "faulterr" -}; - -UpdateDisplayError_t UpdateDisplay_Init(){ - OS_ERR err; - disp_fifo_renew(&msg_queue); - OSMutexCreate(&DisplayQ_Mutex, "Display mutex", &err); - assertOSError(err); - OSSemCreate(&DisplayQ_Sem4, "Display sem4", 0, &err); - assertOSError(err); - - UpdateDisplayError_t ret = UpdateDisplay_SetPage(INFO); - OSTimeDlyHMSM(0, 0, 0, 300, OS_OPT_TIME_HMSM_STRICT, &err); // Wait >215ms so errors will show on the display - assertOSError(err); - return ret; +typedef enum { + // Boolean components + kArray = 0, + kMotor, + // Non-boolean components + kVelocity, + kAccelMeter, + kSoc, + kSuppBatt, + kCruiseSt, + kRegenSt, + kGear, + // Fault code components + kOsCode, + kFaultCode +} Component; + +const char* comp_strings[NUM_COMP_STRINGS] = { + // Boolean components + "arr", "mot", + // Non-boolean components + "vel", "accel", "soc", "supp", "cruiseSt", "rbsSt", "gear", + // Fault code components + "oserr", "faulterr"}; + +UpdateDisplayError UpdateDisplayInit() { + OS_ERR err = 0; + DispFifoRenew(&msg_queue); + OSMutexCreate(&display_q_mutex, "Display mutex", &err); + ASSERT_OS_ERROR(err); + OSSemCreate(&display_q_sem4, "Display sem4", 0, &err); + ASSERT_OS_ERROR(err); + + UpdateDisplayError ret = UpdateDisplaySetPage(kInfo); + OSTimeDlyHMSM(0, 0, 0, 300, OS_OPT_TIME_HMSM_STRICT, // NOLINT + &err); // Wait >215ms so errors will show on the display + ASSERT_OS_ERROR(err); + return ret; } /** @@ -95,84 +97,80 @@ UpdateDisplayError_t UpdateDisplay_Init(){ * it to the display driver. Pends on semaphore and mutex to ensure that: * 1) queue has messages to send (signaled by semaphore) * 2) queue is not currently being written to by a separate thread (mutex) - * @returns UpdateDisplayError_t + * @returns UpdateDisplayError */ -static UpdateDisplayError_t UpdateDisplay_PopNext(){ - DisplayCmd_t cmd; - - OS_ERR err; - CPU_TS ticks; - - OSSemPend(&DisplayQ_Sem4, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); - assertOSError(err); - - OSMutexPend(&DisplayQ_Mutex, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); - assertOSError(err); - - bool result = disp_fifo_get(&msg_queue, &cmd); - OSMutexPost(&DisplayQ_Mutex, OS_OPT_POST_ALL, &err); - assertOSError(err); - - if(!result){ - assertUpdateDisplayError(UPDATEDISPLAY_ERR_FIFO_POP); - return UPDATEDISPLAY_ERR_FIFO_POP; - } - - // Assert a display driver error code if the send fails, else assert that there's no error - assertUpdateDisplayError(Display_Send(cmd) ? UPDATEDISPLAY_ERR_DRIVER : UPDATEDISPLAY_ERR_NONE); - return UPDATEDISPLAY_ERR_NONE; +static UpdateDisplayError updateDisplayPopNext() { + DisplayCmd cmd; + + OS_ERR err = 0; + CPU_TS ticks = 0; + + OSSemPend(&display_q_sem4, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); + ASSERT_OS_ERROR(err); + + OSMutexPend(&display_q_mutex, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); + ASSERT_OS_ERROR(err); + + bool result = DispFifoGet(&msg_queue, &cmd); + OSMutexPost(&display_q_mutex, OS_OPT_POST_ALL, &err); + ASSERT_OS_ERROR(err); + + if (!result) { + assertUpdateDisplayError(kUpdateDisplayErrFifoPop); + return kUpdateDisplayErrFifoPop; + } + + // Assert a display driver error code if the send fails, else assert that + // there's no error + assertUpdateDisplayError(DisplaySend(cmd) ? kUpdateDisplayErrDriver + : kUpdateDisplayErrNone); + return kUpdateDisplayErrNone; } /** * @brief Puts a new display message in the queue. Pends on mutex to ensure - * threadsafe memory access and signals semaphore upon successful fifo_put. - * @returns UpdateDisplayError_t + * threadsafe memory access and signals semaphore upon successful fifoPut. + * @returns UpdateDisplayError */ -static UpdateDisplayError_t UpdateDisplay_PutNext(DisplayCmd_t cmd){ - CPU_TS ticks; - OS_ERR err; - - OSMutexPend(&DisplayQ_Mutex, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); - assertOSError(err); - - bool success = disp_fifo_put(&msg_queue, cmd); - - OSMutexPost(&DisplayQ_Mutex, OS_OPT_POST_ALL, &err); - assertOSError(err); - - if(success){ - OSSemPost(&DisplayQ_Sem4, OS_OPT_POST_ALL, &err); - assertOSError(err); - } - else{ - assertUpdateDisplayError(UPDATEDISPLAY_ERR_FIFO_PUT); - return UPDATEDISPLAY_ERR_FIFO_PUT; - } - - return UPDATEDISPLAY_ERR_NONE; +static UpdateDisplayError updateDisplayPutNext(DisplayCmd cmd) { + CPU_TS ticks = 0; + OS_ERR err = 0; + + OSMutexPend(&display_q_mutex, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); + ASSERT_OS_ERROR(err); + + bool success = DispFifoPut(&msg_queue, cmd); + + OSMutexPost(&display_q_mutex, OS_OPT_POST_ALL, &err); + ASSERT_OS_ERROR(err); + + if (success) { + OSSemPost(&display_q_sem4, OS_OPT_POST_ALL, &err); + ASSERT_OS_ERROR(err); + } else { + assertUpdateDisplayError(kUpdateDisplayErrFifoPut); + return kUpdateDisplayErrNone; + } + + return kUpdateDisplayErrNone; } /** * @brief Several elements on the display do not update their * state until a touch/click event is triggered. This includes the * blinkers, gear selector, cruise control and regen braking indicator. - * @returns UpdateDisplayError_t + * @returns UpdateDisplayError */ -static UpdateDisplayError_t UpdateDisplay_Refresh(){ - DisplayCmd_t refreshCmd = { - .compOrCmd = "click", - .attr = NULL, - .op = NULL, - .numArgs = 2, - .argTypes = {INT_ARG,INT_ARG}, - { - {.num=0}, - {.num=1} - } - }; - - UpdateDisplayError_t ret = UpdateDisplay_PutNext(refreshCmd); - return ret; +static UpdateDisplayError updateDisplayRefresh() { + DisplayCmd refresh_cmd = {.comp_or_cmd = "click", + .attr = NULL, + .op = NULL, + .num_args = 2, + .arg_types = {kIntArg, kIntArg}, + {{.num = 0}, {.num = 1}}}; + + UpdateDisplayError ret = updateDisplayPutNext(refresh_cmd); + return ret; } /** @@ -180,186 +178,187 @@ static UpdateDisplayError_t UpdateDisplay_Refresh(){ * Differentiates between timers, variables, and components to assign values. * @param comp component to set value of * @param val value - * @return UpdateDisplayError_t + * @return UpdateDisplayError */ -static UpdateDisplayError_t UpdateDisplay_SetComponent(Component_t comp, uint32_t val){ - UpdateDisplayError_t ret = UPDATEDISPLAY_ERR_NONE; - - // For components that are on/off - if(comp <= MOTOR && val <= 1){ - DisplayCmd_t visCmd = { - .compOrCmd = "vis", - .attr = NULL, - .op = NULL, - .numArgs = 2, - .argTypes = {STR_ARG,INT_ARG}, - { - {.str=(char*)compStrings[comp]}, - {.num=val} - } - }; - - ret = UpdateDisplay_PutNext(visCmd); - return ret; - } - // For components that have a non-boolean value - else if(comp > MOTOR){ - DisplayCmd_t setCmd = { - .compOrCmd = (char*)compStrings[comp], - .attr = "val", - .op = "=", - .numArgs = 1, - .argTypes = {INT_ARG}, - { - {.num=val} - } - }; - - ret = UpdateDisplay_PutNext(setCmd); - return ret; - } - else{ - assertUpdateDisplayError(UPDATEDISPLAY_ERR_PARSE_COMP); - return UPDATEDISPLAY_ERR_PARSE_COMP; - } - return UPDATEDISPLAY_ERR_NONE; +static UpdateDisplayError updateDisplaySetComponent(Component comp, + uint32_t val) { + UpdateDisplayError ret = kUpdateDisplayErrNone; + + // For components that are on/off + if (comp <= kMotor && val <= 1) { + DisplayCmd vis_cmd = { + .comp_or_cmd = "vis", + .attr = NULL, + .op = NULL, + .num_args = 2, + .arg_types = {kStrArg, kIntArg}, + {{.str = (char*)comp_strings[comp]}, {.num = val}}}; + + ret = updateDisplayPutNext(vis_cmd); + return ret; + } + // For components that have a non-boolean value + if (comp > kMotor) { + DisplayCmd set_cmd = {.comp_or_cmd = (char*)comp_strings[comp], + .attr = "val", + .op = "=", + .num_args = 1, + .arg_types = {kIntArg}, + {{.num = val}}}; + + ret = updateDisplayPutNext(set_cmd); + return ret; + } + assertUpdateDisplayError(kUpdateDisplayErrParseComp); + return kUpdateDisplayErrParseComp; + + return kUpdateDisplayErrNone; } -UpdateDisplayError_t UpdateDisplay_SetPage(Page_t page){ - DisplayCmd_t pgCmd = { - .compOrCmd = "page", - .attr = NULL, - .op = NULL, - .numArgs = 1, - .argTypes = {INT_ARG}, - { - {.num=page} - } - }; - - UpdateDisplayError_t ret = UpdateDisplay_PutNext(pgCmd); - return ret; +UpdateDisplayError UpdateDisplaySetPage(Page page) { + DisplayCmd pg_cmd = {.comp_or_cmd = "page", + .attr = NULL, + .op = NULL, + .num_args = 1, + .arg_types = {kIntArg}, + {{.num = page}}}; + + UpdateDisplayError ret = updateDisplayPutNext(pg_cmd); + return ret; } /* WRAPPERS */ -UpdateDisplayError_t UpdateDisplay_SetSOC(uint8_t percent){ // Integer percentage from 0-100 +UpdateDisplayError UpdateDisplaySetSoc( + uint8_t percent) { // Integer percentage from 0-100 - UpdateDisplayError_t ret = UpdateDisplay_SetComponent(SOC, percent); - if(ret != UPDATEDISPLAY_ERR_NONE) return ret; + UpdateDisplayError ret = updateDisplaySetComponent(kSoc, percent); + if (ret != kUpdateDisplayErrNone) { + return ret; + } - ret = UpdateDisplay_Refresh(); - return ret; + ret = updateDisplayRefresh(); + return ret; } -UpdateDisplayError_t UpdateDisplay_SetSBPV(uint32_t mv){ - - UpdateDisplayError_t ret = UpdateDisplay_SetComponent(SUPP_BATT, mv/100); - if(ret != UPDATEDISPLAY_ERR_NONE) return ret; +UpdateDisplayError UpdateDisplaySetSbpv(uint32_t mv) { + UpdateDisplayError ret = updateDisplaySetComponent(kSuppBatt, mv / 100); + if (ret != kUpdateDisplayErrNone) { + return ret; + } - ret = UpdateDisplay_Refresh(); - return ret; + ret = updateDisplayRefresh(); + return ret; } -UpdateDisplayError_t UpdateDisplay_SetVelocity(uint32_t mphTenths){ - - UpdateDisplayError_t ret = UpdateDisplay_SetComponent(VELOCITY, mphTenths); - return ret; +UpdateDisplayError UpdateDisplaySetVelocity(uint32_t mph_tenths) { + UpdateDisplayError ret = updateDisplaySetComponent(kVelocity, mph_tenths); + return ret; } -UpdateDisplayError_t UpdateDisplay_SetAccel(uint8_t percent){ - - UpdateDisplayError_t ret = UpdateDisplay_SetComponent(ACCEL_METER, percent); - return ret; +UpdateDisplayError UpdateDisplaySetAccel(uint8_t percent) { + UpdateDisplayError ret = updateDisplaySetComponent(kAccelMeter, percent); + return ret; } -UpdateDisplayError_t UpdateDisplay_SetArray(bool state){ - - UpdateDisplayError_t ret = UpdateDisplay_SetComponent(ARRAY, (state)?1:0); - return ret; +UpdateDisplayError UpdateDisplaySetArray(bool state) { + UpdateDisplayError ret = updateDisplaySetComponent(kArray, (state) ? 1 : 0); + return ret; } -UpdateDisplayError_t UpdateDisplay_SetMotor(bool state){ - - UpdateDisplayError_t ret = UpdateDisplay_SetComponent(MOTOR, (state)?1:0); - return ret; +UpdateDisplayError UpdateDisplaySetMotor(bool state) { + UpdateDisplayError ret = updateDisplaySetComponent(kMotor, (state) ? 1 : 0); + return ret; } -UpdateDisplayError_t UpdateDisplay_SetGear(TriState_t gear){ - - UpdateDisplayError_t ret = UpdateDisplay_SetComponent(GEAR, (uint32_t)gear); - if(ret != UPDATEDISPLAY_ERR_NONE) return ret; +UpdateDisplayError UpdateDisplaySetGear(TriState gear) { + UpdateDisplayError ret = updateDisplaySetComponent(kGear, (uint32_t)gear); + if (ret != kUpdateDisplayErrNone) { + return ret; + } - ret = UpdateDisplay_Refresh(); - return ret; + ret = updateDisplayRefresh(); + return ret; } -UpdateDisplayError_t UpdateDisplay_SetRegenState(TriState_t state){ - - UpdateDisplayError_t ret = UpdateDisplay_SetComponent(REGEN_ST, (uint32_t)state); - if(ret != UPDATEDISPLAY_ERR_NONE) return ret; - - ret = UpdateDisplay_Refresh(); - return ret; +UpdateDisplayError UpdateDisplaySetRegenState(TriState state) { + UpdateDisplayError ret = + updateDisplaySetComponent(kRegenSt, (uint32_t)state); + if (ret != kUpdateDisplayErrNone) { + return ret; + } + + ret = updateDisplayRefresh(); + return ret; } -UpdateDisplayError_t UpdateDisplay_SetCruiseState(TriState_t state){ - - UpdateDisplayError_t ret = UpdateDisplay_SetComponent(CRUISE_ST, (uint32_t)state); - if(ret != UPDATEDISPLAY_ERR_NONE) return ret; - - ret = UpdateDisplay_Refresh(); +UpdateDisplayError UpdateDisplaySetCruiseState(TriState state) { + UpdateDisplayError ret = + updateDisplaySetComponent(kCruiseSt, (uint32_t)state); + if (ret != kUpdateDisplayErrNone) { + return ret; + } + + ret = updateDisplayRefresh(); return ret; } /** - * @brief Clears the display message queue and sets the message counter semaphore value to 0 -*/ -void UpdateDisplay_ClearQueue(){ - OS_ERR err; - OSSemSet(&DisplayQ_Sem4, 0, &err); // Set the message queue semaphore value to 0 + * @brief Clears the display message queue and sets the message counter + * semaphore value to 0 + */ +void UpdateDisplayClearQueue() { + OS_ERR err = 0; + OSSemSet(&display_q_sem4, 0, + &err); // Set the message queue semaphore value to 0 if (err != OS_ERR_TASK_WAITING) { - assertOSError(err); // Don't fault if UpdateDisplay is waiting + ASSERT_OS_ERROR(err); // Don't fault if UpdateDisplay is waiting } - disp_fifo_renew(&msg_queue); // Clear the message queue - + DispFifoRenew(&msg_queue); // Clear the message queue } /** * @brief Loops through the display queue and sends all messages */ -void Task_UpdateDisplay(void *p_arg) { +void TaskUpdateDisplay(void* p_arg) { while (1) { - UpdateDisplay_PopNext(); + updateDisplayPopNext(); } } /** * Error handler functions - * Passed as callback functions to the main throwTaskError function by assertUpdateDisplayError -*/ + * Passed as callback functions to the main ThrowTaskError function by + * assertUpdateDisplayError + */ /** - * @brief A handler callback function run by the main throwTaskError function + * @brief A handler callback function run by the main ThrowTaskError function * used if we haven't reached the restart limit and encounter an error - */ -static void handler_UpdateDisplay_Restart() { - UpdateDisplay_ClearQueue(); // Clear the message queue - Display_Reset(); // Try resetting to fix the display error + */ +static void handlerUpdateDisplayRestart() { + UpdateDisplayClearQueue(); // Clear the message queue + DisplayReset(); // Try resetting to fix the display error } /** * @brief Check for a display error and assert it if it exists. - * Stores the error code, calls the main assertion function - * and runs a callback function as a handler to restart the display and clear the queue. + * Stores the error code, calls the main assertion function + * and runs a callback function as a handler to restart the display and clear + * the queue. * @param err variable with display error codes */ - static void assertUpdateDisplayError(UpdateDisplayError_t err){ - Error_UpdateDisplay = (error_code_t)err; // Store the error code for inspection +static void assertUpdateDisplayError(UpdateDisplayError err) { + error_update_display = + (ErrorCode)err; // Store the error code for inspection - if (err == UPDATEDISPLAY_ERR_NONE) return; // No error, return + if (err == kUpdateDisplayErrNone) { + return; // No error, return + } // Otherwise try resetting the display using the restart callback - throwTaskError(Error_UpdateDisplay, handler_UpdateDisplay_Restart,OPT_NO_LOCK_SCHED, OPT_RECOV); + ThrowTaskError(error_update_display, handlerUpdateDisplayRestart, + kOptNoLockSched, kOptRecov); - Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; // Clear the error after handling it + error_update_display = + kUpdateDisplayErrNone; // Clear the error after handling it } diff --git a/Apps/Src/common.c b/Apps/Src/common.c index 0ad5e1d01..f7d254a46 100644 --- a/Apps/Src/common.c +++ b/Apps/Src/common.c @@ -1,19 +1,25 @@ #include "common.h" -void print_float(char * str, float f) { - if(str) printf("%s", str); +#define MASK 0x80000000L - int32_t n = (int32_t)f; - f -= n; - f *= 100; - int32_t d = (f<0)?-f:f; - printf("%d.%02d\n\r", (int)n, (int)d); +void PrintFloat(char* str, float value) { + if (str) { + printf("%s", str); + } + + int32_t num = (int32_t)value; + value -= (float)num; + value *= 100; + int32_t dec = (int32_t)((value < 0) ? -value : value); + printf("%d.%02d\n\r", (int)num, (int)dec); } -void print_bin(char * str, uint32_t i){ - if(str) printf("%s", str); +void PrintBin(char* str, uint32_t value) { + if (str) { + printf("%s", str); + } - for(uint32_t mask=0x80000000L; mask > 0L; mask >>= 1){ - printf("%d\n\r",(mask & i)?1:0); + for (uint32_t mask = MASK; mask > 0L; mask >>= 1) { + printf("%d\n\r", (mask & value) ? 1 : 0); } } \ No newline at end of file diff --git a/Apps/Src/main.c b/Apps/Src/main.c index 62a8f33ba..eab47a1ac 100644 --- a/Apps/Src/main.c +++ b/Apps/Src/main.c @@ -1,169 +1,127 @@ /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file main.c - * @brief - * + * @brief + * */ -#include "common.h" -#include "config.h" -#include "Tasks.h" -#include "stm32f4xx.h" -#include "CANbus.h" -#include "CANConfig.h" +#include "BSP_UART.h" +#include "CanBus.h" +#include "CanConfig.h" #include "Contactors.h" #include "Display.h" #include "Minions.h" #include "Pedals.h" +#include "SendCarCan.h" +#include "Tasks.h" #include "UpdateDisplay.h" -#include "SendCarCAN.h" +#include "common.h" +#include "config.h" +#include "stm32f4xx.h" int main(void) { // Disable interrupts __disable_irq(); - OS_ERR err; + OS_ERR err = 0; OSInit(&err); - TaskSwHook_Init(); + TaskSwHookInit(); - assertOSError(err); + ASSERT_OS_ERROR(err); // Initialize apps - OSTaskCreate( - (OS_TCB*)&Init_TCB, - (CPU_CHAR*)"Init", - (OS_TASK_PTR)Task_Init, - (void*)NULL, - (OS_PRIO)TASK_INIT_PRIO, - (CPU_STK*)Init_Stk, - (CPU_STK_SIZE)WATERMARK_STACK_LIMIT/10, - (CPU_STK_SIZE)TASK_INIT_STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)0, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP), - (OS_ERR*)&err - ); - assertOSError(err); + OSTaskCreate((OS_TCB *)&init_tcb, (CPU_CHAR *)"Init", (OS_TASK_PTR)TaskInit, + (void *)NULL, (OS_PRIO)TASK_INIT_PRIO, (CPU_STK *)init_stk, + (CPU_STK_SIZE)WATERMARK_STACK_LIMIT / 10, // NOLINT + (CPU_STK_SIZE)TASK_INIT_STACK_SIZE, (OS_MSG_QTY)0, (OS_TICK)0, + (void *)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR | OS_OPT_TASK_SAVE_FP), + (OS_ERR *)&err); + ASSERT_OS_ERROR(err); // Enable interrupts __enable_irq(); // Start OS OSStart(&err); - assertOSError(err); + ASSERT_OS_ERROR(err); - while(1); + while (1) {} } -void Task_Init(void *p_arg){ - OS_ERR err; +void TaskInit(void *p_arg) { + OS_ERR err = 0; + + // Start systick + OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U)OSCfg_TickRate_Hz); - // Start systick - OS_CPU_SysTickInit(SystemCoreClock / (CPU_INT32U) OSCfg_TickRate_Hz); - // Initialize drivers - Pedals_Init(); - BSP_UART_Init(UART_2); - CANbus_Init(CARCAN, carCANFilterList, NUM_CARCAN_FILTERS); - CANbus_Init(MOTORCAN, NULL, NUM_MOTORCAN_FILTERS); - Contactors_Init(); - Display_Init(); - Minions_Init(); + PedalsInit(); + BspUartInit(kUart2); + CanBusInit(CARCAN, car_can_filter_list, NUM_CARCAN_FILTERS); + CanBusInit(MOTORCAN, NULL, NUM_MOTORCAN_FILTERS); + ContactorsInit(); + DisplayInit(); + MinionsInit(); // Initialize applications - UpdateDisplay_Init(); - SendCarCAN_Init(); + UpdateDisplayInit(); + SendCarCanInit(); // Initialize ReadTritium - OSTaskCreate( - (OS_TCB*)&ReadTritium_TCB, - (CPU_CHAR*)"ReadTritium", - (OS_TASK_PTR)Task_ReadTritium, - (void*)NULL, - (OS_PRIO)TASK_READ_TRITIUM_PRIO, - (CPU_STK*)ReadTritium_Stk, - (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, - (CPU_STK_SIZE)TASK_READ_TRITIUM_STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)0, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP), - (OS_ERR*)&err - ); - assertOSError(err); + OSTaskCreate((OS_TCB *)&read_tritium_tcb, (CPU_CHAR *)"ReadTritium", + (OS_TASK_PTR)TaskReadTritium, (void *)NULL, + (OS_PRIO)TASK_READ_TRITIUM_PRIO, (CPU_STK *)read_tritium_stk, + (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, + (CPU_STK_SIZE)TASK_READ_TRITIUM_STACK_SIZE, (OS_MSG_QTY)0, + (OS_TICK)0, (void *)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR | OS_OPT_TASK_SAVE_FP), + (OS_ERR *)&err); + ASSERT_OS_ERROR(err); // Initialize SendTritium - OSTaskCreate( - (OS_TCB*)&SendTritium_TCB, - (CPU_CHAR*)"SendTritium", - (OS_TASK_PTR)Task_SendTritium, - (void*)NULL, - (OS_PRIO)TASK_SEND_TRITIUM_PRIO, - (CPU_STK*)SendTritium_Stk, - (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, - (CPU_STK_SIZE)TASK_SEND_TRITIUM_STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)0, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP), - (OS_ERR*)&err - ); - assertOSError(err); + OSTaskCreate((OS_TCB *)&send_tritium_tcb, (CPU_CHAR *)"SendTritium", + (OS_TASK_PTR)TaskSendTritium, (void *)NULL, + (OS_PRIO)TASK_SEND_TRITIUM_PRIO, (CPU_STK *)send_tritium_stk, + (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, + (CPU_STK_SIZE)TASK_SEND_TRITIUM_STACK_SIZE, (OS_MSG_QTY)0, + (OS_TICK)0, (void *)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR | OS_OPT_TASK_SAVE_FP), + (OS_ERR *)&err); + ASSERT_OS_ERROR(err); // Initialize ReadCarCAN - OSTaskCreate( - (OS_TCB*)&ReadCarCAN_TCB, - (CPU_CHAR*)"ReadCarCAN", - (OS_TASK_PTR)Task_ReadCarCAN, - (void*)NULL, - (OS_PRIO)TASK_READ_CAR_CAN_PRIO, - (CPU_STK*)ReadCarCAN_Stk, - (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, - (CPU_STK_SIZE)TASK_READ_CAR_CAN_STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)0, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP), - (OS_ERR*)&err - ); - assertOSError(err); + OSTaskCreate((OS_TCB *)&read_car_can_tcb, (CPU_CHAR *)"ReadCarCAN", + (OS_TASK_PTR)TaskReadCarCan, (void *)NULL, + (OS_PRIO)TASK_READ_CAR_CAN_PRIO, (CPU_STK *)read_car_can_stk, + (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, + (CPU_STK_SIZE)TASK_READ_CAR_CAN_STACK_SIZE, (OS_MSG_QTY)0, + (OS_TICK)0, (void *)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR | OS_OPT_TASK_SAVE_FP), + (OS_ERR *)&err); + ASSERT_OS_ERROR(err); // Initialize UpdateDisplay OSTaskCreate( - (OS_TCB*)&UpdateDisplay_TCB, - (CPU_CHAR*)"UpdateDisplay", - (OS_TASK_PTR)Task_UpdateDisplay, - (void*)NULL, - (OS_PRIO)TASK_UPDATE_DISPLAY_PRIO, - (CPU_STK*)UpdateDisplay_Stk, + (OS_TCB *)&update_display_tcb, (CPU_CHAR *)"UpdateDisplay", + (OS_TASK_PTR)TaskUpdateDisplay, (void *)NULL, + (OS_PRIO)TASK_UPDATE_DISPLAY_PRIO, (CPU_STK *)update_display_stk, (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, - (CPU_STK_SIZE)TASK_UPDATE_DISPLAY_STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)0, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP), - (OS_ERR*)&err - ); - assertOSError(err); - + (CPU_STK_SIZE)TASK_UPDATE_DISPLAY_STACK_SIZE, (OS_MSG_QTY)0, (OS_TICK)0, + (void *)NULL, (OS_OPT)(OS_OPT_TASK_STK_CLR | OS_OPT_TASK_SAVE_FP), + (OS_ERR *)&err); + ASSERT_OS_ERROR(err); + // Initialize SendCarCAN - OSTaskCreate( - (OS_TCB*)&SendCarCAN_TCB, - (CPU_CHAR*)"SendCarCAN", - (OS_TASK_PTR)Task_SendCarCAN, - (void*)NULL, - (OS_PRIO)TASK_SEND_CAR_CAN_PRIO, - (CPU_STK*)SendCarCAN_Stk, - (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, - (CPU_STK_SIZE)TASK_SEND_CAR_CAN_STACK_SIZE, - (OS_MSG_QTY)0, - (OS_TICK)0, - (void*)NULL, - (OS_OPT)(OS_OPT_TASK_STK_CLR|OS_OPT_TASK_SAVE_FP), - (OS_ERR*)&err - ); - assertOSError(err); + OSTaskCreate((OS_TCB *)&send_car_can_tcb, (CPU_CHAR *)"SendCarCAN", + (OS_TASK_PTR)TaskSendCarCan, (void *)NULL, + (OS_PRIO)TASK_SEND_CAR_CAN_PRIO, (CPU_STK *)send_car_can_stk, + (CPU_STK_SIZE)WATERMARK_STACK_LIMIT, + (CPU_STK_SIZE)TASK_SEND_CAR_CAN_STACK_SIZE, (OS_MSG_QTY)0, + (OS_TICK)0, (void *)NULL, + (OS_OPT)(OS_OPT_TASK_STK_CLR | OS_OPT_TASK_SAVE_FP), + (OS_ERR *)&err); + ASSERT_OS_ERROR(err); OSTaskDel(NULL, &err); } diff --git a/BSP/Inc/BSP_ADC.h b/BSP/Inc/BSP_ADC.h index 33ccd47b4..ccedb41a5 100644 --- a/BSP/Inc/BSP_ADC.h +++ b/BSP/Inc/BSP_ADC.h @@ -3,51 +3,42 @@ * @file BSP_ADC.h * @brief Header file for the library to interact * with the Analog to Digital Converter (ADC) - * + * * @defgroup BSP_ADC * @addtogroup BSP_ADC * @{ */ -#ifndef __BSP_ADC_H -#define __BSP_ADC_H +#ifndef BSP_ADC_H +#define BSP_ADC_H -#include "bsp.h" #include "common.h" -#include "config.h" -#define MAX_CHANNELS 10 -#define ADC_PRECISION_BITS 12 -#define ADC_RANGE_MILLIVOLTS 3300 +#define BSP_ADC_PRECISION_BITS 12 -typedef enum -{ - Accelerator_ADC, - Brake_ADC, - NUMBER_OF_CHANNELS -} ADC_t; +typedef enum { kCh10, kCh11, kNumCh } Adc; /** * @brief Initialize the ADC module * @return None - */ -void BSP_ADC_Init(void); + */ +void BspAdcInit(void); /** * @brief Provides the ADC value of the channel at the specified index * @param hardwareDevice pedal enum that represents the specific device * @return Raw ADC value without conversion - */ -int16_t BSP_ADC_Get_Value(ADC_t hardwareDevice); + */ +int16_t BspAdcGetValue(Adc hardware_device); /** - * @brief Provides the ADC value in millivolts of the channel at the specified index + * @brief Provides the ADC value in millivolts of the channel at the specified + * index * @param hardwareDevice pedal enum that represents the specific device * @return ADC value in millivolts - */ -int16_t BSP_ADC_Get_Millivoltage(ADC_t hardwareDevice); + */ +int16_t BspAdcGetMillivoltage(Adc hardware_device); #endif - /* @} */ diff --git a/BSP/Inc/BSP_CAN.h b/BSP/Inc/BSP_CAN.h index 4163e0c2a..c9229e901 100644 --- a/BSP/Inc/BSP_CAN.h +++ b/BSP/Inc/BSP_CAN.h @@ -3,31 +3,37 @@ * @file BSP_CAN.h * @brief Header file for the library to interact * with both CAN lines in the car - * + * * @defgroup BSP_CAN * @addtogroup BSP_CAN * @{ */ -#ifndef __BSP_CAN_H -#define __BSP_CAN_H +#ifndef BSP_CAN_H +#define BSP_CAN_H #include "common.h" -#include "config.h" -#include -typedef enum {CAN_1=0, CAN_3, NUM_CAN} CAN_t; +#define BSP_CAN_DATA_LENGTH 8 +#define BSP_CAN_NUM_MAILBOX 3 + +typedef enum { kCan1 = 0, kCan3, kNumCan } Can; /** - * @brief Initializes the CAN module that communicates with the rest of the electrical system. + * @brief Initializes the CAN module that communicates with the rest of the + * electrical system. * @param bus : The bus to initialize. Should only be either CAN_1 or CAN_3. - * @param rxEvent : the function to execute when recieving a message. NULL for no action. - * @param txEnd : the function to execute after transmitting a message. NULL for no action. - * @param idWhitelist : the idWhitelist to use for message filtering. NULL for no filtering. + * @param rxEvent : the function to execute when recieving a message. NULL for + * no action. + * @param txEnd : the function to execute after transmitting a message. NULL + * for no action. + * @param idWhitelist : the idWhitelist to use for message filtering. NULL for + * no filtering. * @param idWhitelistSize : the size of the idWhitelist, if it is not NULL. * @return None */ -void BSP_CAN_Init(CAN_t bus, callback_t rxEvent, callback_t txEnd, uint16_t* idWhitelist, uint8_t idWhitelistSize); +void BspCanInit(Can bus, Callback rx_event, Callback tx_end, + uint16_t* id_whitelist, uint8_t id_whitelist_size); /** * @brief Writes a message to the specified CAN line @@ -38,19 +44,20 @@ void BSP_CAN_Init(CAN_t bus, callback_t rxEvent, callback_t txEnd, uint16_t* idW * @param len length of the message in bytes * @return number of bytes transmitted (0 if unsuccessful) */ -ErrorStatus BSP_CAN_Write(CAN_t bus, uint32_t id, uint8_t data[8], uint8_t len); + +ErrorStatus BspCanWrite(Can bus, uint32_t id, + const uint8_t data[BSP_CAN_DATA_LENGTH], uint8_t len); /** * @brief Reads the message on the specified CAN line - * @param id pointer to integer to store the + * @param id pointer to integer to store the * message ID that was read * @param data pointer to integer array to store * the message in bytes * @return number of bytes read (0 if unsuccessful) */ -ErrorStatus BSP_CAN_Read(CAN_t bus, uint32_t* id, uint8_t* data); +ErrorStatus BspCanRead(Can bus, uint32_t* id, uint8_t* data); #endif - /* @} */ diff --git a/BSP/Inc/BSP_GPIO.h b/BSP/Inc/BSP_GPIO.h index 66db068c4..c0be15384 100644 --- a/BSP/Inc/BSP_GPIO.h +++ b/BSP/Inc/BSP_GPIO.h @@ -3,55 +3,52 @@ * @file BSP_GPIO.h * @brief Header file for the library to interact * with the GPIO ports - * + * * @defgroup BSP_GPIO * @addtogroup BSP_GPIO * @{ */ -#ifndef __BSP_GPIO_H -#define __BSP_GPIO_H +#ifndef BSP_GPIO_H +#define BSP_GPIO_H #include "common.h" -#include "config.h" #include "stm32f4xx_gpio.h" -#include -#include -typedef enum {PORTA = 0, PORTB, PORTC, PORTD, NUM_PORTS} port_t; -typedef enum {INPUT = 0, OUTPUT} direction_t; +typedef enum { kPortA = 0, kPortB, kPortC, kPortD, kNumPorts } Port; +typedef enum { kInput = 0, kOutput } Direction; /** * @brief Initializes a GPIO port * @param port - port to initialize * @param mask - pins - * @param direction - input or output + * @param direction - input or output * @return None - */ -void BSP_GPIO_Init(port_t port, uint16_t mask, direction_t direction); + */ +void BspGpioInit(Port port, uint16_t mask, Direction direction); /** * @brief Reads value of the specified port * @param port to read * @return data of the port - */ -uint16_t BSP_GPIO_Read(port_t port); + */ +uint16_t BspGpioRead(Port port); /** - * @brief Writes data to a specified port + * @brief Writes data to a specified port * @param port port to write to - * @param data data to write + * @param data data to write * @return None - */ -void BSP_GPIO_Write(port_t port, uint16_t data); + */ +void BspGpioWrite(Port port, uint16_t data); /** * @brief Reads data from a specified pin (not applicalbe to output pins) * @param port The port to read from * @param pinmask Mask from stm header file that says which pin to read from * @return State of the pin - */ -uint8_t BSP_GPIO_Read_Pin(port_t port, uint16_t pinmask); + */ +uint8_t BspGpioReadPin(Port port, uint16_t pin_mask); /** * @brief Writes data to a specified pin @@ -59,18 +56,17 @@ uint8_t BSP_GPIO_Read_Pin(port_t port, uint16_t pinmask); * @param pinmask Mask from stm header file that says which pin to write too * @param state true=ON or false=OFF * @return None - */ -void BSP_GPIO_Write_Pin(port_t port, uint16_t pinmask, bool state); + */ +void BspGpioWritePin(Port port, uint16_t pin_mask, bool state); /** * @brief Returns state of output pin (not applicable to input pins) * @param port The port to get state from * @param pin The pin to get state from * @return 1 if pin is high, 0 if low - */ -uint8_t BSP_GPIO_Get_State(port_t port, uint16_t pin); + */ +uint8_t BspGpioGetState(Port port, uint16_t pin); #endif - /* @} */ diff --git a/BSP/Inc/BSP_OS.h b/BSP/Inc/BSP_OS.h deleted file mode 100644 index ab4bfcd87..000000000 --- a/BSP/Inc/BSP_OS.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar - * @file BSP_OS.h - * @brief - * - * @defgroup BSP_OS - * @addtogroup BSP_OS - * @{ - */ - -#ifndef BSP_OS_H -#define BSP_OS_H - -typedef struct { - callback_t pend; - callback_t post; -} bsp_os_t; - -#endif - - -/* @} */ diff --git a/BSP/Inc/BSP_SPI.h b/BSP/Inc/BSP_SPI.h deleted file mode 100644 index 27ad70d96..000000000 --- a/BSP/Inc/BSP_SPI.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar - * @file BSP_SPI.h - * @brief Header file for the library to interact - * over SPI with minion board(s) - * - * @defgroup BSP_SPI - * @addtogroup BSP_SPI - * @{ - */ - -#ifndef __BSP_SPI_H -#define __BSP_SPI_H - -#include "common.h" -#include "bsp.h" -#include "os.h" - - - -/** - * @brief Initializes the SPI communication - * to be used to communicate with - * minion board(s) - * @param None - * @return None - */ -void BSP_SPI_Init(void); - -/** - * @brief Transmits a message through SPI - * @param txBuf data to transmit - * @param txLen length of the data packet - * @return None - * Do not call from an ISR - */ -void BSP_SPI_Write(uint8_t* txBuf, uint8_t txLen); - -/** - * @brief Receives a message through SPI - * @param rxBuf buffer to store the received data - * @param rxLen length of the buffer - * @return None - * Do not call from an ISR - */ -void BSP_SPI_Read(uint8_t* rxBuf, uint8_t rxLen); - -#endif - - -/* @} */ diff --git a/BSP/Inc/BSP_UART.h b/BSP/Inc/BSP_UART.h index 15743921d..9cf74ef3b 100644 --- a/BSP/Inc/BSP_UART.h +++ b/BSP/Inc/BSP_UART.h @@ -1,48 +1,47 @@ /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar - * @file BSP_UART.h + * @file BSP_USART.h * @brief Header file for the library to interact - * with the UART line - * - * @defgroup BSP_UART - * @addtogroup BSP_UART + * with the USART line + * + * @defgroup BSP_USART + * @addtogroup BSP_USART * @{ */ -#ifndef __BSP_UART_H -#define __BSP_UART_H +#ifndef BSP_UART_H +#define BSP_UART_H #include "common.h" -#include -typedef enum {UART_2, UART_3, NUM_UART} UART_t; +typedef enum { kUart2, kUart3, kNumUart } Uart; + /** - * @brief Initializes the UART peripheral + * @brief Initializes the USART peripheral */ -void BSP_UART_Init(UART_t); +void BspUartInit(Uart); /** - * @brief Gets one line of ASCII text that was received - * from a specified UART device + * @brief Gets one line of ASCII text that was received + * from a specified USART device * @pre str should be at least 128bytes long. - * @param uart device selected + * @param usart device selected * @param str pointer to buffer string * @return number of bytes that was read */ -uint32_t BSP_UART_Read(UART_t uart, char *str); +uint32_t BspUartRead(Uart usart, char *str); /** - * @brief Transmits data to through a specific - * UART device (represented as a line of data + * @brief Transmits data to through a specific + * USART device (represented as a line of data * in csv file). - * @param uart device selected + * @param usart device selected * @param str pointer to buffer with data to send. * @param len size of buffer * @return number of bytes that were sent */ -uint32_t BSP_UART_Write(UART_t uart ,char *str, uint32_t len); +uint32_t BspUartWrite(Uart usart, char *str, uint32_t len); #endif - /* @} */ diff --git a/BSP/Inc/bsp.h b/BSP/Inc/bsp.h old mode 100755 new mode 100644 index f45456695..b93c54a67 --- a/BSP/Inc/bsp.h +++ b/BSP/Inc/bsp.h @@ -1,38 +1,22 @@ /** + * @file * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar - * @file bsp.h - * @brief - * + * @brief + * * @defgroup bsp * @addtogroup bsp * @{ */ -#ifndef __BSP_H -#define __BSP_H +#ifndef BSP_H +#define BSP_H + +#include #include "BSP_ADC.h" #include "BSP_CAN.h" -#include "BSP_UART.h" -#include "BSP_SPI.h" #include "BSP_GPIO.h" - -#include -#include - -#ifdef SIMULATOR -#define DATA_PATH(f) "BSP/Simulator/Hardware/Data/" f - -#define SWITCHES_CSV "Switches.csv" -#define CONTACTORS_CSV "Contactors.csv" -#define PEDALS_CSV "Pedals.csv" -#define UART_CSV "UART.csv" -#define CAN_CSV "CAN.csv" -#define SPI_CSV "SPI.csv" -#define LIGHTS_CSV "Lights.csv" -#define PRECHARGE_CSV "PreCharge.csv" -#define GPIO_CSV "GPIO.csv" -#endif +#include "BSP_UART.h" #endif diff --git a/BSP/STM32F413/Makefile b/BSP/STM32F413/Makefile index bfc0a49b9..f5ee202bc 100644 --- a/BSP/STM32F413/Makefile +++ b/BSP/STM32F413/Makefile @@ -184,6 +184,36 @@ $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) $(BUILD_DIR): mkdir $@ +####################################### +# clang +####################################### +CLANGINPUTS = \ +$(wildcard ../../Apps/Inc/*) \ +$(wildcard ../../Apps/Src/*) \ +$(wildcard ../../Drivers/Inc/*) \ +$(wildcard ../../Drivers/Src/*) \ +$(wildcard ../../BSP/Inc/*) \ +$(wildcard ../../BSP/STM32F413/Src/BSP_*.c) \ +$(wildcard ../../BSP/STM32F413/Src/retarget.c) \ + +####################################### +# tidy +####################################### +TIDYFLAGS = --config-file=../../.clang-tidy +TIDYCFLAGS = $(C_DEFS) +TIDYCFLAGS += -m32 + +tidy: + clang-tidy-17 $(TIDYFLAGS) $(CLANGINPUTS) --fix -- $(C_INCLUDES) $(TIDYCFLAGS) + +####################################### +# format +####################################### +FORMATFLAGS = --config-file=../../.clang-format + +format: + clang-format-17 -i $(CLANGINPUTS) + ####################################### # clean up ####################################### diff --git a/BSP/STM32F413/Src/BSP_ADC.c b/BSP/STM32F413/Src/BSP_ADC.c index f49dac17b..2cc562700 100644 --- a/BSP/STM32F413/Src/BSP_ADC.c +++ b/BSP/STM32F413/Src/BSP_ADC.c @@ -1,90 +1,106 @@ /* Copyright (c) 2020 UT Longhorn Racing Solar */ #include "BSP_ADC.h" + #include "stm32f4xx.h" -static volatile uint16_t ADCresults[2]; - -static void ADC_InitDMA(void) { - // Start the clock for the DMA - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); - - // Create the DMA structure - DMA_InitTypeDef DMA_InitStruct; - - DMA_InitStruct.DMA_Channel = DMA_Channel_0; - DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR); - DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t) &ADCresults; - DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory; - DMA_InitStruct.DMA_BufferSize = 2; - DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; - DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; - DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; - DMA_InitStruct.DMA_Priority = DMA_Priority_High; - DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable; - DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; - DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single; - DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; - DMA_Init(DMA2_Stream0, &DMA_InitStruct); - - // Enable DMA2 stream 0 - DMA_Cmd(DMA2_Stream0, ENABLE); +#define NUM_ADC 2 +#define DMA_BUFFER_SIZE 2 +#define ADC10_RANK 1 +#define ADC11_RANK 2 + +#define ADC_RANGE_MILLIVOLTS 3300 + +static volatile uint16_t adc_results[NUM_ADC]; + +static void adcInitDma(void) { + // Start the clock for the DMA + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); + + // Create the DMA structure + DMA_InitTypeDef dma_init_struct; + + dma_init_struct.DMA_Channel = DMA_Channel_0; + dma_init_struct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; + dma_init_struct.DMA_Memory0BaseAddr = (uint32_t)&adc_results; + dma_init_struct.DMA_DIR = DMA_DIR_PeripheralToMemory; + dma_init_struct.DMA_BufferSize = DMA_BUFFER_SIZE; + dma_init_struct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + dma_init_struct.DMA_MemoryInc = DMA_MemoryInc_Enable; + dma_init_struct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; + dma_init_struct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; + dma_init_struct.DMA_Mode = DMA_Mode_Circular; + dma_init_struct.DMA_Priority = DMA_Priority_High; + dma_init_struct.DMA_FIFOMode = DMA_FIFOMode_Disable; + dma_init_struct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; + dma_init_struct.DMA_MemoryBurst = DMA_MemoryBurst_Single; + dma_init_struct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(DMA2_Stream0, &dma_init_struct); + + // Enable DMA2 stream 0 + DMA_Cmd(DMA2_Stream0, ENABLE); } /** - * @brief Initializes the ADC module. This is to measure the hall effect sensors - * on the Current Monitor Board. + * @brief Initializes the ADC module. This is to measure the hall effect + * sensors on the Current Monitor Board. * @param None * @return None */ -void BSP_ADC_Init(void) { - RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // Enable the ADC clock - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); // Enable the PC clock for port C - - ADC_InitDMA(); - - GPIO_InitTypeDef GPIO_InitStruct; - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; // Using pin PC0 and PC1 - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN; // Analog Input - GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; // High impedence - GPIO_Init(GPIOC,&GPIO_InitStruct); - - // ADC Common Init - ADC_CommonInitTypeDef ADC_CommonStruct; - ADC_CommonStruct.ADC_Mode = ADC_Mode_Independent; - ADC_CommonStruct.ADC_Prescaler = ADC_Prescaler_Div2; - ADC_CommonStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; - ADC_CommonStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; - ADC_CommonInit(&ADC_CommonStruct); - - // Set up to use DMA so that multiple channels can be used - ADC_InitTypeDef ADC_InitStruct; // Initialization structure - ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b; // High resolution - ADC_InitStruct.ADC_ScanConvMode = ENABLE; // So we can go through all the channels - ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; // Cycle the channels - ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; - ADC_InitStruct.ADC_ExternalTrigConv = DISABLE; - ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; - ADC_InitStruct.ADC_NbrOfConversion = 2; // We have two channels that we need to read - - ADC_Init(ADC1, &ADC_InitStruct); - - // Configure the channels - // Apparently channel 2 has priority, or is at least read first. - // If you change the priorities, be prepared to have the order in the array change. - ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_480Cycles); // Accelerator - ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_480Cycles); // Brake - - ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); - - ADC_DMACmd(ADC1, ENABLE); - - // Enable ADC1 - ADC_Cmd(ADC1, ENABLE); - - ADC_SoftwareStartConv(ADC1); +void BspAdcInit(void) { + RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, + ENABLE); // Enable the ADC clock + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, + ENABLE); // Enable the PC clock for port C + + adcInitDma(); + + GPIO_InitTypeDef gpio_init_struct; + gpio_init_struct.GPIO_Pin = + GPIO_Pin_0 | GPIO_Pin_1; // Using pin PC0 and PC1 + gpio_init_struct.GPIO_Mode = GPIO_Mode_AN; // Analog Input + gpio_init_struct.GPIO_PuPd = GPIO_PuPd_NOPULL; // High impedence + GPIO_Init(GPIOC, &gpio_init_struct); + + // ADC Common Init + ADC_CommonInitTypeDef adc_common_struct; + adc_common_struct.ADC_Mode = ADC_Mode_Independent; + adc_common_struct.ADC_Prescaler = ADC_Prescaler_Div2; + adc_common_struct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; + adc_common_struct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; + ADC_CommonInit(&adc_common_struct); + + // Set up to use DMA so that multiple channels can be used + ADC_InitTypeDef adc_init_struct; // Initialization structure + adc_init_struct.ADC_Resolution = ADC_Resolution_12b; // High resolution + adc_init_struct.ADC_ScanConvMode = + ENABLE; // So we can go through all the channels + adc_init_struct.ADC_ContinuousConvMode = ENABLE; // Cycle the channels + adc_init_struct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; + adc_init_struct.ADC_ExternalTrigConv = DISABLE; + adc_init_struct.ADC_DataAlign = ADC_DataAlign_Right; + adc_init_struct.ADC_NbrOfConversion = + NUM_ADC; // We have two channels that we need to read + + ADC_Init(ADC1, &adc_init_struct); + + // Configure the channels + // Apparently channel 2 has priority, or is at least read first. + // If you change the priorities, be prepared to have the order in the array + // change. + ADC_RegularChannelConfig(ADC1, ADC_Channel_10, ADC10_RANK, + ADC_SampleTime_480Cycles); // Accelerator + ADC_RegularChannelConfig(ADC1, ADC_Channel_11, ADC11_RANK, + ADC_SampleTime_480Cycles); // Brake + + ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); + + ADC_DMACmd(ADC1, ENABLE); + + // Enable ADC1 + ADC_Cmd(ADC1, ENABLE); + + ADC_SoftwareStartConv(ADC1); } /** @@ -92,12 +108,11 @@ void BSP_ADC_Init(void) { * @param None * @return millivoltage value ADC measurement */ -int16_t BSP_ADC_Get_Value(ADC_t hardwareDevice) { - +int16_t BspAdcGetValue(Adc hardware_device) { // Get ADC raw data - uint16_t data = ADCresults[hardwareDevice]; - - return (int16_t) data; + uint16_t data = adc_results[hardware_device]; + + return (int16_t)data; } /** @@ -105,11 +120,10 @@ int16_t BSP_ADC_Get_Value(ADC_t hardwareDevice) { * @param None * @return millivoltage value ADC measurement */ -int16_t BSP_ADC_Get_Millivoltage(ADC_t hardwareDevice) { - +int16_t BspAdcGetMillivoltage(Adc hardware_device) { // Get ADC raw data - int16_t data = (int16_t) ADCresults[hardwareDevice]; - + int16_t data = (int16_t)adc_results[hardware_device]; + // Convert to millivoltage - return (ADC_RANGE_MILLIVOLTS * data) >> ADC_PRECISION_BITS; + return (int16_t)((ADC_RANGE_MILLIVOLTS * data) >> BSP_ADC_PRECISION_BITS); } diff --git a/BSP/STM32F413/Src/BSP_CAN.c b/BSP/STM32F413/Src/BSP_CAN.c index 82edafcd9..2261c28ea 100644 --- a/BSP/STM32F413/Src/BSP_CAN.c +++ b/BSP/STM32F413/Src/BSP_CAN.c @@ -1,72 +1,76 @@ /* Copyright (c) 2020 UT Longhorn Racing Solar */ #include "BSP_CAN.h" -#include "stm32f4xx.h" + #include "os.h" +#include "stm32f4xx.h" + +#define NUM_CAN_LINES 2 // The message information that we care to receive -typedef struct _msg -{ +typedef struct Msg { uint32_t id; - uint8_t data[8]; -} msg_t; + uint8_t data[BSP_CAN_DATA_LENGTH]; +} Msg; // Set up a fifo for receiving -#define FIFO_TYPE msg_t +#define FIFO_TYPE Msg #define FIFO_SIZE 25 -#define FIFO_NAME msg_queue +#define FIFO_NAME MsgQueue #include "fifo.h" -#define NUM_FILTER_REGS 4 // Number of 16 bit registers for ids in one CAN_FilterInit struct +#define NUM_FILTER_REGS \ + 4 // Number of 16 bit registers for ids in one CAN_FilterInit struct -//return error if someone tries to call from motor can +// return error if someone tries to call from motor can -static msg_queue_t gRxQueue[2]; +static MsgQueue g_rx_queue[NUM_CAN_LINES]; // Required for receiving CAN messages -static CanTxMsg gTxMessage[2]; -static CanRxMsg gRxMessage[2]; +static CanTxMsg g_tx_message[NUM_CAN_LINES]; +static CanRxMsg g_rx_message[NUM_CAN_LINES]; // User parameters for CAN events -static callback_t gRxEvent[2]; -static callback_t gTxEnd[2]; +static Callback g_rx_event[NUM_CAN_LINES]; +static Callback g_tx_end[NUM_CAN_LINES]; -void BSP_CAN1_Init(uint16_t* idWhitelist, uint8_t idWhitelistSize); -void BSP_CAN3_Init(uint16_t* idWhitelist, uint8_t idWhitelistSize); +void BspCan1Init(const uint16_t* id_whitelist, uint8_t id_whitelist_size); +void BspCan3Init(const uint16_t* id_whitelist, uint8_t id_whitelist_size); /** - * @brief Initializes the CAN module that communicates with the rest of the electrical system. - * @param rxEvent : the function to execute when recieving a message. NULL for no action. - * @param txEnd : the function to execute after transmitting a message. NULL for no action. + * @brief Initializes the CAN module that communicates with the rest of the + * electrical system. + * @param rxEvent : the function to execute when recieving a message. NULL for + * no action. + * @param txEnd : the function to execute after transmitting a message. NULL + * for no action. * @return None */ -void BSP_CAN_Init(CAN_t bus, callback_t rxEvent, callback_t txEnd, uint16_t* idWhitelist, uint8_t idWhitelistSize) { - +void BspCanInit(Can bus, Callback rx_event, Callback tx_end, + uint16_t* id_whitelist, uint8_t id_whitelist_size) { // Configure event handles - gRxEvent[bus] = rxEvent; - gTxEnd[bus] = txEnd; + g_rx_event[bus] = rx_event; + g_tx_end[bus] = tx_end; - if (bus == CAN_1) - { - BSP_CAN1_Init(idWhitelist, idWhitelistSize); - } - else - { - BSP_CAN3_Init(idWhitelist, idWhitelistSize); + if (bus == kCan1) { + BspCan1Init(id_whitelist, id_whitelist_size); + } else { + BspCan3Init(id_whitelist, id_whitelist_size); } } -void BSP_CAN1_Init(uint16_t* idWhitelist, uint8_t idWhitelistSize) { - GPIO_InitTypeDef GPIO_InitStruct; - CAN_InitTypeDef CAN_InitStruct; - NVIC_InitTypeDef NVIC_InitStruct; - CAN_FilterInitTypeDef CAN_FilterInitStruct; +void BspCan1Init(const uint16_t* id_whitelist, uint8_t id_whitelist_size) { + GPIO_InitTypeDef gpio_init_struct; + CAN_InitTypeDef can_init_struct; + NVIC_InitTypeDef nvic_init_struct; + CAN_FilterInitTypeDef can_filter_init_struct; // Initialize the queue - gRxQueue[0] = msg_queue_new(); + g_rx_queue[0] = MsgQueueNew(); - /* CAN GPIOs configuration **************************************************/ + /* CAN GPIOs configuration + * **************************************************/ /* Enable GPIO clock */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); @@ -76,141 +80,160 @@ void BSP_CAN1_Init(uint16_t* idWhitelist, uint8_t idWhitelistSize) { GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_CAN1); /* Configure CAN RX and TX pins */ - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; - GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - /* CAN configuration ********************************************************/ + gpio_init_struct.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12; + gpio_init_struct.GPIO_Mode = GPIO_Mode_AF; + gpio_init_struct.GPIO_Speed = GPIO_Speed_50MHz; + gpio_init_struct.GPIO_OType = GPIO_OType_PP; + gpio_init_struct.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(GPIOA, &gpio_init_struct); + + /* CAN configuration + * ********************************************************/ /* Enable CAN clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); /* CAN cell init */ - CAN_InitStruct.CAN_TTCM = DISABLE; - CAN_InitStruct.CAN_ABOM = DISABLE; - CAN_InitStruct.CAN_AWUM = DISABLE; - CAN_InitStruct.CAN_NART = DISABLE; - CAN_InitStruct.CAN_RFLM = DISABLE; - CAN_InitStruct.CAN_TXFP = ENABLE; - #ifdef CAR_LOOPBACK + can_init_struct.CAN_TTCM = DISABLE; + can_init_struct.CAN_ABOM = DISABLE; + can_init_struct.CAN_AWUM = DISABLE; + can_init_struct.CAN_NART = DISABLE; + can_init_struct.CAN_RFLM = DISABLE; + can_init_struct.CAN_TXFP = ENABLE; +#ifdef CAR_LOOPBACK CAN_InitStruct.CAN_Mode = CAN_Mode_LoopBack; - #else - CAN_InitStruct.CAN_Mode = CAN_Mode_Normal; - #endif - CAN_InitStruct.CAN_SJW = CAN_SJW_1tq; +#else + can_init_struct.CAN_Mode = CAN_Mode_Normal; +#endif + can_init_struct.CAN_SJW = CAN_SJW_1tq; /* CAN Baudrate = 125 KBps * 1/(prescalar + (prescalar*BS1) + (prescalar*BS2)) * Clk = CAN Baudrate - * The CAN clk is currently set to 20MHz (APB1 clock set to 20MHz in BSP_PLL_Init()) + * The CAN clk is currently set to 20MHz (APB1 clock set to 20MHz in + * BSP_PLL_Init()) */ - CAN_InitStruct.CAN_BS1 = CAN_BS1_3tq; - CAN_InitStruct.CAN_BS2 = CAN_BS2_4tq; - CAN_InitStruct.CAN_Prescaler = 16; - CAN_Init(CAN1, &CAN_InitStruct); - - /* CAN filter init - * Initializes hardware filter banks to be used for filtering CAN IDs (whitelist) + can_init_struct.CAN_BS1 = CAN_BS1_3tq; + can_init_struct.CAN_BS2 = CAN_BS2_4tq; + can_init_struct.CAN_Prescaler = 16; // NOLINT + CAN_Init(CAN1, &can_init_struct); + + /* CAN filter init + * Initializes hardware filter banks to be used for filtering CAN IDs + * (whitelist) */ - if(idWhitelist == NULL){ + if (id_whitelist == NULL) { // No filtering. All IDs can pass through. - CAN_FilterInitStruct.CAN_FilterNumber = 0; - CAN_FilterInitStruct.CAN_FilterMode = CAN_FilterMode_IdMask; - CAN_FilterInitStruct.CAN_FilterScale = CAN_FilterScale_32bit; - CAN_FilterInitStruct.CAN_FilterIdHigh = 0x0000; - CAN_FilterInitStruct.CAN_FilterIdLow = 0x0000; - CAN_FilterInitStruct.CAN_FilterMaskIdHigh = 0x0000; - CAN_FilterInitStruct.CAN_FilterMaskIdLow = 0x0000; - CAN_FilterInitStruct.CAN_FilterFIFOAssignment = 0; - CAN_FilterInitStruct.CAN_FilterActivation = ENABLE; - CAN_FilterInit(CAN1, &CAN_FilterInitStruct); - } else{ + can_filter_init_struct.CAN_FilterNumber = 0; + can_filter_init_struct.CAN_FilterMode = CAN_FilterMode_IdMask; + can_filter_init_struct.CAN_FilterScale = CAN_FilterScale_32bit; + can_filter_init_struct.CAN_FilterIdHigh = 0x0000; + can_filter_init_struct.CAN_FilterIdLow = 0x0000; + can_filter_init_struct.CAN_FilterMaskIdHigh = 0x0000; + can_filter_init_struct.CAN_FilterMaskIdLow = 0x0000; + can_filter_init_struct.CAN_FilterFIFOAssignment = 0; + can_filter_init_struct.CAN_FilterActivation = ENABLE; + CAN_FilterInit(CAN1, &can_filter_init_struct); + } else { // Filter CAN IDs // So far, if we shift whatever id we need by 5, it works - // If whitelist is passed but no valid ID exists inside of it, filter nothing i.e. no ID gets through - // MAXIMUM CAN ID ALLOWED IS 2047 - - CAN_FilterInitStruct.CAN_FilterMode = CAN_FilterMode_IdList; //list mode - CAN_FilterInitStruct.CAN_FilterScale = CAN_FilterScale_16bit; - CAN_FilterInitStruct.CAN_FilterFIFOAssignment = 0; - CAN_FilterInitStruct.CAN_FilterActivation = ENABLE; - uint16_t validIDCounter = 0; - - uint16_t* FilterStructPtr = (uint16_t*)&(CAN_FilterInitStruct); //address of CAN Filter Struct - for(uint8_t i = 0; i < idWhitelistSize; i++){ - if (idWhitelist[i] == 0){ //zero ID check + // If whitelist is passed but no valid ID exists inside of it, filter + // nothing i.e. no ID gets through MAXIMUM CAN ID ALLOWED IS 2047 + + can_filter_init_struct.CAN_FilterMode = + CAN_FilterMode_IdList; // list mode + can_filter_init_struct.CAN_FilterScale = CAN_FilterScale_16bit; + can_filter_init_struct.CAN_FilterFIFOAssignment = 0; + can_filter_init_struct.CAN_FilterActivation = ENABLE; + uint16_t valid_id_counter = 0; + + uint16_t* filter_struct_ptr = (uint16_t*)&( + can_filter_init_struct); // address of CAN Filter Struct + for (uint8_t i = 0; i < id_whitelist_size; i++) { + if (id_whitelist[i] == 0) { // zero ID check continue; } - - CAN_FilterInitStruct.CAN_FilterNumber = i / NUM_FILTER_REGS; //determines filter number based on CAN ID - *(FilterStructPtr + (i%NUM_FILTER_REGS)) = idWhitelist[i] << 5; - validIDCounter++; - - if(i % NUM_FILTER_REGS == NUM_FILTER_REGS - 1){ //if four elements have been written to a filter call CAN_FilterInit() - CAN_FilterInit(CAN1, &CAN_FilterInitStruct); - } - else if(i == idWhitelistSize - 1){ //we are out of elements, call CAN_FilterInit() - for(uint8_t j = i%NUM_FILTER_REGS + 1; j <= NUM_FILTER_REGS - 1; j++) // Set unfilled filter registers to 0 - *(FilterStructPtr + j) = 0x0000; - CAN_FilterInit(CAN1, &CAN_FilterInitStruct); - } - else if(validIDCounter > 112){ //All filter banks are to be filled and there is no point in filtering - for(uint8_t filter = 0; filter < 28; filter++){//Therefore, let all IDs through (no filtering) - CAN_FilterInitStruct.CAN_FilterNumber = filter; - CAN_FilterInitStruct.CAN_FilterActivation = DISABLE; - CAN_FilterInit(CAN1, &CAN_FilterInitStruct); - } + can_filter_init_struct.CAN_FilterNumber = + i / + NUM_FILTER_REGS; // determines filter number based on CAN ID + *(filter_struct_ptr + (i % NUM_FILTER_REGS)) = id_whitelist[i] + << 5; // NOLINT + valid_id_counter++; + + if (i % NUM_FILTER_REGS == + NUM_FILTER_REGS - 1) { // if four elements have been written to + // a filter call CAN_FilterInit() + CAN_FilterInit(CAN1, &can_filter_init_struct); + } else if (i == id_whitelist_size - 1) { // we are out of elements, + // call CAN_FilterInit() + for (uint8_t j = i % NUM_FILTER_REGS + 1; + j <= NUM_FILTER_REGS - 1; + j++) { // Set unfilled filter registers to 0 + *(filter_struct_ptr + j) = 0x0000; + } + + CAN_FilterInit(CAN1, &can_filter_init_struct); + } else if (valid_id_counter > + 112) { // NOLINT + // All filter banks are to be filled and there is + // no point in filtering + for (uint8_t filter = 0; filter < 28; // NOLINT + filter++) { // Therefore, let all IDs through (no + // filtering) + can_filter_init_struct.CAN_FilterNumber = filter; + can_filter_init_struct.CAN_FilterActivation = DISABLE; + CAN_FilterInit(CAN1, &can_filter_init_struct); + } } } } /* Transmit Structure preparation */ - gTxMessage[0].ExtId = 0x5; - gTxMessage[0].RTR = CAN_RTR_DATA; - gTxMessage[0].IDE = CAN_ID_STD; - gTxMessage[0].DLC = 1; + g_tx_message[0].ExtId = 0x5; // NOLINT + g_tx_message[0].RTR = CAN_RTR_DATA; + g_tx_message[0].IDE = CAN_ID_STD; + g_tx_message[0].DLC = 1; /* Receive Structure preparation */ - gRxMessage[0].StdId = 0x00; - gRxMessage[0].ExtId = 0x00; - gRxMessage[0].IDE = CAN_ID_STD; - gRxMessage[0].DLC = 0; - gRxMessage[0].FMI = 0; + g_rx_message[0].StdId = 0x00; + g_rx_message[0].ExtId = 0x00; + g_rx_message[0].IDE = CAN_ID_STD; + g_rx_message[0].DLC = 0; + g_rx_message[0].FMI = 0; /* Enable FIFO 0 message pending Interrupt */ CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); // Enable Rx interrupts - NVIC_InitStruct.NVIC_IRQChannel = CAN1_RX0_IRQn; // TODO: CHECK IRQ CHANNELS - NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00; - NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00; - NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStruct); - - if(NULL != gTxEnd[0]) { + nvic_init_struct.NVIC_IRQChannel = + CAN1_RX0_IRQn; // TODO: CHECK IRQ CHANNELS + nvic_init_struct.NVIC_IRQChannelPreemptionPriority = 0x00; + nvic_init_struct.NVIC_IRQChannelSubPriority = 0x00; + nvic_init_struct.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&nvic_init_struct); + + if (NULL != g_tx_end[0]) { // Enable Tx Interrupts CAN_ITConfig(CAN1, CAN_IT_TME, ENABLE); - NVIC_InitStruct.NVIC_IRQChannel = CAN1_TX_IRQn; - NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x0; // TODO: assess both of these priority settings - NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x0; - NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStruct); + nvic_init_struct.NVIC_IRQChannel = CAN1_TX_IRQn; + nvic_init_struct.NVIC_IRQChannelPreemptionPriority = + 0x0; // TODO: assess both of these priority settings + nvic_init_struct.NVIC_IRQChannelSubPriority = 0x0; + nvic_init_struct.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&nvic_init_struct); } } -void BSP_CAN3_Init(uint16_t* idWhitelist, uint8_t idWhitelistSize) -{ - GPIO_InitTypeDef GPIO_InitStruct; - CAN_InitTypeDef CAN_InitStruct; - NVIC_InitTypeDef NVIC_InitStruct; - CAN_FilterInitTypeDef CAN_FilterInitStruct; +void BspCan3Init(const uint16_t* id_whitelist, uint8_t id_whitelist_size) { + GPIO_InitTypeDef gpio_init_struct; + CAN_InitTypeDef can_init_struct; + NVIC_InitTypeDef nvic_init_struct; + CAN_FilterInitTypeDef can_filter_init_struct; // Initialize the queue - gRxQueue[1] = msg_queue_new(); + g_rx_queue[1] = MsgQueueNew(); - /* CAN GPIOs configuration **************************************************/ + /* CAN GPIOs configuration + * **************************************************/ /* Enable GPIO clock */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); @@ -220,75 +243,87 @@ void BSP_CAN3_Init(uint16_t* idWhitelist, uint8_t idWhitelistSize) GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF11_CAN3); /* Configure CAN RX and TX pins */ - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_8; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; - GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - /* CAN configuration ********************************************************/ + gpio_init_struct.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_8; + gpio_init_struct.GPIO_Mode = GPIO_Mode_AF; + gpio_init_struct.GPIO_Speed = GPIO_Speed_50MHz; + gpio_init_struct.GPIO_OType = GPIO_OType_PP; + gpio_init_struct.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(GPIOA, &gpio_init_struct); + + /* CAN configuration + * ********************************************************/ /* Enable CAN clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN3, ENABLE); /* CAN cell init */ - CAN_InitStruct.CAN_TTCM = DISABLE; - CAN_InitStruct.CAN_ABOM = DISABLE; - CAN_InitStruct.CAN_AWUM = DISABLE; - CAN_InitStruct.CAN_NART = DISABLE; - CAN_InitStruct.CAN_RFLM = DISABLE; - CAN_InitStruct.CAN_TXFP = ENABLE; - #ifdef MOTOR_LOOPBACK + can_init_struct.CAN_TTCM = DISABLE; + can_init_struct.CAN_ABOM = DISABLE; + can_init_struct.CAN_AWUM = DISABLE; + can_init_struct.CAN_NART = DISABLE; + can_init_struct.CAN_RFLM = DISABLE; + can_init_struct.CAN_TXFP = ENABLE; +#ifdef MOTOR_LOOPBACK CAN_InitStruct.CAN_Mode = CAN_Mode_LoopBack; - #else - CAN_InitStruct.CAN_Mode = CAN_Mode_Normal; - #endif - CAN_InitStruct.CAN_SJW = CAN_SJW_1tq; +#else + can_init_struct.CAN_Mode = CAN_Mode_Normal; +#endif + can_init_struct.CAN_SJW = CAN_SJW_1tq; /* CAN Baudrate = 125 KBps * 1/(prescalar + (prescalar*BS1) + (prescalar*BS2)) * Clk = CAN Baudrate - * The CAN clk is currently set to 20MHz (APB1 clock set to 20MHz in BSP_PLL_Init()) + * The CAN clk is currently set to 20MHz (APB1 clock set to 20MHz in + * BSP_PLL_Init()) */ - CAN_InitStruct.CAN_BS1 = CAN_BS1_3tq; - CAN_InitStruct.CAN_BS2 = CAN_BS2_4tq; - CAN_InitStruct.CAN_Prescaler = 16; - CAN_Init(CAN3, &CAN_InitStruct); - - /* CAN filter init - * Initializes hardware filter banks to be used for filtering CAN IDs (whitelist) + can_init_struct.CAN_BS1 = CAN_BS1_3tq; + can_init_struct.CAN_BS2 = CAN_BS2_4tq; + can_init_struct.CAN_Prescaler = 16; // NOLINT + CAN_Init(CAN3, &can_init_struct); + + /* CAN filter init + * Initializes hardware filter banks to be used for filtering CAN IDs + * (whitelist) */ - if(idWhitelist == NULL){ + if (id_whitelist == NULL) { // No filtering. All IDs can pass through. - CAN_FilterInitStruct.CAN_FilterNumber = 0; - CAN_FilterInitStruct.CAN_FilterMode = CAN_FilterMode_IdMask; - CAN_FilterInitStruct.CAN_FilterScale = CAN_FilterScale_32bit; - CAN_FilterInitStruct.CAN_FilterIdHigh = 0x0000; - CAN_FilterInitStruct.CAN_FilterIdLow = 0x0000; - CAN_FilterInitStruct.CAN_FilterMaskIdHigh = 0x0000; - CAN_FilterInitStruct.CAN_FilterMaskIdLow = 0x0000; - CAN_FilterInitStruct.CAN_FilterFIFOAssignment = 0; - CAN_FilterInitStruct.CAN_FilterActivation = ENABLE; - CAN_FilterInit(CAN3, &CAN_FilterInitStruct); - } else{ + can_filter_init_struct.CAN_FilterNumber = 0; + can_filter_init_struct.CAN_FilterMode = CAN_FilterMode_IdMask; + can_filter_init_struct.CAN_FilterScale = CAN_FilterScale_32bit; + can_filter_init_struct.CAN_FilterIdHigh = 0x0000; + can_filter_init_struct.CAN_FilterIdLow = 0x0000; + can_filter_init_struct.CAN_FilterMaskIdHigh = 0x0000; + can_filter_init_struct.CAN_FilterMaskIdLow = 0x0000; + can_filter_init_struct.CAN_FilterFIFOAssignment = 0; + can_filter_init_struct.CAN_FilterActivation = ENABLE; + CAN_FilterInit(CAN3, &can_filter_init_struct); + } else { // Filter CAN IDs - CAN_FilterInitStruct.CAN_FilterMode = CAN_FilterMode_IdList; //list mode - CAN_FilterInitStruct.CAN_FilterScale = CAN_FilterScale_16bit; - CAN_FilterInitStruct.CAN_FilterFIFOAssignment = 0; - CAN_FilterInitStruct.CAN_FilterActivation = ENABLE; - - uint16_t* FilterStructPtr = (uint16_t*)&(CAN_FilterInitStruct); //address of CAN Filter Struct - for(uint8_t i = 0; i < idWhitelistSize; i++){ - CAN_FilterInitStruct.CAN_FilterNumber = i / NUM_FILTER_REGS; //determines filter number based on CAN ID - *(FilterStructPtr + (i%NUM_FILTER_REGS)) = idWhitelist[i]; - - if(i % NUM_FILTER_REGS == NUM_FILTER_REGS - 1){ //if four elements have been written to a filter call CAN_FilterInit() - CAN_FilterInit(CAN3, &CAN_FilterInitStruct); - } - else if(i == idWhitelistSize - 1){ //we are out of elements, call CAN_FilterInit() - for(uint8_t j = i%NUM_FILTER_REGS + 1; j <= NUM_FILTER_REGS - 1; j++) // Set unfilled filter registers to 0 - *(FilterStructPtr + j) = 0x0000; - - CAN_FilterInit(CAN3, &CAN_FilterInitStruct); + can_filter_init_struct.CAN_FilterMode = + CAN_FilterMode_IdList; // list mode + can_filter_init_struct.CAN_FilterScale = CAN_FilterScale_16bit; + can_filter_init_struct.CAN_FilterFIFOAssignment = 0; + can_filter_init_struct.CAN_FilterActivation = ENABLE; + + uint16_t* filter_struct_ptr = (uint16_t*)&( + can_filter_init_struct); // address of CAN Filter Struct + for (uint8_t i = 0; i < id_whitelist_size; i++) { + can_filter_init_struct.CAN_FilterNumber = + i / + NUM_FILTER_REGS; // determines filter number based on CAN ID + *(filter_struct_ptr + (i % NUM_FILTER_REGS)) = id_whitelist[i]; + + if (i % NUM_FILTER_REGS == + NUM_FILTER_REGS - 1) { // if four elements have been written to + // a filter call CAN_FilterInit() + CAN_FilterInit(CAN3, &can_filter_init_struct); + } else if (i == id_whitelist_size - 1) { // we are out of elements, + // call CAN_FilterInit() + for (uint8_t j = i % NUM_FILTER_REGS + 1; + j <= NUM_FILTER_REGS - 1; + j++) { // Set unfilled filter registers to 0 + *(filter_struct_ptr + j) = 0x0000; + } + + CAN_FilterInit(CAN3, &can_filter_init_struct); } } } @@ -296,61 +331,63 @@ void BSP_CAN3_Init(uint16_t* idWhitelist, uint8_t idWhitelistSize) // CAN_SlaveStartBank(CAN1, 0); /* Transmit Structure preparation */ - gTxMessage[1].ExtId = 0x5; - gTxMessage[1].RTR = CAN_RTR_DATA; - gTxMessage[1].IDE = CAN_ID_STD; - gTxMessage[1].DLC = 1; + g_tx_message[1].ExtId = 0x5; // NOLINT + g_tx_message[1].RTR = CAN_RTR_DATA; + g_tx_message[1].IDE = CAN_ID_STD; + g_tx_message[1].DLC = 1; /* Receive Structure preparation */ - gRxMessage[1].StdId = 0x00; - gRxMessage[1].ExtId = 0x00; - gRxMessage[1].IDE = CAN_ID_STD; - gRxMessage[1].DLC = 0; - gRxMessage[1].FMI = 0; + g_rx_message[1].StdId = 0x00; + g_rx_message[1].ExtId = 0x00; + g_rx_message[1].IDE = CAN_ID_STD; + g_rx_message[1].DLC = 0; + g_rx_message[1].FMI = 0; /* Enable FIFO 0 message pending Interrupt */ CAN_ITConfig(CAN3, CAN_IT_FMP0, ENABLE); - //TODO: Double check preemption priority and subpriority - // Enable Rx interrupts - NVIC_InitStruct.NVIC_IRQChannel = CAN3_RX0_IRQn; - NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00; - NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00; - NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStruct); + // TODO: Double check preemption priority and subpriority + // Enable Rx interrupts + nvic_init_struct.NVIC_IRQChannel = CAN3_RX0_IRQn; + nvic_init_struct.NVIC_IRQChannelPreemptionPriority = 0x00; + nvic_init_struct.NVIC_IRQChannelSubPriority = 0x00; + nvic_init_struct.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&nvic_init_struct); // Enable Tx interrupts - if(NULL != gTxEnd[1]){ - CAN_ITConfig(CAN3,CAN_IT_TME,ENABLE); - NVIC_InitStruct.NVIC_IRQChannel = CAN3_TX_IRQn; - NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00; - NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00; - NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStruct); + if (NULL != g_tx_end[1]) { + CAN_ITConfig(CAN3, CAN_IT_TME, ENABLE); + nvic_init_struct.NVIC_IRQChannel = CAN3_TX_IRQn; + nvic_init_struct.NVIC_IRQChannelPreemptionPriority = 0x00; + nvic_init_struct.NVIC_IRQChannelSubPriority = 0x00; + nvic_init_struct.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&nvic_init_struct); } } /** * @brief Transmits the data onto the CAN bus with the specified id - * @param id : Message of ID. Also indicates the priority of message. The lower the value, the higher the priority. + * @param id : Message of ID. Also indicates the priority of message. The + * lower the value, the higher the priority. * @param data : data to be transmitted. The max is 8 bytes. - * @param length : num of bytes of data to be transmitted. This must be <= 8 bytes or else the rest of the message is dropped. - * @return ERROR if module was unable to transmit the data onto the CAN bus. SUCCESS indicates data was transmitted. + * @param length : num of bytes of data to be transmitted. This must be <= 8 + * bytes or else the rest of the message is dropped. + * @return ERROR if module was unable to transmit the data onto the CAN bus. + * SUCCESS indicates data was transmitted. */ -ErrorStatus BSP_CAN_Write(CAN_t bus, uint32_t id, uint8_t data[8], uint8_t length) -{ - - memset(gTxMessage[bus].Data, 0, sizeof gTxMessage[bus].Data); - gTxMessage[bus].StdId = id; - gTxMessage[bus].DLC = length; - for (int i = 0; i < length; i++) - { - gTxMessage[bus].Data[i] = data[i]; +ErrorStatus BspCanWrite(Can bus, uint32_t id, + const uint8_t data[BSP_CAN_DATA_LENGTH], + uint8_t length) { + memset(g_tx_message[bus].Data, 0, sizeof g_tx_message[bus].Data); + g_tx_message[bus].StdId = id; + g_tx_message[bus].DLC = length; + for (int i = 0; i < length; i++) { + g_tx_message[bus].Data[i] = data[i]; } - uint8_t retVal = (CAN_Transmit(bus == CAN_1 ? CAN1 : CAN3, &gTxMessage[bus]) != 0); - if (retVal == CAN_TxStatus_NoMailBox) - { + uint8_t ret_val = + (CAN_Transmit(bus == kCan1 ? CAN1 : CAN3, &g_tx_message[bus]) != 0); + if (ret_val == CAN_TxStatus_NoMailBox) { return ERROR; } return SUCCESS; @@ -361,24 +398,23 @@ ErrorStatus BSP_CAN_Write(CAN_t bus, uint32_t id, uint8_t data[8], uint8_t lengt * @note Non-blocking statement * @pre The data parameter must be at least 8 bytes or hardfault may occur. * @param id : pointer to store id of the message that was received. - * @param data : pointer to store data that was received. Must be 8bytes or bigger. - * @return ERROR if nothing was received so ignore id and data that was received. SUCCESS indicates data was received and stored. + * @param data : pointer to store data that was received. Must be 8bytes or + * bigger. + * @return ERROR if nothing was received so ignore id and data that was + * received. SUCCESS indicates data was received and stored. */ -ErrorStatus BSP_CAN_Read(CAN_t bus, uint32_t *id, uint8_t *data) -{ +ErrorStatus BspCanRead(Can bus, uint32_t* id, uint8_t* data) { // If the queue is empty, return err - if (msg_queue_is_empty(&gRxQueue[bus])) - { + if (MsgQueueIsEmpty(&g_rx_queue[bus])) { return ERROR; } // Get the message - msg_t msg; - msg_queue_get(&gRxQueue[bus], &msg); + Msg msg; + MsgQueueGet(&g_rx_queue[bus], &msg); // Transfer the message to the provided pointers - for (int i = 0; i < 8; i++) - { + for (int i = 0; i < BSP_CAN_DATA_LENGTH; i++) { // NOLINT data[i] = msg.data[i]; } *id = msg.id; @@ -386,80 +422,69 @@ ErrorStatus BSP_CAN_Read(CAN_t bus, uint32_t *id, uint8_t *data) return SUCCESS; } -void CAN3_RX0_IRQHandler() -{ +void Can3RX0IrqHandler() { CPU_SR_ALLOC(); CPU_CRITICAL_ENTER(); OSIntEnter(); CPU_CRITICAL_EXIT(); // Take any pending messages into a queue - while (CAN_MessagePending(CAN3, CAN_FIFO0)) - { - CAN_Receive(CAN3, CAN_FIFO0, &gRxMessage[1]); + while (CAN_MessagePending(CAN3, CAN_FIFO0)) { + CAN_Receive(CAN3, CAN_FIFO0, &g_rx_message[1]); - msg_t rxMsg; - rxMsg.id = gRxMessage[1].StdId; - memcpy(&rxMsg.data[0], gRxMessage[1].Data, 8); + Msg rx_msg; + rx_msg.id = g_rx_message[1].StdId; + memcpy(&rx_msg.data[0], g_rx_message[1].Data, BSP_CAN_DATA_LENGTH); // Place the message in the queue - if (msg_queue_put(&gRxQueue[1], rxMsg)) - { + if (MsgQueuePut(&g_rx_queue[1], rx_msg)) { // If the queue was not already full... // Call the driver-provided function, if it is not null - if (gRxEvent[1] != NULL) - { - gRxEvent[1](); + if (g_rx_event[1] != NULL) { + g_rx_event[1](); } - } - else - { - // If the queue is already full, then we can't really do anything else + } else { + // If the queue is already full, then we can't really do anything + // else break; } } - OSIntExit(); // Signal to uC/OS + OSIntExit(); // Signal to uC/OS } -void CAN1_RX0_IRQHandler(void) -{ +void Can1RX0IrqHandler(void) { CPU_SR_ALLOC(); CPU_CRITICAL_ENTER(); OSIntEnter(); CPU_CRITICAL_EXIT(); // Take any pending messages into a queue - while (CAN_MessagePending(CAN1, CAN_FIFO0)) - { - CAN_Receive(CAN1, CAN_FIFO0, &gRxMessage[0]); + while (CAN_MessagePending(CAN1, CAN_FIFO0)) { + CAN_Receive(CAN1, CAN_FIFO0, &g_rx_message[0]); - msg_t rxMsg; - rxMsg.id = gRxMessage[0].StdId; - memcpy(&rxMsg.data[0], gRxMessage[0].Data, 8); + Msg rx_msg; + rx_msg.id = g_rx_message[0].StdId; + memcpy(&rx_msg.data[0], g_rx_message[0].Data, BSP_CAN_DATA_LENGTH); // Place the message in the queue - if (msg_queue_put(&gRxQueue[0], rxMsg)) - { + if (MsgQueuePut(&g_rx_queue[0], rx_msg)) { // If the queue was not already full... // Call the driver-provided function, if it is not null - if (gRxEvent[0] != NULL) - { - gRxEvent[0](); + if (g_rx_event[0] != NULL) { + g_rx_event[0](); } - } - else - { - // If the queue is already full, then we can't really do anything else + } else { + // If the queue is already full, then we can't really do anything + // else break; } } - OSIntExit(); // Signal to uC/OS + OSIntExit(); // Signal to uC/OS } -void CAN3_TX_IRQHandler(void) -{ +void Can3TxIrqHandler(void) { CPU_SR_ALLOC(); CPU_CRITICAL_ENTER(); OSIntEnter(); @@ -469,20 +494,19 @@ void CAN3_TX_IRQHandler(void) CAN_ClearFlag(CAN3, CAN_FLAG_RQCP0 | CAN_FLAG_RQCP1 | CAN_FLAG_RQCP2); // Call the function provided - gTxEnd[1](); + g_tx_end[1](); - OSIntExit(); // Signal to uC/OS + OSIntExit(); // Signal to uC/OS } -void CAN1_TX_IRQHandler(void) -{ +void Can1TxIrqHandler(void) { CPU_SR_ALLOC(); CPU_CRITICAL_ENTER(); OSIntEnter(); CPU_CRITICAL_EXIT(); // Call the function provided CAN_ClearFlag(CAN1, CAN_FLAG_RQCP0 | CAN_FLAG_RQCP1 | CAN_FLAG_RQCP2); - gTxEnd[0](); + g_tx_end[0](); - OSIntExit(); // Signal to uC/OS + OSIntExit(); // Signal to uC/OS } diff --git a/BSP/STM32F413/Src/BSP_GPIO.c b/BSP/STM32F413/Src/BSP_GPIO.c old mode 100755 new mode 100644 index ffd20a800..fe0eafa8f --- a/BSP/STM32F413/Src/BSP_GPIO.c +++ b/BSP/STM32F413/Src/BSP_GPIO.c @@ -1,110 +1,106 @@ /* Copyright (c) 2021 UT Longhorn Racing Solar */ #include "BSP_GPIO.h" + #include "Tasks.h" +#include "common.h" -static GPIO_TypeDef* GPIO_GetPort(port_t port){ - const GPIO_TypeDef* gpio_mapping[4] = {GPIOA, GPIOB, GPIOC, GPIOD}; +#define NUM_PORTS 4 - return (GPIO_TypeDef *) gpio_mapping[port]; +static GPIO_TypeDef *gpioGetPort(Port port) { + const GPIO_TypeDef *gpio_mapping[NUM_PORTS] = {GPIOA, GPIOB, GPIOC, GPIOD}; + return (GPIO_TypeDef *)gpio_mapping[port]; } - /** * @brief Initializes a GPIO port * @param port - port to initialize * @param mask - pins - * @param direction - input or output + * @param direction - input or output * @return None - */ - -void BSP_GPIO_Init(port_t port, uint16_t mask, direction_t direction){ - GPIO_InitTypeDef GPIO_InitStruct; - - RCC_AHB1PeriphClockCmd(1 << port, ENABLE); - // Configure the pins to be generic GPIO - GPIO_InitStruct.GPIO_Pin = mask; - GPIO_InitStruct.GPIO_Mode = direction ? GPIO_Mode_OUT : GPIO_Mode_IN; - GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; - GPIO_InitStruct.GPIO_Speed = GPIO_Low_Speed; - GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; // TODO: verify - - // Compute the offset for the port handle from the port passed in - GPIO_TypeDef *portHandle = GPIO_GetPort(port); + */ + +void BspGpioInit(Port port, uint16_t mask, Direction direction) { + GPIO_InitTypeDef gpio_init_struct; + + RCC_AHB1PeriphClockCmd(1 << port, ENABLE); + // Configure the pins to be generic GPIO + gpio_init_struct.GPIO_Pin = mask; + gpio_init_struct.GPIO_Mode = direction ? GPIO_Mode_OUT : GPIO_Mode_IN; + gpio_init_struct.GPIO_OType = GPIO_OType_PP; + gpio_init_struct.GPIO_Speed = GPIO_Low_Speed; + gpio_init_struct.GPIO_PuPd = GPIO_PuPd_NOPULL; // TODO: verify + + // Compute the offset for the port handle from the port passed in + GPIO_TypeDef *port_handle = gpioGetPort(port); // Initialize the GPIO - GPIO_Init(portHandle, &GPIO_InitStruct); + GPIO_Init(port_handle, &gpio_init_struct); } - /** * @brief Reads value of the specified port * @param port to read * @return data of the port - */ + */ -uint16_t BSP_GPIO_Read(port_t port){ - GPIO_TypeDef *gpio_port = GPIO_GetPort(port); +uint16_t BspGpioRead(Port port) { + GPIO_TypeDef *gpio_port = gpioGetPort(port); - return GPIO_ReadInputData(gpio_port); + return GPIO_ReadInputData(gpio_port); } - /** - * @brief Writes data to a specified port + * @brief Writes data to a specified port * @param port port to write to - * @param data data to write + * @param data data to write * @return None - */ + */ -void BSP_GPIO_Write(port_t port, uint16_t data){ - GPIO_TypeDef *gpio_port = GPIO_GetPort(port); +void BspGpioWrite(Port port, uint16_t data) { + GPIO_TypeDef *gpio_port = gpioGetPort(port); - GPIO_Write(gpio_port, data); + GPIO_Write(gpio_port, data); } - /** - * @brief Reads data from a specified input pin (not applicable to output pins) + * @brief Reads data from a specified input pin (not applicable to output + * pins) * @param port The port to read from - * @param pin The pin to read from + * @param pin The pin to read from * @return State of the pin - */ + */ -uint8_t BSP_GPIO_Read_Pin(port_t port, uint16_t pinmask){ - GPIO_TypeDef *gpio_port = GPIO_GetPort(port); +uint8_t BspGpioReadPin(Port port, uint16_t pin_mask) { + GPIO_TypeDef *gpio_port = gpioGetPort(port); - return GPIO_ReadInputDataBit(gpio_port, pinmask); + return GPIO_ReadInputDataBit(gpio_port, pin_mask); } - - /** * @brief Writes data to a specified pin * @param port The port to write to - * @param pin The pin to write to + * @param pin The pin to write to * @param state true=ON or false=OFF * @return None - */ + */ -void BSP_GPIO_Write_Pin(port_t port, uint16_t pinmask, bool state){ - GPIO_TypeDef *gpio_port = GPIO_GetPort(port); - GPIO_WriteBit(gpio_port, pinmask, (state==ON)?Bit_SET:Bit_RESET); +void BspGpioWritePin(Port port, uint16_t pin_mask, bool state) { + GPIO_TypeDef *gpio_port = gpioGetPort(port); + GPIO_WriteBit(gpio_port, pin_mask, (state == ON) ? Bit_SET : Bit_RESET); } - - /** * @brief Returns state of output pin (not applicable to input pins) * @param port The port to get state from * @param pin The pin to get state from * @return 1 if pin is high, 0 if low - */ + */ -uint8_t BSP_GPIO_Get_State(port_t port, uint16_t pin){ - GPIO_TypeDef *gpio_port = GPIO_GetPort(port); +uint8_t BspGpioGetState(Port port, uint16_t pin) { + GPIO_TypeDef *gpio_port = gpioGetPort(port); - return GPIO_ReadOutputDataBit(gpio_port, pin); + return GPIO_ReadOutputDataBit(gpio_port, pin); } diff --git a/BSP/STM32F413/Src/BSP_SPI.c b/BSP/STM32F413/Src/BSP_SPI.c deleted file mode 100644 index 32e8fd4c1..000000000 --- a/BSP/STM32F413/Src/BSP_SPI.c +++ /dev/null @@ -1,251 +0,0 @@ -/* Copyright (c) 2020 UT Longhorn Racing Solar */ - -#include "BSP_SPI.h" -#include "stm32f4xx.h" -#include "os.h" - -#define SPI_PORT SPI1 - -// These are the sizes of the fifos. -// You can write/read more than this at once, -// but performance will degrade slightly. -#define TX_SIZE 128 -#define RX_SIZE 64 - -#define FIFO_TYPE uint8_t -#define FIFO_SIZE TX_SIZE -#define FIFO_NAME txfifo -#include "fifo.h" - -#define FIFO_TYPE uint8_t -#define FIFO_SIZE RX_SIZE -#define FIFO_NAME rxfifo -#include "fifo.h" - -static txfifo_t spiTxFifo; -static rxfifo_t spiRxFifo; - -static OS_SEM SPI_Update_Sem4; - -static void spi_post(void) { - OS_ERR err; - OSSemPost(&SPI_Update_Sem4, OS_OPT_POST_1, &err); - // TODO: error handling -} - -static void spi_pend(void) { - OS_ERR err; - CPU_TS ts; - OSSemPend(&SPI_Update_Sem4, 0, OS_OPT_PEND_BLOCKING, &ts, &err); - // TODO: error handling -} - -// Use this inline function to wait until SPI communication is complete -static inline void SPI_Wait(void) { - while((SPI1->SR & (SPI_SR_TXE | SPI_SR_RXNE)) == 0 || (SPI1->SR & SPI_SR_BSY)); -} - -// Use this inline function to wait until SPI communication is complete -static inline void SPI_WaitTx(void) { - SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, ENABLE); - spi_pend(); -} - -/** SPI_WriteRead - * @brief Sends and receives a byte of data on the SPI line. - * @param txData single byte that will be sent to the device. - * @return rxData single byte that was read from the device. - */ -static uint8_t SPI_WriteRead(uint8_t txData){ - - SPI_TypeDef *bus = SPI_PORT; - - SPI_Wait(); - bus->DR = txData & 0x00FF; - SPI_Wait(); - return bus->DR & 0x00FF; -} - - -/** - * @brief Initializes the SPI port. - * @return None - */ -void BSP_SPI_Init(void) { - - OS_ERR err; - OSSemCreate(&SPI_Update_Sem4, "SPI Update", 0, &err); - - spiTxFifo = txfifo_new(); - spiRxFifo = rxfifo_new(); - - GPIO_InitTypeDef GPIO_InitStruct; - SPI_InitTypeDef SPI_InitStruct; - - - - // SPI configuration: - // speed : 125kbps - // CPOL : 1 (polarity of clock during idle is high) - // CPHA : 1 (tx recorded during 2nd edge) - // Pins: - // SPI1: - // PA5 : SCK - // PA6 : MISO - // PA7 : MOSI - // PA4 : CS - - // Initialize clocks - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); - RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); - - // Initialize pins - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); - - // Initialize SPI port - SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; - SPI_InitStruct.SPI_Mode = SPI_Mode_Master; - SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; - SPI_InitStruct.SPI_CPOL = SPI_CPOL_High; - SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge; - SPI_InitStruct.SPI_NSS = SPI_NSS_Soft; - SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; - SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; - SPI_InitStruct.SPI_CRCPolynomial = 0; - SPI_Init(SPI1, &SPI_InitStruct); - SPI_Cmd(SPI1, ENABLE); - - // Initialize CS pin - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - // Configure SPI1 interrupt priority - NVIC_InitTypeDef NVIC_InitStruct; - NVIC_InitStruct.NVIC_IRQChannel = SPI1_IRQn; - NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; - NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; - NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStruct); - - // Enable the Rx buffer not empty interrupt - SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE); -} - -/** - * @brief Transmits data to through SPI. - * @note Blocking statement - * @param txBuf data array that contains the data to be sent. - * @param txLen length of data array. - * @return None - * Do not call from an ISR - */ -void BSP_SPI_Write(uint8_t *txBuf, uint8_t txLen) { - // If we're below an experimentally-determined value, just use polling - if(txLen < 8) { - for(int i = 0; i < txLen; i++) { - SPI_WriteRead(txBuf[i]); - } - } else { - // If we have a lot of data, we use interrupts to mitigate it - // Fill as much of the fifo as possible - size_t i = 0; - while(i < txLen) { - // Put as much data into the fifo as can fit - while(i < txLen && txfifo_put(&spiTxFifo, txBuf[i])) { - i++; - } - - // Wait for the transmission to complete - SPI_WaitTx(); - } - - SPI_Wait(); - } -} - -/** - * @brief Gets the data from SPI. - * @note Blocking statement - * @param rxBuf data array to store the data that is received. - * @param rxLen length of data array. - * @return None - * Do not call from an ISR - */ -void BSP_SPI_Read(uint8_t *rxBuf, uint8_t rxLen) { - - // If we have only a little amount of data, just use polling - if(rxLen < 8) { - for(int i = 0; i < rxLen; i++) { - rxBuf[i] = SPI_WriteRead(0x00); - } - } else { - SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE); - // Fill the fifo with zeros to read - size_t i = 0, r = 0; - // Empty the fifo - rxfifo_renew(&spiRxFifo); - // Read the data - while(i < rxLen) { - // Keep filling the fifo with data until we have read everything - while(i < rxLen && txfifo_put(&spiTxFifo, 0)) { - i++; - } - - // Wait for the transmission to complete - SPI_WaitTx(); - - // Busy wait the last bit, just to ensure all bytes have been received - SPI_Wait(); - - // Copy the data out of the fifo - while(r < i && rxfifo_get(&spiRxFifo, &rxBuf[r])) { - r++; - } - } - SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, DISABLE); - } -} - - -void SPI1_IRQHandler(){ - // Save the CPU registers - CPU_SR_ALLOC(); - - // Protect a critical section - CPU_CRITICAL_ENTER(); - - // make the kernel aware that the interrupt has started - OSIntEnter(); - CPU_CRITICAL_EXIT(); - - // Handle the interrupts - if (SPI_I2S_GetITStatus(SPI1, SPI_I2S_IT_TXE) == SET){ - // Check to see if there is any data awaiting transmission - if(!txfifo_get(&spiTxFifo, (uint8_t*)&SPI1->DR)) { - // We are out of data, so turn off the interrupt and post the semaphore - SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, DISABLE); - spi_post(); - } - } - if (SPI_I2S_GetITStatus(SPI1, SPI_I2S_IT_RXNE) == SET){ - // Get the incoming data, put it in the fifo - // If this overflows, it's the user's fault. - rxfifo_put(&spiRxFifo, SPI1->DR); - } - - //make the kernel aware that the interrupt has ended - OSIntExit(); -} diff --git a/BSP/STM32F413/Src/BSP_Switches.c b/BSP/STM32F413/Src/BSP_Switches.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/BSP/STM32F413/Src/BSP_UART.c b/BSP/STM32F413/Src/BSP_UART.c index b7ed87423..35aa67122 100644 --- a/BSP/STM32F413/Src/BSP_UART.c +++ b/BSP/STM32F413/Src/BSP_UART.c @@ -1,323 +1,344 @@ /* Copyright (c) 2020 UT Longhorn Racing Solar */ #include "BSP_UART.h" -#include "stm32f4xx.h" + #include "os.h" +#include "stm32f4xx.h" -#define TX_SIZE 128 -#define RX_SIZE 64 +#define TX_SIZE 128 +#define RX_SIZE 64 +#define NUM_USART 2 // Initialize the FIFOs #define FIFO_TYPE char #define FIFO_SIZE TX_SIZE -#define FIFO_NAME txfifo +#define FIFO_NAME TxFifo #include "fifo.h" -static txfifo_t usbTxFifo; -static txfifo_t displayTxFifo; +static TxFifo usb_tx_fifo; +static TxFifo display_tx_fifo; #define FIFO_TYPE char #define FIFO_SIZE RX_SIZE -#define FIFO_NAME rxfifo +#define FIFO_NAME RxFifo #include "fifo.h" -static rxfifo_t usbRxFifo; -static rxfifo_t displayRxFifo; +static RxFifo usb_rx_fifo; +static RxFifo display_rx_fifo; -static bool usbLineReceived = false; -static bool displayLineReceived = false; +static bool usb_line_received = false; +static bool display_line_received = false; -static callback_t usbRxCallback = NULL; -static callback_t usbTxCallback = NULL; -static callback_t displayRxCallback = NULL; -static callback_t displayTxCallback = NULL; +static Callback usb_rx_callback = NULL; +static Callback usb_tx_callback = NULL; +static Callback display_rx_callback = NULL; +static Callback display_tx_callback = NULL; -static rxfifo_t *rx_fifos[NUM_UART] = {&usbRxFifo, &displayRxFifo}; -static txfifo_t *tx_fifos[NUM_UART] = {&usbTxFifo, &displayTxFifo}; -static bool *lineRecvd[NUM_UART] = {&usbLineReceived, &displayLineReceived}; -static USART_TypeDef *handles[NUM_UART] = {USART2, USART3}; +static RxFifo *rx_fifos[NUM_USART] = {&usb_rx_fifo, &display_rx_fifo}; +static TxFifo *tx_fifos[NUM_USART] = {&usb_tx_fifo, &display_tx_fifo}; +static bool *line_recvd_global[NUM_USART] = {&usb_line_received, + &display_line_received}; +static USART_TypeDef *handles[NUM_USART] = {USART2, USART3}; -static void USART_DISPLAY_Init() { - displayTxFifo = txfifo_new(); - displayRxFifo = rxfifo_new(); +static void usartDisplayInit() { + display_tx_fifo = TxFifoNew(); + display_rx_fifo = RxFifoNew(); - GPIO_InitTypeDef GPIO_InitStruct = {0}; - USART_InitTypeDef UART_InitStruct = {0}; + GPIO_InitTypeDef gpio_init_struct = {0}; + USART_InitTypeDef usart_init_struct = {0}; // Initialize clocks - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); // Initialize pins - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; - GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_25MHz; - GPIO_Init(GPIOB, &GPIO_InitStruct); - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; - GPIO_Init(GPIOC, &GPIO_InitStruct); + gpio_init_struct.GPIO_Pin = GPIO_Pin_10; + gpio_init_struct.GPIO_Mode = GPIO_Mode_AF; + gpio_init_struct.GPIO_OType = GPIO_OType_PP; + gpio_init_struct.GPIO_PuPd = GPIO_PuPd_UP; + gpio_init_struct.GPIO_Speed = GPIO_Speed_25MHz; + GPIO_Init(GPIOB, &gpio_init_struct); + gpio_init_struct.GPIO_Pin = GPIO_Pin_5; + GPIO_Init(GPIOC, &gpio_init_struct); GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_USART3); - //Initialize UART3 - UART_InitStruct.USART_BaudRate = 115200; - UART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - UART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; - UART_InitStruct.USART_Parity = USART_Parity_No; - UART_InitStruct.USART_StopBits = USART_StopBits_1; - UART_InitStruct.USART_WordLength = USART_WordLength_8b; - USART_Init(USART3, &UART_InitStruct); + // Initialize USART3 + usart_init_struct.USART_BaudRate = 115200; // NOLINT + usart_init_struct.USART_HardwareFlowControl = + USART_HardwareFlowControl_None; + usart_init_struct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; + usart_init_struct.USART_Parity = USART_Parity_No; + usart_init_struct.USART_StopBits = USART_StopBits_1; + usart_init_struct.USART_WordLength = USART_WordLength_8b; + USART_Init(USART3, &usart_init_struct); // Enable interrupts USART_Cmd(USART3, ENABLE); // Enable NVIC - NVIC_InitTypeDef NVIC_InitStructure; - NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); + NVIC_InitTypeDef nvic_init_structure; + nvic_init_structure.NVIC_IRQChannel = USART3_IRQn; + nvic_init_structure.NVIC_IRQChannelPreemptionPriority = 1; + nvic_init_structure.NVIC_IRQChannelSubPriority = 0; + nvic_init_structure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&nvic_init_structure); } -static void USART_USB_Init() { - usbTxFifo = txfifo_new(); - usbRxFifo = rxfifo_new(); +static void usartUsbInit() { + usb_tx_fifo = TxFifoNew(); + usb_rx_fifo = RxFifoNew(); - GPIO_InitTypeDef GPIO_InitStruct = {0}; - USART_InitTypeDef UART_InitStruct = {0}; + GPIO_InitTypeDef gpio_init_struct = {0}; + USART_InitTypeDef usart_init_struct = {0}; // Initialize clocks RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // Initialize pins - GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; - GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStruct.GPIO_Speed = GPIO_Speed_25MHz; - GPIO_Init(GPIOA, &GPIO_InitStruct); + gpio_init_struct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; + gpio_init_struct.GPIO_Mode = GPIO_Mode_AF; + gpio_init_struct.GPIO_OType = GPIO_OType_PP; + gpio_init_struct.GPIO_PuPd = GPIO_PuPd_UP; + gpio_init_struct.GPIO_Speed = GPIO_Speed_25MHz; + GPIO_Init(GPIOA, &gpio_init_struct); GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); - //Initialize UART2 - UART_InitStruct.USART_BaudRate = 115200; - UART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - UART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; - UART_InitStruct.USART_Parity = USART_Parity_No; - UART_InitStruct.USART_StopBits = USART_StopBits_1; - UART_InitStruct.USART_WordLength = USART_WordLength_8b; - USART_Init(USART2, &UART_InitStruct); + // Initialize USART2 + usart_init_struct.USART_BaudRate = 115200; // NOLINT + usart_init_struct.USART_HardwareFlowControl = + USART_HardwareFlowControl_None; + usart_init_struct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; + usart_init_struct.USART_Parity = USART_Parity_No; + usart_init_struct.USART_StopBits = USART_StopBits_1; + usart_init_struct.USART_WordLength = USART_WordLength_8b; + USART_Init(USART2, &usart_init_struct); USART_Cmd(USART2, ENABLE); // Enable NVIC - NVIC_InitTypeDef NVIC_InitStructure; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); + NVIC_InitTypeDef nvic_init_structure; + nvic_init_structure.NVIC_IRQChannelPreemptionPriority = 1; + nvic_init_structure.NVIC_IRQChannelSubPriority = 0; + nvic_init_structure.NVIC_IRQChannel = USART2_IRQn; + nvic_init_structure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&nvic_init_structure); setvbuf(stdout, NULL, _IONBF, 0); } /** - * @brief Initializes the UART peripheral + * @brief Initializes the USART peripheral */ -static void BSP_UART_Init_Internal(callback_t rxCallback, callback_t txCallback, UART_t uart) { - switch(uart){ - case UART_2: // their UART_USB - USART_USB_Init(); - usbRxCallback = rxCallback; - usbTxCallback = txCallback; - break; - case UART_3: // their UART_DISPLAY - USART_DISPLAY_Init(); - displayRxCallback = rxCallback; - displayTxCallback = txCallback; - break; - default: - // Error - break; +static void bspUartInitInternal(Callback rx_callback, Callback tx_callback, + Uart usart) { + switch (usart) { + case kUart2: // their USART_USB + usartUsbInit(); + usb_rx_callback = rx_callback; + usb_tx_callback = tx_callback; + break; + case kUart3: // their USART_DISPLAY + usartDisplayInit(); + display_rx_callback = rx_callback; + display_tx_callback = tx_callback; + break; + default: + // Error + break; } } -void BSP_UART_Init(UART_t uart) { +void BspUartInit(Uart usart) { // Not using callbacks for now - BSP_UART_Init_Internal(NULL, NULL, uart); + bspUartInitInternal(NULL, NULL, usart); } /** - * @brief Gets one line of ASCII text that was received. The '\n' and '\r' characters will not be stored (tested on Putty on Windows) + * @brief Gets one line of ASCII text that was received. The '\n' and '\r' + * characters will not be stored (tested on Putty on Windows) * @pre str should be at least 128bytes long. - * @param str : pointer to buffer to store the string. This buffer should be initialized - * before hand. + * @param str : pointer to buffer to store the string. This buffer should be + * initialized before hand. * @param usart : which usart to read from (2 or 3) * @return number of bytes that was read */ -uint32_t BSP_UART_Read(UART_t usart, char *str) { +uint32_t BspUartRead(Uart usart, char *str) { char data = 0; uint32_t recvd = 0; - bool *line_recvd = lineRecvd[usart]; - - while(*line_recvd == false){ - BSP_UART_Write(usart, "", 0); // needs to be in. Otherwise, usbLineReceived will not update + bool *line_recvd = line_recvd_global[usart]; + + while (*line_recvd == false) { + BspUartWrite( + usart, "", + 0); // needs to be in. Otherwise, usbLineReceived will not update } USART_TypeDef *usart_handle = handles[usart]; - USART_ITConfig(usart_handle, USART_IT_RXNE, RESET); - - rxfifo_t *fifo = rx_fifos[usart]; - - rxfifo_peek(fifo, &data); - while(!rxfifo_is_empty(fifo) && data != '\r') { - recvd += rxfifo_get(fifo, (char*)str++); - rxfifo_peek(fifo, &data); + USART_ITConfig(usart_handle, USART_IT_RXNE, (FunctionalState)RESET); + + RxFifo *fifo = rx_fifos[usart]; + + RxFifoPeek(fifo, &data); + while (!RxFifoIsEmpty(fifo) && data != '\r') { + recvd += RxFifoGet(fifo, (char *)str++); + RxFifoPeek(fifo, &data); } - rxfifo_get(fifo, &data); + RxFifoGet(fifo, &data); *str = 0; *line_recvd = false; - USART_ITConfig(usart_handle, USART_IT_RXNE, SET); + USART_ITConfig(usart_handle, USART_IT_RXNE, (FunctionalState)SET); return recvd; } /** - * @brief Transmits data to through UART line + * @brief Transmits data to through USART line * @param str : pointer to buffer with data to send. * @param len : size of buffer * @param usart : which usart to read from (2 or 3) * @return number of bytes that were sent - * + * * @note This function uses a fifo to buffer the write. If that * fifo is full, this function may block while waiting for * space to open up. Do not call from timing-critical * sections of code. */ -uint32_t BSP_UART_Write(UART_t usart, char *str, uint32_t len) { +uint32_t BspUartWrite(Uart usart, char *str, uint32_t len) { uint32_t sent = 0; USART_TypeDef *usart_handle = handles[usart]; - USART_ITConfig(usart_handle, USART_IT_TC, RESET); + USART_ITConfig(usart_handle, USART_IT_TC, (FunctionalState)RESET); - txfifo_t *fifo = tx_fifos[usart]; + TxFifo *fifo = tx_fifos[usart]; - while(sent < len) { - if(!txfifo_put(fifo, str[sent])) { + while (sent < len) { + if (!TxFifoPut(fifo, str[sent])) { // Allow the interrupt to fire - USART_ITConfig(usart_handle, USART_IT_TC, SET); + USART_ITConfig(usart_handle, USART_IT_TC, (FunctionalState)SET); // Wait for space to open up - while(txfifo_is_full(fifo)); + while (TxFifoIsFull(fifo)) { + ; + } // Disable the interrupt again - USART_ITConfig(usart_handle, USART_IT_TC, RESET); + USART_ITConfig(usart_handle, USART_IT_TC, (FunctionalState)RESET); } else { - sent++; + sent++; } } - USART_ITConfig(usart_handle, USART_IT_TC, SET); + USART_ITConfig(usart_handle, USART_IT_TC, (FunctionalState)SET); return sent; } -void USART2_IRQHandler(void) { +void UsarT2IrqHandler(void) { CPU_SR_ALLOC(); CPU_CRITICAL_ENTER(); OSIntEnter(); CPU_CRITICAL_EXIT(); - if(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET) { + if (USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET) { uint8_t data = USART2->DR; - bool removeSuccess = 1; - if(data == '\r' || data == '\n'){ - usbLineReceived = true; - if(usbRxCallback != NULL) - usbRxCallback(); + bool remove_success = 1; + if (data == '\r' || data == '\n') { + usb_line_received = true; + if (usb_rx_callback != NULL) { + usb_rx_callback(); + } } // Check if it was a backspace. // '\b' for minicmom // '\177' for putty - else if(data != '\b' && data != '\177') { - rxfifo_put(&usbRxFifo, data); + else if (data != '\b' && data != '\177') { + RxFifoPut(&usb_rx_fifo, (char)data); } // Sweet, just a "regular" key. Put it into the fifo - // Doesn't matter if it fails. If it fails, then the data gets thrown away - // and the easiest solution for this is to increase RX_SIZE + // Doesn't matter if it fails. If it fails, then the data gets thrown + // away and the easiest solution for this is to increase RX_SIZE else { - char junk; + char junk = 0; // Delete the last entry! - removeSuccess = rxfifo_popback(&usbRxFifo, &junk); + remove_success = RxFifoPopBack(&usb_rx_fifo, &junk); - USART_SendData(UART_2, 0x7F); // TODO: Not sure if the backspace works. Need to test + USART_SendData(USART2, + 0x7F); // NOLINT + // TODO: Not sure if the backspace works. + // Need to test } - if(removeSuccess) { + if (remove_success) { USART2->DR = data; } } - if(USART_GetITStatus(USART2, USART_IT_TC) != RESET) { - // If getting data from fifo fails i.e. the tx fifo is empty, then turn off the TX interrupt - if(!txfifo_get(&usbTxFifo, (char*)&(USART2->DR))) { - USART_ITConfig(USART2, USART_IT_TC, RESET); // Turn off the interrupt - if(usbTxCallback != NULL) - usbTxCallback(); // Callback + if (USART_GetITStatus(USART2, USART_IT_TC) != RESET) { + // If getting data from fifo fails i.e. the tx fifo is empty, then turn + // off the TX interrupt + if (!TxFifoGet(&usb_tx_fifo, (char *)&(USART2->DR))) { + USART_ITConfig(USART2, USART_IT_TC, + (FunctionalState)RESET); // Turn off the interrupt + if (usb_tx_callback != NULL) { + usb_tx_callback(); // Callback + } } } - if(USART_GetITStatus(USART2, USART_IT_ORE) != RESET); - + if (USART_GetITStatus(USART2, USART_IT_ORE) != RESET) {} OSIntExit(); - } -void USART3_IRQHandler(void) { +void Usart3IrqHandler(void) { CPU_SR_ALLOC(); CPU_CRITICAL_ENTER(); OSIntEnter(); CPU_CRITICAL_EXIT(); - if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) { + if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) { uint8_t data = USART3->DR; - bool removeSuccess = 1; - if(data == '\r'){ - displayLineReceived = true; - if(displayRxCallback != NULL) - displayRxCallback(); + bool remove_success = 1; + if (data == '\r') { + display_line_received = true; + if (display_rx_callback != NULL) { + display_rx_callback(); + } } // Check if it was a backspace. // '\b' for minicmom // '\177' for putty - if(data != '\b' && data != '\177') rxfifo_put(&displayRxFifo, data); - // Sweet, just a "regular" key. Put it into the fifo - // Doesn't matter if it fails. If it fails, then the data gets thrown away - // and the easiest solution for this is to increase RX_SIZE - else { - char junk; + if (data != '\b' && data != '\177') { + RxFifoPut(&display_rx_fifo, (char)data); + // Sweet, just a "regular" key. Put it into the fifo + // Doesn't matter if it fails. If it fails, then the data gets + // thrown away and the easiest solution for this is to increase + // RX_SIZE + } else { + char junk = 0; // Delete the last entry! - removeSuccess = rxfifo_popback(&displayRxFifo, &junk); + remove_success = RxFifoPopBack(&display_rx_fifo, &junk); } - if(removeSuccess) { + if (remove_success) { USART3->DR = data; } } - if(USART_GetITStatus(USART3, USART_IT_TC) != RESET) { - // If getting data from fifo fails i.e. the tx fifo is empty, then turn off the TX interrupt - if(!txfifo_get(&displayTxFifo, (char*)&(USART3->DR))) { - USART_ITConfig(USART3, USART_IT_TC, RESET); - if(displayTxCallback != NULL) - displayTxCallback(); + if (USART_GetITStatus(USART3, USART_IT_TC) != RESET) { + // If getting data from fifo fails i.e. the tx fifo is empty, then turn + // off the TX interrupt + if (!TxFifoGet(&display_tx_fifo, (char *)&(USART3->DR))) { + USART_ITConfig(USART3, USART_IT_TC, (FunctionalState)RESET); + if (display_tx_callback != NULL) { + display_tx_callback(); + } } } - if(USART_GetITStatus(USART3, USART_IT_ORE) != RESET); + if (USART_GetITStatus(USART3, USART_IT_ORE) != RESET) {} OSIntExit(); } diff --git a/BSP/STM32F413/Src/retarget.c b/BSP/STM32F413/Src/retarget.c index 305ffb46b..42c84db2b 100644 --- a/BSP/STM32F413/Src/retarget.c +++ b/BSP/STM32F413/Src/retarget.c @@ -1,35 +1,24 @@ /* Copyright (c) 2020 UT Longhorn Racing Solar */ -#include "common.h" #include "BSP_UART.h" +#include "common.h" -#define STDIN_FILENO 0 +#define STDIN_FILENO 0 #define STDOUT_FILENO 1 #define STDERR_FILENO 2 -int _write(int fd, char *buffer, unsigned int len) { - if(buffer != NULL) { - BSP_UART_Write(UART_2, buffer, len); +int _write(int fd, char *buffer, unsigned int len) { // NOLINT + if (buffer != NULL) { + BspUartWrite(kUart2, buffer, len); } - return len; + return (int)len; } -int _read(int const fd, char *buffer, unsigned const len) { - if(buffer != NULL) { - - } +int _read(int const fd, const char *buffer, unsigned const len) { // NOLINT + if (buffer != NULL) {} return 1; } -int _close(int file) -{ - return -1; -} - -int _lseek(int file, int ptr, int dir) -{ - return 0; -} - - +int _close(int file) { return -1; } // NOLINT +int _lseek(int file, int ptr, int dir) { return 0; } // NOLINT diff --git a/Drivers/Inc/CANbus.h b/Drivers/Inc/CANbus.h deleted file mode 100644 index fcc01383e..000000000 --- a/Drivers/Inc/CANbus.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar - * @file CANbus.h - * @brief - * - * @defgroup CANbus - * @addtogroup CANbus - * @{ - */ - -#ifndef CAN_H__ -#define CAN_H__ - -#include "BSP_CAN.h" - -#define CARCAN CAN_1 //convenience aliases for the CANBuses -#define MOTORCAN CAN_3 - -/** - * This enum is used to signify the ID of the message you want to send. - * It is used internally to index our lookup table (CANLUT.C) and get message-specific fields. - * For user purposes, it selects the message to send. - * - * If changing the order of this enum, make sure to mirror that change in the lookup table, or - * else the driver will not work properly. - * - * If adding new types of CAN messages, add the identifier wherever it fits in - * (the enum is sorted in ascending order on purpose), and then add an entry to the lookup table. - */ -typedef enum { - BPS_TRIP = 0x002, - BPS_CONTACTOR = 0x102, - STATE_OF_CHARGE = 0x106, - SUPPLEMENTAL_VOLTAGE = 0x10B, - MOTOR_DRIVE = 0x221, - MOTOR_POWER = 0x222, - MOTOR_RESET = 0x223, - MOTOR_STATUS = 0x241, - MC_BUS = 0x242, - VELOCITY = 0x243, - MC_PHASE_CURRENT = 0x244, - VOLTAGE_VEC = 0x245, - CURRENT_VEC = 0x246, - BACKEMF = 0x247, - TEMPERATURE = 0x24B, - ODOMETER_AMPHOURS = 0x24E, - ARRAY_CONTACTOR_STATE_CHANGE = 0x24F, - SLIP_SPEED = 0x257, - CONTROL_MODE = 0x580, - IO_STATE = 0x581, - MAX_CAN_ID -} CANId_t; - -/** - * @brief Struct to use in CAN MSG LUT - * @param idxEn Whether or not this message is part of a sequence of messages. - * @param size Size of message's data. Should be a maximum of eight (in decimal). - */ -typedef struct { - bool idxEn: 1; - unsigned int size: 7; -} CANLUT_T; - -/** - * Standard CAN packet - * @param ID CANId_t value indicating which message we are trying to send - * @param idx If message is part of a sequence of messages (for messages longer than 64 bits), this indicates the index of the message. - * This is not designed to exceed the 8bit unsigned max value. - * @param data data of the message -*/ -typedef struct { - CANId_t ID; - uint8_t idx; - uint8_t data[8]; -} CANDATA_t; - -/** - * Standard identifier for whether or not a CAN transaction is blocking or not - * (DEPRECATED) - */ -// typedef enum {CAN_BLOCKING=0, CAN_NON_BLOCKING} CAN_blocking_t; - -//Compatibility macros for deprecated enum -#define CAN_BLOCKING true -#define CAN_NON_BLOCKING false - - -/** - * @brief Initializes the CAN system for a given bus - * @param bus The bus to initialize. You can either use CAN_1, CAN_3, or the convenience macros CARCAN and MOTORCAN. CAN2 will not be supported. - * @param idWhitelist A list of CAN IDs that we want to receive. If NULL, we will receive all messages. - * @param idWhitelistSize The size of the whitelist. - * @return ERROR if bus != CAN1 or CAN3, SUCCESS otherwise - */ -ErrorStatus CANbus_Init(CAN_t bus, CANId_t* idWhitelist, uint8_t idWhitelistSize); - -/** - * @brief Transmits data onto the CANbus. Transmits up to 8 bytes at a time. If more is necessary, please use an IDX message. - * @param CanData The data to be transmitted - * @param blocking Whether or not this transmission should be a blocking send. - * @param bus The bus to transmit on. This should be either CARCAN or MOTORCAN. - * @return ERROR if data wasn't sent, otherwise it was sent. - */ -ErrorStatus CANbus_Send(CANDATA_t CanData,bool blocking, CAN_t bus); - -/** - * @brief Reads a CAN message from the CAN hardware and returns it to the provided pointers. - * @param data pointer to where to store the CAN id of the received msg - * @param blocking Whether or not this read should be a blocking read - * @param bus The bus to use. This should either be CARCAN or MOTORCAN. - * @returns ERROR if read failed, SUCCESS otherwise - */ -ErrorStatus CANbus_Read(CANDATA_t* data, bool blocking, CAN_t bus); - -#endif - - -/* @} */ diff --git a/Drivers/Inc/CanBus.h b/Drivers/Inc/CanBus.h new file mode 100644 index 000000000..49b397dfd --- /dev/null +++ b/Drivers/Inc/CanBus.h @@ -0,0 +1,121 @@ +/** + * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar + * @file CanBus.h + * @brief + * + * @defgroup CANbus + * @addtogroup CANbus + * @{ + */ + +#ifndef CAN_H +#define CAN_H + +#include "BSP_CAN.h" + +#define CARCAN kCan1 // convenience aliases for the CANBuses +#define MOTORCAN kCan3 + +/** + * This enum is used to signify the ID of the message you want to send. + * It is used internally to index our lookup table (kCanLut.C) and get + * message-specific fields. For user purposes, it selects the message to send. + * + * If changing the order of this enum, make sure to mirror that change in the + * lookup table, or else the driver will not work properly. + * + * If adding new types of CAN messages, add the identifier wherever it fits in + * (the enum is sorted in ascending order on purpose), and then add an entry to + * the lookup table. + */ +typedef enum { + kBpsTrip = 0x002, + kBpsContactor = 0x102, + kStateOfCharge = 0x106, + kSupplementalVoltage = 0x10B, + kMotorDrive = 0x221, + kMotorPower = 0x222, + kMotorReset = 0x223, + kMotorStatus = 0x241, + kMcBus = 0x242, + kVelocity = 0x243, + kMcPhaseCurrent = 0x244, + kVoltageVec = 0x245, + kCurrentVec = 0x246, + kBackEmf = 0x247, + kTemperature = 0x24B, + kOdometerAmpHours = 0x24E, + kArrayContactorStateChange = 0x24F, + kSlipSpeed = 0x257, + kControlMode = 0x580, + kIoState = 0x581, + kMaxCanId +} CanId; + +/** + * @brief Struct to use in CAN MSG LUT + * @param idxEn Whether or not this message is part of a sequence of messages. + * @param size Size of message's data. Should be a maximum of eight (in + * decimal). + */ +typedef struct { + bool idx_en : 1; + unsigned int size : 7; +} CanLut; + +/** + * Standard CAN packet + * @param ID CanId value indicating which message we are trying to send + * @param idx If message is part of a sequence of messages (for messages + * longer than 64 bits), this indicates the index of the message. This is not + * designed to exceed the 8bit unsigned max value. + * @param data data of the message + */ +typedef struct { + CanId id; + uint8_t idx; + uint8_t data[BSP_CAN_DATA_LENGTH]; +} CanData; + +// Compatibility macros for deprecated enum +#define CAN_BLOCKING true +#define CAN_NON_BLOCKING false + +/** + * @brief Initializes the CAN system for a given bus + * @param bus The bus to initialize. You can either use CAN_1, CAN_3, or the + * convenience macros CARCAN and MOTORCAN. CAN2 will not be supported. + * @param idWhitelist A list of CAN IDs that we want to receive. If NULL, we + * will receive all messages. + * @param idWhitelistSize The size of the whitelist. + * @return ERROR if bus != CAN1 or CAN3, SUCCESS otherwise + */ +ErrorStatus CanBusInit(Can bus, CanId* id_whitelist, uint8_t id_whitelist_size); + +/** + * @brief Transmits data onto the CANbus. Transmits up to 8 bytes at a time. + * If more is necessary, please use an IDX message. + * @param CanData The data to be transmitted + * @param blocking Whether or not this transmission should be a + * blocking send. + * @param bus The bus to transmit on. This should be + * either CARCAN or MOTORCAN. + * @return ERROR if data wasn't sent, otherwise it was sent. + */ +ErrorStatus CanBusSend(CanData can_data, bool blocking, Can bus); + +/** + * @brief Reads a CAN message from the CAN hardware and returns it to the + * provided pointers. + * @param data pointer to where to store the CAN id of the + * received msg + * @param blocking Whether or not this read should be a blocking read + * @param bus The bus to use. This should either be CARCAN or + * MOTORCAN. + * @returns ERROR if read failed, SUCCESS otherwise + */ +ErrorStatus CanBusRead(CanData* msg_container, bool blocking, Can bus); + +#endif + +/* @} */ diff --git a/Drivers/Inc/CANConfig.h b/Drivers/Inc/CanConfig.h similarity index 59% rename from Drivers/Inc/CANConfig.h rename to Drivers/Inc/CanConfig.h index 0035e2f37..609c45485 100644 --- a/Drivers/Inc/CANConfig.h +++ b/Drivers/Inc/CanConfig.h @@ -1,30 +1,30 @@ /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar - * @file CANConfig.h - * @brief - * + * @file CanConfig.h + * @brief + * * @defgroup CANConfig * @addtogroup CANConfig * @{ */ #ifndef CAN_CONFIG #define CAN_CONFIG -#include "CANbus.h" + +#include "CanBus.h" /** * Filter Lists for CarCAN and MotorCAN -*/ + */ #define NUM_CARCAN_FILTERS 4 #define NUM_MOTORCAN_FILTERS 7 -extern CANId_t carCANFilterList[NUM_CARCAN_FILTERS]; -extern CANId_t motorCANFilterList[NUM_MOTORCAN_FILTERS]; - +extern CanId car_can_filter_list[NUM_CARCAN_FILTERS]; +extern CanId motor_can_filter_list[NUM_MOTORCAN_FILTERS]; /** - * The lookup table containing the entries for all of our CAN messages. Located in CANLUT.c + * The lookup table containing the entries for all of our CAN messages. Located + * in kCanLut.c */ -extern const CANLUT_T CANLUT[MAX_CAN_ID]; +extern const CanLut kCanLut[kMaxCanId]; #endif - /* @} */ diff --git a/Drivers/Inc/Contactors.h b/Drivers/Inc/Contactors.h index 77cf7ec15..4d9b2aaac 100644 --- a/Drivers/Inc/Contactors.h +++ b/Drivers/Inc/Contactors.h @@ -1,63 +1,58 @@ /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file Contactors.h - * @brief - * + * @brief + * * @defgroup Contactors * @addtogroup Contactors * @{ */ -#ifndef __CONTACTORS_H -#define __CONTACTORS_H +#ifndef CONTACTORS_H +#define CONTACTORS_H +#include "BSP_GPIO.h" #include "common.h" #include "config.h" -#include "BSP_GPIO.h" -#include "stm32f4xx_gpio.h" - - -#define CONTACTORS_PORT PORTC -#define ARRAY_PRECHARGE_BYPASS_PIN GPIO_Pin_10 -#define MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN GPIO_Pin_12 - -#define FOREACH_contactor(contactor) \ - contactor(ARRAY_PRECHARGE_BYPASS_CONTACTOR), \ - contactor(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR), \ -typedef enum contactor_ENUM { - FOREACH_contactor(GENERATE_ENUM) - NUM_CONTACTORS, -}contactor_t; +#define CONTACTORS_PORT kPortC +#define ARRAY_PRECHARGE_BYPASS_PIN GPIO_Pin_10 +#define MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN GPIO_Pin_12 +#define FOREACH_CONTACTOR(contactor) \ + contactor(kArrayPrechargeBypassContactor), \ + contactor(kMotorControllerPrechargeBypassContactor), +typedef enum ContactorEnum { + FOREACH_CONTACTOR(GENERATE_ENUM) kNumContactors, +} Contactor; /** * @brief Initializes contactors to be used * in connection with the Motor and Array * @return None - */ -void Contactors_Init(); + */ +void ContactorsInit(); /** - * @brief Returns the current state of + * @brief Returns the current state of * a specified contactor * @param contactor the contactor - * (MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR/ARRAY_PRECHARGE_BYPASS_CONTACTOR) + * (kMotorControllerPrechargeBypassContactor/kArrayPrechargeBypassContactor) * @return The contactor's state (ON/OFF) - */ -bool Contactors_Get(contactor_t contactor); + */ +bool ContactorsGet(Contactor contactor); /** * @brief Sets the state of a specified contactor - * @param contactor the contactor (MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR/ARRAY_PRECHARGE_BYPASS_CONTACTOR) + * @param contactor the contactor + * (kMotorControllerPrechargeBypassContactor/kArrayPrechargeBypassContactor) * @param state the state to set (ON/OFF) (true/false) * @param blocking whether or not this should be a blocking call * @return Whether or not the contactor was successfully set */ -ErrorStatus Contactors_Set(contactor_t contactor, bool state, bool blocking); +ErrorStatus ContactorsSet(Contactor contactor, bool state, bool blocking); #endif - /* @} */ diff --git a/Drivers/Inc/Display.h b/Drivers/Inc/Display.h index b97048b26..2225f3a81 100644 --- a/Drivers/Inc/Display.h +++ b/Drivers/Inc/Display.h @@ -2,107 +2,103 @@ * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file Display.h * @brief Function prototypes for the display driver. - * + * * This contains function prototypes relevant to sending/receiving messages * to/from our Nextion HMI. - * + * * @defgroup Display * @addtogroup Display * @{ */ -#ifndef __DISPLAY_H -#define __DISPLAY_H +#ifndef DISPLAY_H +#define DISPLAY_H -#include "common.h" // common headers -#include "Tasks.h" // for os and fault error locs +#include "Tasks.h" // for os and fault error locs +#include "common.h" // common headers -#define MAX_ARGS 2 // maximum # of arguments in a command packet +#define DISPLAY_CMD_MAX_ARGS 2 // maximum # of arguments in a command packet /** * Error types */ -typedef enum{ // Currently only ERR_NONE and ERR_PARSE are used - DISPLAY_ERR_NONE, - DISPLAY_ERR_PARSE, // Error parsing command struct passed to Display_Send - DISPLAY_ERR_INV_INSTR, // Invalid instruction passed to nextion (0x00) - DISPLAY_ERR_INV_COMP, // Invalid component id passed to nextion (0x02) - DISPLAY_ERR_INV_PGID, // Invalid page id passed to nextion (0x03) - DISPLAY_ERR_INV_VAR, // Invalid variable name passed to nextion (0x1A) - DISPLAY_ERR_INV_VAROP, // Invalid variable operation passed to nextion (0x1B) - DISPLAY_ERR_ASSIGN, // Assignment failure nextion (0x1C) - DISPLAY_ERR_PARAMS, // Invalid number of parameters passed to nextion (0x1E) - DISPLAY_ERR_MAX_ARGS, // Command arg list exceeded MAX_ARGS elements - DISPLAY_ERR_OTHER // Other nextion display error -} DisplayError_t; - +typedef enum { // Currently only ERR_NONE and ERR_PARSE are used + kDisplayErrNone, + kDisplayErrParse, // Error parsing command struct passed to Display_Send + kDisplayErrInvInstr, // Invalid instruction passed to nextion (0x00) + kDisplayErrInvComp, // Invalid component id passed to nextion (0x02) + kDisplayErrInvPgid, // Invalid page id passed to nextion (0x03) + kDisplayErrInvVar, // Invalid variable name passed to nextion (0x1A) + kDisplayErrInvVarop, // Invalid variable operation passed to nextion + // (0x1B) + kDisplayErrAssign, // Assignment failure nextion (0x1C) + kDisplayErrParams, // Invalid number of parameters passed to nextion + // (0x1E) + kDisplayErrMaxArgs, // Command arg list exceeded DISPLAY_CMD_MAX_ARGS + // elements + kDisplayErrOther // Other nextion display error +} DisplayError; /** - * All three pages on the HMI + * All three pages on the HMI */ -typedef enum{ - STARTUP =0, - INFO, - FAULT -} Page_t; +typedef enum { kStartup = 0, kInfo, kFault } Page; /** * Argument types */ -typedef enum{ - STR_ARG, - INT_ARG -} Arg_e; +typedef enum { kStrArg, kIntArg } Arg; /** * Packages relevant display command data */ -typedef struct{ - char* compOrCmd; - char* attr; - char* op; - uint8_t numArgs; - Arg_e argTypes[MAX_ARGS]; // TRUE for integers, FALSE for strings - union{ - char* str; - uint32_t num; - } args[MAX_ARGS]; -} DisplayCmd_t; +typedef struct { + char* comp_or_cmd; + char* attr; + char* op; + uint8_t num_args; + Arg arg_types[DISPLAY_CMD_MAX_ARGS]; // TRUE for integers, FALSE for + // strings + union { + char* str; + uint32_t num; + } args[DISPLAY_CMD_MAX_ARGS]; +} DisplayCmd; /** * @brief Sends a display message. * @returns DisplayError_t */ -DisplayError_t Display_Send(DisplayCmd_t cmd); +DisplayError DisplaySend(DisplayCmd cmd); /** * @brief Initializes the display * @returns DisplayError_t */ -DisplayError_t Display_Init(void); +DisplayError DisplayInit(void); /** * @brief Resets (reboots) the display * @returns DisplayError_t */ -DisplayError_t Display_Reset(void); +DisplayError DisplayReset(void); /** - * @brief Overwrites any processing commands and triggers the display fault screen + * @brief Overwrites any processing commands and triggers the display fault + * screen * @param faultCode the application's fault code (will be displayed in hex) * @returns DisplayError_t */ -DisplayError_t Display_Error(error_code_t faultCode); +DisplayError DisplayFault(ErrorCode fault_code); /** * @brief Overwrites any processing commands and triggers the evacuation screen * @param SOC_percent the state of charge of the battery in percent * @param supp_mv the voltage of the battery in millivolts * @returns DisplayError_t -*/ -DisplayError_t Display_Evac(uint8_t SOC_percent, uint32_t supp_mv); + */ +DisplayError DisplayEvac(uint8_t soc_percent, uint32_t supp_mv); #endif - /* @} */ diff --git a/Drivers/Inc/GPIOExpander.h b/Drivers/Inc/GPIOExpander.h deleted file mode 100644 index 5e8644c85..000000000 --- a/Drivers/Inc/GPIOExpander.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar - * @file GPIOExpander.h - * @brief - * - * @defgroup GPIOExpander - * @addtogroup GPIOExpander - * @{ - */ - -/* Deprecated */ - -#ifndef __GPIOEXPANDER_H -#define __GPIOEXPANDER_H - -#include "common.h" - -typedef struct _spi_message { - int8_t opcode; - int8_t requestedPort; - int8_t data; -} spi_message; - - -// Opcodes -#define SPI_OPCODE_R 0x41 -#define SPI_OPCODE_W 0x40 - -// Register Addresses (BANK = 0) -#define SPI_IODIRA 0x00 -#define SPI_IOPOLA 0x02 -#define SPI_GPINTENA 0x04 -#define SPI_DEFVALA 0x06 -#define SPI_INTCONA 0x08 -#define SPI_IOCONA 0x0A -#define SPI_GPPUA 0x0C -#define SPI_INTFA 0x0E -#define SPI_INTCAPA 0x10 -#define SPI_GPIOA 0x12 - -#define SPI_IODIRB 0x01 -#define SPI_IOPOLB 0x03 -#define SPI_GPINTENB 0x05 -#define SPI_DEFVALB 0x07 -#define SPI_INTCONB 0x09 -#define SPI_GPPUAB 0x0D -#define SPI_INTFAB 0x0F -#define SPI_INTCAPB 0x11 -#define SPI_GPIOB 0x13 -#define SPI_OLATB 0x15 - -#endif - -/* @} */ diff --git a/Drivers/Inc/Minions.h b/Drivers/Inc/Minions.h index 4ef240c22..4f7304962 100644 --- a/Drivers/Inc/Minions.h +++ b/Drivers/Inc/Minions.h @@ -2,10 +2,10 @@ /** * @defgroup Minions - * - * This modules allows us to use GPIO more easily + * + * This modules allows us to use GPIO more easily * for our application's purposes - * + * * @defgroup Minions * @addtogroup Minions * @{ @@ -13,58 +13,51 @@ #ifndef MINIONS_H #define MINIONS_H -#include "common.h" -#include + #include "BSP_GPIO.h" +#include "common.h" // used to index into lookup table // if changed, PINS_LOOKARR should be changed in Minions.c -#define FOREACH_PIN(PIN) \ - PIN(IGN_1), \ - PIN(IGN_2), \ - PIN(REGEN_SW), \ - PIN(FOR_SW), \ - PIN(REV_SW), \ - PIN(CRUZ_EN), \ - PIN(CRUZ_ST), \ - PIN(BRAKELIGHT), \ +#define FOREACH_PIN(PIN) \ + PIN(kIgn1), PIN(kIgn2), PIN(kRegenSw), PIN(kForSw), PIN(kRevSw), \ + PIN(kCruzEn), PIN(kCruzSt), PIN(kBrakeLight), -typedef enum MINIONPIN_ENUM { - FOREACH_PIN(GENERATE_ENUM) - NUM_PINS, -} pin_t; +typedef enum { + FOREACH_PIN(GENERATE_ENUM) kNumPins, +} Pin; typedef struct { - uint16_t pinMask; - port_t port; - direction_t direction; -} pinInfo_t; + uint16_t pin_mask; + Port port; + Direction direction; +} PinInfo; /** * @brief Initializes digital I/O - * + * */ -void Minions_Init(void); +void MinionsInit(void); /** * @brief Reads the status of a pin - * - * @param pin + * + * @param pin * @return true is high * @return false is low */ -bool Minions_Read(pin_t pin); +bool MinionsRead(Pin pin); /** * @brief Updates the status of a pin - * - * @param pin - * @param status + * + * @param pin + * @param status * @return true is fail (wrote to an input) * @return false is success (wrote to an output) */ -bool Minions_Write(pin_t pin, bool status); +bool MinionsWrite(Pin pin, bool status); -#endif +#endif /* @} */ diff --git a/Drivers/Inc/Pedals.h b/Drivers/Inc/Pedals.h index 365180e10..45232b924 100644 --- a/Drivers/Inc/Pedals.h +++ b/Drivers/Inc/Pedals.h @@ -2,44 +2,38 @@ * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file Pedals.h * @brief Header file for the Pedals driver - * + * * @defgroup Pedals * @addtogroup Pedals * @{ */ -#ifndef __PEDALS_H -#define __PEDALS_H +#ifndef PEDALS_H +#define PEDALS_H #include "BSP_ADC.h" /** * @brief Stuff - * + * */ -typedef enum -{ - ACCELERATOR, - BRAKE, - NUMBER_OF_PEDALS -} pedal_t; +typedef enum { kAccelerator, kBrake, kNumberOfPedals } Pedal; /** * @brief Initialize the pedals * @param None * @return None - */ -void Pedals_Init(void); + */ +void PedalsInit(void); /** - * @brief Provides the pedal distance pressed in percetage (accelerator or brake) + * @brief Provides the pedal distance pressed in percetage (accelerator or + * brake) * @param pedal_t pedal, ACCELERATOR or BRAKE as defined in enum * @return distance the pedal has been pressed in percentage - */ -int8_t Pedals_Read(pedal_t pedal); - + */ +int8_t PedalsRead(Pedal pedal); #endif - /* @} */ diff --git a/Drivers/Src/CANConfig.c b/Drivers/Src/CANConfig.c deleted file mode 100644 index 23135d00b..000000000 --- a/Drivers/Src/CANConfig.c +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar - * @file CANConfig.c - * @brief - * - */ -#include "CANConfig.h" - -#define BYTE 1 -#define HALFWORD 2 -#define WORD 4 -#define DOUBLE 8 -#define NOIDX false -#define IDX true - -/** - * @brief Lookup table to simplify user-defined packet structs. Contains metadata fields that are always the same for every message of a given ID. - * Indexed by CANId_t values. Any changes or additions must be made in parallel with changes made to the CANID_t enum in CANbus.h - */ -const CANLUT_T CANLUT[MAX_CAN_ID] = { - [BPS_TRIP] = {NOIDX, DOUBLE}, /** BPS_TRIP **/ - [BPS_CONTACTOR] = {NOIDX, DOUBLE}, /** BPS_CONTACTOR **/ - [STATE_OF_CHARGE] = {NOIDX, DOUBLE}, /** STATE_OF_CHARGE **/ - [SUPPLEMENTAL_VOLTAGE] = {NOIDX, DOUBLE}, /** SUPPLEMENTAL_VOLTAGE **/ - [MOTOR_DRIVE] = {NOIDX, DOUBLE}, /** MOTOR_DRIVE **/ - [MOTOR_POWER] = {NOIDX, DOUBLE}, /** MOTOR_POWER **/ - [MOTOR_RESET] = {NOIDX, DOUBLE}, /** MOTOR_RESET **/ - [MOTOR_STATUS] = {NOIDX, DOUBLE}, /** MOTOR_STATUS **/ - [MC_BUS] = {NOIDX, DOUBLE}, /** MC_BUS **/ - [VELOCITY] = {NOIDX, DOUBLE}, /** VELOCITY **/ - [MC_PHASE_CURRENT] = {NOIDX, DOUBLE}, /** MC_PHASE_CURRENT **/ - [VOLTAGE_VEC] = {NOIDX, DOUBLE}, /** VOLTAGE_VEC **/ - [CURRENT_VEC] = {NOIDX, DOUBLE}, /** CURRENT_VEC **/ - [BACKEMF] = {NOIDX, DOUBLE}, /** BACKEMF **/ - [TEMPERATURE] = {NOIDX, DOUBLE}, /** TEMPERATURE **/ - [ODOMETER_AMPHOURS] = {NOIDX, DOUBLE}, /** ODOMETER_AMPHOURS **/ - [ARRAY_CONTACTOR_STATE_CHANGE] = {NOIDX, BYTE }, /** ARRAY_CONTACTOR_STATE_CHANGE **/ - [SLIP_SPEED] = {NOIDX, DOUBLE}, - [MOTOR_DRIVE] = {NOIDX, DOUBLE}, /** MOTOR_DRIVE **/ - [MOTOR_POWER] = {NOIDX, DOUBLE}, /** MOTOR_POWER **/ - [MOTOR_RESET] = {NOIDX, DOUBLE}, /** MOTOR_RESET **/ - [MOTOR_STATUS] = {NOIDX, DOUBLE}, /** MOTOR_STATUS **/ - [IO_STATE] = {NOIDX, DOUBLE}, /** IO_STATE **/ - [CONTROL_MODE] = {NOIDX, BYTE }, /** CONTROL_MODE **/ -}; - -/** - * @brief Lists of CAN IDs that we want to receive. Used to initialize the CAN filters for CarCAN and MotorCAN. -*/ - -CANId_t carCANFilterList[NUM_CARCAN_FILTERS] = { - BPS_TRIP, - BPS_CONTACTOR, // Bit 1 and 0 contain BPS HV Plus/Minus (associated Motor Controller) Contactor and BPS HV Array Contactor, respectively - STATE_OF_CHARGE, - SUPPLEMENTAL_VOLTAGE -}; - -CANId_t motorCANFilterList[NUM_MOTORCAN_FILTERS] = { - MC_BUS, - VELOCITY, - BACKEMF, - TEMPERATURE, - ODOMETER_AMPHOURS, - SLIP_SPEED, - MOTOR_STATUS -}; diff --git a/Drivers/Src/CANbus.c b/Drivers/Src/CANbus.c deleted file mode 100755 index 413a5c734..000000000 --- a/Drivers/Src/CANbus.c +++ /dev/null @@ -1,258 +0,0 @@ -/** - * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar - * @file CANbus.c - * @brief - * - */ -#include "CANbus.h" -#include "config.h" -#include "os.h" -#include "Tasks.h" -#include "CANConfig.h" - -static OS_SEM CANMail_Sem4[NUM_CAN]; // sem4 to count how many sending hardware mailboxes we have left (start at 3) -static OS_SEM CANBus_ReceiveSem4[NUM_CAN]; // sem4 to count how many msgs in our recieving queue -static OS_MUTEX CANbus_TxMutex[NUM_CAN]; // mutex to lock tx line -static OS_MUTEX CANbus_RxMutex[NUM_CAN]; // mutex to lock Rx line - -/** - * @brief this function will be passed down to the BSP layer to trigger on RX events. Increments the receive semaphore to signal message in hardware mailbox. Do not access directly outside this driver. - * @param bus The CAN bus to operate on. Should be CARCAN or MOTORCAN. - */ -void CANbus_RxHandler(CAN_t bus) -{ - OS_ERR err; - OSSemPost(&(CANBus_ReceiveSem4[bus]), OS_OPT_POST_1, &err); // increment our queue counter - assertOSError(err); -} - -/** - * @brief this function will be passed down to the BSP layer to trigger on TXend. Releases hold of the mailbox semaphore (Increments it to show mailbox available). Do not access directly outside this driver. - * @param bus The CAN bus to operate on. Should be CARCAN or MOTORCAN. - */ -void CANbus_TxHandler(CAN_t bus) -{ - OS_ERR err; - OSSemPost(&(CANMail_Sem4[bus]), OS_OPT_POST_1, &err); - assertOSError(err); -} - -//wrapper functions for the interrupt customized for each bus -void CANbus_TxHandler_1(){ - CANbus_TxHandler(CAN_1); -} - -void CANbus_RxHandler_1(){ - CANbus_RxHandler(CAN_1); -} -void CANbus_TxHandler_3(){ - CANbus_TxHandler(CAN_3); -} -void CANbus_RxHandler_3(){ - CANbus_RxHandler(CAN_3); -} - -/** - * @brief Checks each CAN ID. If an ID is not in CANLUT, set that ID to NULL - * @param wlist The whitelist containing the IDs to be checked - * @param size The size of the whitelist of IDs - * @return Returns the whitelist to be -*/ -static CANId_t* whitelist_validator(CANId_t* wlist, uint8_t size){ - for(int i = 0; i < size; i++){ - CANId_t curr = wlist[i]; - if(curr >= MAX_CAN_ID) { - wlist[i] = 0; - } else if (CANLUT[curr].size == 0 ) { - wlist[i] = 0; - } - } - return wlist; -} - -ErrorStatus CANbus_Init(CAN_t bus, CANId_t* idWhitelist, uint8_t idWhitelistSize) -{ - // initialize CAN mailbox semaphore to 3 for the 3 CAN mailboxes that we have - // initialize tx - OS_ERR err; - idWhitelist = whitelist_validator(idWhitelist, idWhitelistSize); - if(bus==CAN_1){ - BSP_CAN_Init(bus,&CANbus_RxHandler_1,&CANbus_TxHandler_1, (uint16_t*)idWhitelist, idWhitelistSize); - } else if (bus==CAN_3){ - BSP_CAN_Init(bus,&CANbus_RxHandler_3,&CANbus_TxHandler_3, (uint16_t*)idWhitelist, idWhitelistSize); - } else { - return ERROR; - } - - OSMutexCreate(&(CANbus_TxMutex[bus]), (bus == CAN_1 ? "CAN TX Lock 1":"CAN TX Lock 3"), &err); - assertOSError(err); - - OSMutexCreate(&(CANbus_RxMutex[bus]), (bus == CAN_1 ? "CAN RX Lock 1":"CAN RX Lock 3"), &err); - assertOSError(err); - - OSSemCreate(&(CANMail_Sem4[bus]), (bus == CAN_1 ? "CAN Mailbox Semaphore 1":"CAN Mailbox Semaphore 3"), 3, &err); // there's 3 hardware mailboxes on the board, so 3 software mailboxes - assertOSError(err); - - OSSemCreate(&(CANBus_ReceiveSem4[bus]), (bus == CAN_1 ? "CAN Received Msg Queue Ctr 1":"CAN Received Msg Queue Ctr 3"), 0, &err); // create a mailbox counter to hold the messages in as they come in - assertOSError(err); - - return SUCCESS; -} - -ErrorStatus CANbus_Send(CANDATA_t CanData,bool blocking, CAN_t bus) -{ - CPU_TS timestamp; - OS_ERR err; - - //error check the id - if(CanData.ID >= MAX_CAN_ID){return ERROR;} - - CANLUT_T msginfo = CANLUT[CanData.ID]; //lookup msg information in table - - if(msginfo.size == 0){return ERROR;} //if they passed in an invalid id, it will be zero - - - // make sure that Can mailbox is available - if (blocking == CAN_BLOCKING) - { - OSSemPend( - &(CANMail_Sem4[bus]), - 0, - OS_OPT_PEND_BLOCKING, - ×tamp, - &err); - } - else - { - OSSemPend( - &(CANMail_Sem4[bus]), - 0, - OS_OPT_PEND_NON_BLOCKING, - ×tamp, - &err); - - // don't crash if we are just using this in non-blocking mode and don't block - if(err == OS_ERR_PEND_WOULD_BLOCK){ - return ERROR; - } - } - if (err != OS_ERR_NONE) - { - assertOSError(err); - return ERROR; - } - - uint8_t txdata[8]; - if(msginfo.idxEn){ //first byte of txData should be the idx value - memcpy(txdata, &CanData.idx, 1); - memcpy(&(txdata[sizeof(CanData.idx)]), &CanData.data, msginfo.size); - } else { //non-idx case - memcpy(txdata, &CanData.data, msginfo.size); - } - - OSMutexPend( // ensure that tx line is available - &(CANbus_TxMutex[bus]), - 0, - OS_OPT_PEND_BLOCKING, - ×tamp, - &err); - assertOSError(err); // couldn't lock tx line - - // tx line locked - ErrorStatus retval = BSP_CAN_Write( - bus, //bus to transmit onto - CanData.ID, //ID from Data struct - txdata, //data we memcpy'd earlier - (msginfo.idxEn ? msginfo.size+sizeof(CanData.idx) : msginfo.size) //if IDX then add one to the msg size, else the msg size - ); - - OSMutexPost( // unlock the TX line - &(CANbus_TxMutex[bus]), - OS_OPT_POST_NONE, - &err); - assertOSError(err); - if(retval == ERROR){ - CANbus_TxHandler(bus); //release the mailbox by posting back to the counter semaphore - } - - return retval; -} - -ErrorStatus CANbus_Read(CANDATA_t* MsgContainer, bool blocking, CAN_t bus) -{ - CPU_TS timestamp; - OS_ERR err; - - if (blocking == CAN_BLOCKING) - { - OSSemPend( // check if the queue actually has anything - &(CANBus_ReceiveSem4[bus]), - 0, - OS_OPT_PEND_BLOCKING, - ×tamp, - &err); - } - else - { - OSSemPend( - &(CANBus_ReceiveSem4[bus]), - 0, - OS_OPT_PEND_NON_BLOCKING, - ×tamp, - &err); - - // don't crash if we are just using this in non-blocking mode and don't block - if(err == OS_ERR_PEND_WOULD_BLOCK){ - return ERROR; - } - } - if (err != OS_ERR_NONE) - { - assertOSError(err); - return ERROR; - } - - OSMutexPend( // ensure that RX line is available - &(CANbus_RxMutex[bus]), - 0, - OS_OPT_PEND_BLOCKING, - ×tamp, - &err); - assertOSError(err); - - // Actually get the message - uint32_t id; - ErrorStatus status = BSP_CAN_Read(bus, &id, MsgContainer->data); - - OSMutexPost( // unlock RX line - &(CANbus_RxMutex[bus]), - OS_OPT_POST_NONE, - &err); - assertOSError(err); - if(status == ERROR){ - return ERROR; - } - - //error check the id - MsgContainer->ID = (CANId_t) id; - if(MsgContainer->ID >= MAX_CAN_ID){ - MsgContainer = NULL; - return ERROR; - } - CANLUT_T entry = CANLUT[MsgContainer->ID]; //lookup msg information in table - if(entry.size == 0){ - MsgContainer = NULL; - return ERROR; - } //if they passed in an invalid id, it will be zero - - //search LUT for id to populate idx and trim data - if(entry.idxEn==true){ - MsgContainer->idx = MsgContainer->data[0]; - memmove( // Can't use memcpy, as memory regions overlap - MsgContainer->data, - &(MsgContainer->data[1]), - 7 // max size of data (8) - size of idx byte (1) - ); - } - return status; -} diff --git a/Drivers/Src/CanBus.c b/Drivers/Src/CanBus.c new file mode 100644 index 000000000..8fe433fa3 --- /dev/null +++ b/Drivers/Src/CanBus.c @@ -0,0 +1,240 @@ +/** + * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar + * @file CANbus.c + * @brief + * + */ + +#include "CanBus.h" + +#include "CanConfig.h" +#include "Tasks.h" +#include "config.h" +#include "os.h" + +static OS_SEM + can_mail_sem4[kNumCan]; // sem4 to count how many sending hardware + // mailboxes we have left (start at 3) +static OS_SEM can_bus_receive_sem4[kNumCan]; // sem4 to count how many msgs in + // our recieving queue +static OS_MUTEX can_bus_tx_mutex[kNumCan]; // mutex to lock tx line +static OS_MUTEX can_bus_rx_mutex[kNumCan]; // mutex to lock Rx line + +/** + * @brief this function will be passed down to the BSP layer to trigger on RX + * events. Increments the receive semaphore to signal message in hardware + * mailbox. Do not access directly outside this driver. + * @param bus The CAN bus to operate on. Should be CARCAN or MOTORCAN. + */ +void CanBusRxHandler(Can bus) { + OS_ERR err = 0; + OSSemPost(&(can_bus_receive_sem4[bus]), OS_OPT_POST_1, + &err); // increment our queue counter + ASSERT_OS_ERROR(err); +} + +/** + * @brief this function will be passed down to the BSP layer to trigger on + * TXend. Releases hold of the mailbox semaphore (Increments it to show mailbox + * available). Do not access directly outside this driver. + * @param bus The CAN bus to operate on. Should be CARCAN or MOTORCAN. + */ +void CanBusTxHandler(Can bus) { + OS_ERR err = 0; + OSSemPost(&(can_mail_sem4[bus]), OS_OPT_POST_1, &err); + ASSERT_OS_ERROR(err); +} + +// wrapper functions for the interrupt customized for each bus +void CanBusTxHandler1() { CanBusTxHandler(kCan1); } + +void CanBusRxHandler1() { CanBusRxHandler(kCan1); } +void CanBusTxHandler3() { CanBusTxHandler(kCan3); } +void CanBusRxHandler3() { CanBusRxHandler(kCan3); } + +/** + * @brief Checks each CAN ID. If an ID is not in kCanLut, set that ID to NULL + * @param wlist The whitelist containing the IDs to be checked + * @param size The size of the whitelist of IDs + * @return Returns the whitelist to be + */ +static CanId* whitelistValidator(CanId* wlist, uint8_t size) { + for (int i = 0; i < size; i++) { + CanId curr = wlist[i]; + if (curr >= kMaxCanId || kCanLut[curr].size == 0) { + wlist[i] = 0; + } + } + return wlist; +} + +ErrorStatus CanBusInit(Can bus, CanId* id_whitelist, + uint8_t id_whitelist_size) { + // initialize CAN mailbox semaphore to 3 for the 3 CAN mailboxes that we + // have initialize tx + OS_ERR err = 0; + id_whitelist = whitelistValidator(id_whitelist, id_whitelist_size); + if (bus == kCan1) { + BspCanInit(bus, &CanBusRxHandler1, &CanBusTxHandler1, + (uint16_t*)id_whitelist, id_whitelist_size); + } else if (bus == kCan3) { + BspCanInit(bus, &CanBusRxHandler3, &CanBusTxHandler3, + (uint16_t*)id_whitelist, id_whitelist_size); + } else { + return ERROR; + } + + OSMutexCreate(&(can_bus_tx_mutex[bus]), + (bus == kCan1 ? "CAN TX Lock 1" : "CAN TX Lock 3"), &err); + ASSERT_OS_ERROR(err); + + OSMutexCreate(&(can_bus_rx_mutex[bus]), + (bus == kCan1 ? "CAN RX Lock 1" : "CAN RX Lock 3"), &err); + ASSERT_OS_ERROR(err); + + OSSemCreate( + &(can_mail_sem4[bus]), + (bus == kCan1 ? "CAN Mailbox Semaphore 1" : "CAN Mailbox Semaphore 3"), + BSP_CAN_NUM_MAILBOX, &err); // there's 3 hardware mailboxes on the + // board, so 3 software mailboxes + ASSERT_OS_ERROR(err); + + OSSemCreate(&(can_bus_receive_sem4[bus]), + (bus == kCan1 ? "CAN Received Msg Queue Ctr 1" + : "CAN Received Msg Queue Ctr 3"), + 0, &err); // create a mailbox counter to hold the messages in + // as they come in + ASSERT_OS_ERROR(err); + + return SUCCESS; +} + +ErrorStatus CanBusSend(CanData can_data, bool blocking, Can bus) { + CPU_TS timestamp = 0; + OS_ERR err = 0; + + // error check the id + if (can_data.id >= kMaxCanId) { + return ERROR; + } + + CanLut msginfo = kCanLut[can_data.id]; // lookup msg information in table + + if (msginfo.size == 0) { + return ERROR; + } // if they passed in an invalid id, it will be zero + + // make sure that Can mailbox is available + if (blocking == CAN_BLOCKING) { + OSSemPend(&(can_mail_sem4[bus]), 0, OS_OPT_PEND_BLOCKING, ×tamp, + &err); + } else { + OSSemPend(&(can_mail_sem4[bus]), 0, OS_OPT_PEND_NON_BLOCKING, + ×tamp, &err); + + // don't crash if we are just using this in non-blocking mode and don't + // block + if (err == OS_ERR_PEND_WOULD_BLOCK) { + return ERROR; + } + } + if (err != OS_ERR_NONE) { + ASSERT_OS_ERROR(err); + return ERROR; + } + + uint8_t txdata[BSP_CAN_DATA_LENGTH]; + if (msginfo.idx_en) { // first byte of txData should be the idx value + memcpy(txdata, &can_data.idx, 1); + memcpy(&(txdata[sizeof(can_data.idx)]), &can_data.data, msginfo.size); + } else { // non-idx case + memcpy(txdata, &can_data.data, msginfo.size); + } + + OSMutexPend( // ensure that tx line is available + &(can_bus_tx_mutex[bus]), 0, OS_OPT_PEND_BLOCKING, ×tamp, &err); + ASSERT_OS_ERROR(err); // couldn't lock tx line + + // tx line locked + ErrorStatus retval = BspCanWrite( + bus, // bus to transmit onto + can_data.id, // ID from Data struct + txdata, // data we memcpy'd earlier + (msginfo.idx_en ? msginfo.size + sizeof(can_data.idx) + : msginfo.size) // if IDX then add one to the msg size, + // else the msg size + ); + + OSMutexPost( // unlock the TX line + &(can_bus_tx_mutex[bus]), OS_OPT_POST_NONE, &err); + ASSERT_OS_ERROR(err); + if (retval == ERROR) { + CanBusTxHandler(bus); // release the mailbox by posting back to the + // counter semaphore + } + + return retval; +} + +ErrorStatus CanBusRead(CanData* msg_container, bool blocking, Can bus) { + CPU_TS timestamp = 0; + OS_ERR err = 0; + + if (blocking == CAN_BLOCKING) { + OSSemPend( // check if the queue actually has anything + &(can_bus_receive_sem4[bus]), 0, OS_OPT_PEND_BLOCKING, ×tamp, + &err); + } else { + OSSemPend(&(can_bus_receive_sem4[bus]), 0, OS_OPT_PEND_NON_BLOCKING, + ×tamp, &err); + + // don't crash if we are just using this in non-blocking mode and don't + // block + if (err == OS_ERR_PEND_WOULD_BLOCK) { + return ERROR; + } + } + if (err != OS_ERR_NONE) { + ASSERT_OS_ERROR(err); + return ERROR; + } + + OSMutexPend( // ensure that RX line is available + &(can_bus_rx_mutex[bus]), 0, OS_OPT_PEND_BLOCKING, ×tamp, &err); + ASSERT_OS_ERROR(err); + + // Actually get the message + uint32_t id = 0; + ErrorStatus status = BspCanRead(bus, &id, msg_container->data); + + OSMutexPost( // unlock RX line + &(can_bus_rx_mutex[bus]), OS_OPT_POST_NONE, &err); + ASSERT_OS_ERROR(err); + if (status == ERROR) { + return ERROR; + } + + // error check the id + msg_container->id = (CanId)id; + if (msg_container->id >= kMaxCanId) { + msg_container = NULL; + return ERROR; + } + CanLut entry = + kCanLut[msg_container->id]; // lookup msg information in table + if (entry.size == 0) { + msg_container = NULL; + return ERROR; + } // if they passed in an invalid id, it will be zero + + // search LUT for id to populate idx and trim data + if (entry.idx_en == true) { + msg_container->idx = msg_container->data[0]; + memmove( // Can't use memcpy, as memory regions overlap + msg_container->data, &(msg_container->data[1]), + BSP_CAN_DATA_LENGTH - + 1 // max size of data (8) - size of idx byte (1) + ); + } + return status; +} diff --git a/Drivers/Src/CanConfig.c b/Drivers/Src/CanConfig.c new file mode 100644 index 000000000..06e59b4d7 --- /dev/null +++ b/Drivers/Src/CanConfig.c @@ -0,0 +1,60 @@ +/** + * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar + * @file CANConfig.c + * @brief + * + */ + +#include "CanConfig.h" + +#define BYTE 1 +#define HALFWORD 2 +#define WORD 4 +#define DOUBLE 8 +#define NOIDX false +#define IDX true + +/** + * @brief Lookup table to simplify user-defined packet structs. Contains + * metadata fields that are always the same for every message of a given ID. + * Indexed by CanId values. Any changes or additions must be made in + * parallel with changes made to the CANID_t enum in CanBus.h + */ +const CanLut kCanLut[kMaxCanId] = { + [kBpsTrip] = {NOIDX, DOUBLE}, + [kBpsContactor] = {NOIDX, DOUBLE}, + [kStateOfCharge] = {NOIDX, DOUBLE}, + [kSupplementalVoltage] = {NOIDX, DOUBLE}, + [kMotorDrive] = {NOIDX, DOUBLE}, + [kMotorPower] = {NOIDX, DOUBLE}, + [kMotorReset] = {NOIDX, DOUBLE}, + [kMotorStatus] = {NOIDX, DOUBLE}, + [kMcBus] = {NOIDX, DOUBLE}, + [kVelocity] = {NOIDX, DOUBLE}, + [kMcPhaseCurrent] = {NOIDX, DOUBLE}, + [kVoltageVec] = {NOIDX, DOUBLE}, + [kCurrentVec] = {NOIDX, DOUBLE}, + [kBackEmf] = {NOIDX, DOUBLE}, + [kTemperature] = {NOIDX, DOUBLE}, + [kOdometerAmpHours] = {NOIDX, DOUBLE}, + [kArrayContactorStateChange] = {NOIDX, BYTE}, + [kSlipSpeed] = {NOIDX, DOUBLE}, + [kIoState] = {NOIDX, DOUBLE}, + [kControlMode] = {NOIDX, BYTE}, +}; + +/** + * @brief Lists of CAN IDs that we want to receive. Used to initialize the CAN + * filters for CarCAN and MotorCAN. + */ + +CanId car_can_filter_list[NUM_CARCAN_FILTERS] = { + kBpsTrip, + kBpsContactor, // Bit 1 and 0 contain BPS HV Plus/Minus (associated Motor + // Controller) Contactor and BPS HV Array Contactor, + // respectively + kStateOfCharge, kSupplementalVoltage}; + +CanId motor_can_filter_list[NUM_MOTORCAN_FILTERS] = { + kMcBus, kVelocity, kBackEmf, kTemperature, kOdometerAmpHours, + kSlipSpeed, kMotorStatus}; diff --git a/Drivers/Src/Contactors.c b/Drivers/Src/Contactors.c index 66ec45e0f..f1dfb251d 100644 --- a/Drivers/Src/Contactors.c +++ b/Drivers/Src/Contactors.c @@ -1,31 +1,33 @@ /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file Contactors.h - * @brief - * + * @brief + * */ #include "Contactors.h" -#include "stm32f4xx_gpio.h" + #include "Tasks.h" -static OS_MUTEX contactorsMutex; +static OS_MUTEX contactors_mutex; /** * @brief Helper function for setting contactors without mutex. - * Should only be called if mutex is held and struct contactor has been checked + * Should only be called if mutex is held and struct contactor has been + * checked * @param contactor the contactor - * (MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR/ARRAY_PRECHARGE_BYPASS_CONTACTOR) + * (kMotorControllerPrechargeBypassContactor/kArrayPrechargeBypassContactor) * @param state the state to set (ON/OFF) * @return None - */ -static void setContactor(contactor_t contactor, bool state) { + */ +static void setContactor(Contactor contactor, bool state) { switch (contactor) { - case ARRAY_PRECHARGE_BYPASS_CONTACTOR : - BSP_GPIO_Write_Pin(CONTACTORS_PORT, ARRAY_PRECHARGE_BYPASS_PIN, state); + case kArrayPrechargeBypassContactor: + BspGpioWritePin(CONTACTORS_PORT, ARRAY_PRECHARGE_BYPASS_PIN, state); break; - case MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR : - BSP_GPIO_Write_Pin(CONTACTORS_PORT, MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN, state); + case kMotorControllerPrechargeBypassContactor: + BspGpioWritePin(CONTACTORS_PORT, + MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN, state); break; default: break; @@ -36,40 +38,41 @@ static void setContactor(contactor_t contactor, bool state) { * @brief Initializes contactors to be used * in connection with the Motor and Array * @return None - */ -void Contactors_Init() { - BSP_GPIO_Init(CONTACTORS_PORT, - (ARRAY_PRECHARGE_BYPASS_PIN) | - (MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN), - 1); + */ +void ContactorsInit() { + BspGpioInit( + CONTACTORS_PORT, + (ARRAY_PRECHARGE_BYPASS_PIN) | (MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN), + 1); // start disabled - for (int contactor = 0; contactor < NUM_CONTACTORS; ++contactor) { + for (int contactor = 0; contactor < kNumContactors; ++contactor) { setContactor(contactor, OFF); } // initialize mutex - OS_ERR err; - OSMutexCreate(&contactorsMutex, "Contactors lock", &err); - assertOSError(err); + OS_ERR err = 0; + OSMutexCreate(&contactors_mutex, "Contactors lock", &err); + ASSERT_OS_ERROR(err); } /** - * @brief Returns the current state of + * @brief Returns the current state of * a specified contactor * @param contactor the contactor - * (MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR/ARRAY_PRECHARGE_BYPASS_CONTACTOR) + * (kMotorControllerPrechargeBypassContactor/kArrayPrechargeBypassContactor) * @return The contactor's state (ON/OFF) - */ -bool Contactors_Get(contactor_t contactor) { + */ +bool ContactorsGet(Contactor contactor) { State state = OFF; switch (contactor) { - - case ARRAY_PRECHARGE_BYPASS_CONTACTOR : - state = BSP_GPIO_Get_State(CONTACTORS_PORT, ARRAY_PRECHARGE_BYPASS_PIN); + case kArrayPrechargeBypassContactor: + state = + BspGpioGetState(CONTACTORS_PORT, ARRAY_PRECHARGE_BYPASS_PIN); break; - case MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR : - state = BSP_GPIO_Get_State(CONTACTORS_PORT, MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN); + case kMotorControllerPrechargeBypassContactor: + state = BspGpioGetState(CONTACTORS_PORT, + MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN); break; default: break; @@ -80,32 +83,34 @@ bool Contactors_Get(contactor_t contactor) { /** * @brief Sets the state of a specified contactor * @param contactor the contactor - * (MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR/ARRAY_PRECHARGE_BYPASS_CONTACTOR) + * (kMotorControllerPrechargeBypassContactor/kArrayPrechargeBypassContactor) * @param state the state to set (ON/OFF) * @param blocking whether or not this should be a blocking call * @return Whether or not the contactor was successfully set */ -ErrorStatus Contactors_Set(contactor_t contactor, bool state, bool blocking) { - CPU_TS timestamp; - OS_ERR err; +ErrorStatus ContactorsSet(Contactor contactor, bool state, bool blocking) { + CPU_TS timestamp = 0; + OS_ERR err = 0; ErrorStatus result = ERROR; // acquire lock if its available - OSMutexPend(&contactorsMutex, 0, blocking ? OS_OPT_PEND_BLOCKING : OS_OPT_PEND_NON_BLOCKING, ×tamp, &err); - - if(err == OS_ERR_PEND_WOULD_BLOCK){ + OSMutexPend(&contactors_mutex, 0, + blocking ? OS_OPT_PEND_BLOCKING : OS_OPT_PEND_NON_BLOCKING, + ×tamp, &err); + + if (err == OS_ERR_PEND_WOULD_BLOCK) { return ERROR; } - assertOSError(err); + ASSERT_OS_ERROR(err); // change contactor to match state and make sure it worked setContactor(contactor, state); - bool ret = (bool)Contactors_Get(contactor); - result = (ret == state) ? SUCCESS: ERROR; + bool ret = (bool)ContactorsGet(contactor); + result = (ret == state) ? SUCCESS : ERROR; // release lock - OSMutexPost(&contactorsMutex, OS_OPT_POST_NONE, &err); - assertOSError(err); + OSMutexPost(&contactors_mutex, OS_OPT_POST_NONE, &err); + ASSERT_OS_ERROR(err); return result; } diff --git a/Drivers/Src/Display.c b/Drivers/Src/Display.c index 298ea0f25..e85f00d81 100644 --- a/Drivers/Src/Display.c +++ b/Drivers/Src/Display.c @@ -5,124 +5,133 @@ * * This contains functions relevant to sending/receiving messages * to/from our Nextion display. - * + * */ #include "Display.h" -#include "bsp.h" // for writing to UART -#include "Tasks.h" // for os and fault error codes -#define DISP_OUT UART_3 +#include "Tasks.h" // for os and fault error codes +#include "bsp.h" // for writing to UART + +#define PAGE_STR_SIZE 7 +#define FAULT_STR_SIZE 20 +#define SOC_STR_SIZE 13 +#define SUPP_STR_SIZE 18 + +#define DISP_OUT kUart3 #define MAX_MSG_LEN 32 #define MAX_ARG_LEN 16 // Assignment commands have only 1 arg, an operator, and an attribute -#define isAssignCmd(cmd) (cmd.compOrCmd != NULL && cmd.op != NULL && cmd.attr != NULL && cmd.numArgs == 1) -// Operational commands have no attribute and no operator, just a command and >= 0 arguments -#define isOpCmd(cmd) (cmd.op == NULL && cmd.attr == NULL) - -static const char *TERMINATOR = "\xff\xff\xff"; - -DisplayError_t Display_Init(){ - BSP_UART_Init(DISP_OUT); - return Display_Reset(); +#define IS_ASSIGN_CMD(cmd) \ + ((((cmd).comp_or_cmd != NULL) && ((cmd).op != NULL) && \ + ((cmd).attr != NULL) && ((cmd).num_args == 1))) +// Operational commands have no attribute and no operator, just a command and >= +// 0 arguments +#define IS_OP_CMD(cmd) ((cmd).op == NULL && (cmd).attr == NULL) + +static const char *terminator = "\xff\xff\xff"; + +DisplayError DisplayInit() { + BspUartInit(DISP_OUT); + return DisplayReset(); } -DisplayError_t Display_Send(DisplayCmd_t cmd){ - char msgArgs[MAX_MSG_LEN]; - if (isAssignCmd(cmd)){ - if (cmd.argTypes[0] == INT_ARG){ - sprintf(msgArgs, "%d", (int)cmd.args[0].num); - } - else{ - if (cmd.args[0].str == NULL){return DISPLAY_ERR_PARSE;} - sprintf(msgArgs, "%s", cmd.args[0].str); - } - - BSP_UART_Write(DISP_OUT, cmd.compOrCmd, strlen(cmd.compOrCmd)); - BSP_UART_Write(DISP_OUT, ".", 1); - BSP_UART_Write(DISP_OUT, cmd.attr, strlen(cmd.attr)); - BSP_UART_Write(DISP_OUT, cmd.op, strlen(cmd.op)); - } - else if (isOpCmd(cmd)){ - msgArgs[0] = ' '; // No args - msgArgs[1] = '\0'; - if (cmd.numArgs > MAX_ARGS){return DISPLAY_ERR_OTHER;} - if (cmd.numArgs >= 1){ // If there are arguments - for (int i = 0; i < cmd.numArgs; i++){ - char arg[MAX_ARG_LEN]; - if (cmd.argTypes[i] == INT_ARG){ - sprintf(arg, "%d", (int)cmd.args[i].num); - } - else{ - sprintf(arg, "%s", cmd.args[i].str); - } - - strcat(msgArgs, arg); - - if (i < cmd.numArgs - 1){ // delimiter - strcat(msgArgs, ","); - } - } - } - BSP_UART_Write(DISP_OUT, cmd.compOrCmd, strlen(cmd.compOrCmd)); - } - else{ // Error parsing command struct - return DISPLAY_ERR_PARSE; - } - - if (cmd.numArgs >= 1){ // If there are arguments - BSP_UART_Write(DISP_OUT, msgArgs, strlen(msgArgs)); - } - - BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); - - return DISPLAY_ERR_NONE; +DisplayError DisplaySend(DisplayCmd cmd) { + char msg_args[MAX_MSG_LEN]; + if (IS_ASSIGN_CMD(cmd)) { + if (cmd.arg_types[0] == kIntArg) { + sprintf(msg_args, "%d", (int)cmd.args[0].num); + } else { + if (cmd.args[0].str == NULL) { + return kDisplayErrParse; + } + sprintf(msg_args, "%s", cmd.args[0].str); + } + + BspUartWrite(DISP_OUT, cmd.comp_or_cmd, strlen(cmd.comp_or_cmd)); + BspUartWrite(DISP_OUT, ".", 1); + BspUartWrite(DISP_OUT, cmd.attr, strlen(cmd.attr)); + BspUartWrite(DISP_OUT, cmd.op, strlen(cmd.op)); + } else if (IS_OP_CMD(cmd)) { + msg_args[0] = ' '; // No args + msg_args[1] = '\0'; + if (cmd.num_args > DISPLAY_CMD_MAX_ARGS) { + return kDisplayErrOther; + } + if (cmd.num_args >= 1) { // If there are arguments + for (int i = 0; i < cmd.num_args; i++) { + char arg[MAX_ARG_LEN]; + if (cmd.arg_types[i] == kIntArg) { + sprintf(arg, "%d", (int)cmd.args[i].num); + } else { + sprintf(arg, "%s", cmd.args[i].str); + } + + strcat(msg_args, arg); + + if (i < cmd.num_args - 1) { // delimiter + strcat(msg_args, ","); + } + } + } + BspUartWrite(DISP_OUT, cmd.comp_or_cmd, strlen(cmd.comp_or_cmd)); + } else { // Error parsing command struct + return kDisplayErrParse; + } + + if (cmd.num_args >= 1) { // If there are arguments + BspUartWrite(DISP_OUT, msg_args, strlen(msg_args)); + } + + BspUartWrite(DISP_OUT, (char *)terminator, strlen(terminator)); + + return kDisplayErrNone; } -DisplayError_t Display_Reset(){ - DisplayCmd_t restCmd = { - .compOrCmd = "rest", - .attr = NULL, - .op = NULL, - .numArgs = 0}; +DisplayError DisplayReset() { + DisplayCmd rest_cmd = { + .comp_or_cmd = "rest", .attr = NULL, .op = NULL, .num_args = 0}; - BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); // Terminates any in progress command + BspUartWrite(DISP_OUT, (char *)terminator, + strlen(terminator)); // Terminates any in progress command - return Display_Send(restCmd); + return DisplaySend(rest_cmd); } -DisplayError_t Display_Error(error_code_t faultCode){ - - BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); // Terminates any in progress command +DisplayError DisplayFault(ErrorCode fault_code) { + BspUartWrite(DISP_OUT, (char *)terminator, + strlen(terminator)); // Terminates any in progress command - char faultPage[7] = "page 2"; - BSP_UART_Write(DISP_OUT, faultPage, strlen(faultPage)); - BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); + char fault_page[PAGE_STR_SIZE] = "page 2"; + BspUartWrite(DISP_OUT, fault_page, strlen(fault_page)); + BspUartWrite(DISP_OUT, (char *)terminator, strlen(terminator)); - char setFaultCode[20]; - sprintf(setFaultCode, "%s\"%04x\"", "faulterr.txt=", (uint16_t)faultCode); - BSP_UART_Write(DISP_OUT, setFaultCode, strlen(setFaultCode)); - BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); + char set_fault_code[FAULT_STR_SIZE]; + sprintf(set_fault_code, "%s\"%04x\"", + "faulterr.txt=", (uint16_t)fault_code); + BspUartWrite(DISP_OUT, set_fault_code, strlen(set_fault_code)); + BspUartWrite(DISP_OUT, (char *)terminator, strlen(terminator)); - return DISPLAY_ERR_NONE; + return kDisplayErrNone; } -DisplayError_t Display_Evac(uint8_t SOC_percent, uint32_t supp_mv){ - BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); // Terminates any in progress command +DisplayError DisplayEvac(uint8_t soc_percent, uint32_t supp_mv) { + BspUartWrite(DISP_OUT, (char *)terminator, + strlen(terminator)); // Terminates any in progress command - char evacPage[7] = "page 3"; - BSP_UART_Write(DISP_OUT, evacPage, strlen(evacPage)); - BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); + char evac_page[PAGE_STR_SIZE] = "page 3"; + BspUartWrite(DISP_OUT, evac_page, strlen(evac_page)); + BspUartWrite(DISP_OUT, (char *)terminator, strlen(terminator)); - char soc[13]; - sprintf(soc, "%s%d", "soc.val=", (int)SOC_percent); - BSP_UART_Write(DISP_OUT, soc, strlen(soc)); - BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); + char soc[SOC_STR_SIZE]; + sprintf(soc, "%s%d", "soc.val=", (int)soc_percent); + BspUartWrite(DISP_OUT, soc, strlen(soc)); + BspUartWrite(DISP_OUT, (char *)terminator, strlen(terminator)); - char supp[18]; - sprintf(supp, "%s%d", "supp.val=", (int)supp_mv); - BSP_UART_Write(DISP_OUT, supp, strlen(supp)); - BSP_UART_Write(DISP_OUT, (char *)TERMINATOR, strlen(TERMINATOR)); + char supp[SUPP_STR_SIZE]; + sprintf(supp, "%s%d", "supp.val=", (int)supp_mv); + BspUartWrite(DISP_OUT, supp, strlen(supp)); + BspUartWrite(DISP_OUT, (char *)terminator, strlen(terminator)); - return DISPLAY_ERR_NONE; + return kDisplayErrNone; } diff --git a/Drivers/Src/Minions.c b/Drivers/Src/Minions.c index b42857275..6a97d03b5 100644 --- a/Drivers/Src/Minions.c +++ b/Drivers/Src/Minions.c @@ -1,40 +1,38 @@ /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file Minions.c - * @brief - * + * @brief + * */ #include "Minions.h" /* Should be in sync with enum in Minions.h */ -const pinInfo_t PININFO_LUT[NUM_PINS] = { - {GPIO_Pin_1, PORTA, INPUT}, - {GPIO_Pin_0, PORTA, INPUT}, - {GPIO_Pin_4, PORTA, INPUT}, - {GPIO_Pin_5, PORTA, INPUT}, - {GPIO_Pin_6, PORTA, INPUT}, - {GPIO_Pin_7, PORTA, INPUT}, - {GPIO_Pin_4, PORTB, INPUT}, - {GPIO_Pin_5, PORTB, OUTPUT} -}; +const PinInfo kPininfoLut[kNumPins] = { + {GPIO_Pin_1, kPortA, kInput}, {GPIO_Pin_0, kPortA, kInput}, + {GPIO_Pin_4, kPortA, kInput}, {GPIO_Pin_5, kPortA, kInput}, + {GPIO_Pin_6, kPortA, kInput}, {GPIO_Pin_7, kPortA, kInput}, + {GPIO_Pin_4, kPortB, kInput}, {GPIO_Pin_5, kPortB, kOutput}}; -void Minions_Init(void){ - for(uint8_t i = 0; i < NUM_PINS; i++){ - BSP_GPIO_Init(PININFO_LUT[i].port, PININFO_LUT[i].pinMask, PININFO_LUT[i].direction); +void MinionsInit(void) { + for (int i = 0; i < kNumPins; i++) { + BspGpioInit(kPininfoLut[i].port, kPininfoLut[i].pin_mask, + kPininfoLut[i].direction); } } -bool Minions_Read(pin_t pin){ - if((PININFO_LUT[pin].direction == INPUT)){ - return (bool) BSP_GPIO_Read_Pin(PININFO_LUT[pin].port, PININFO_LUT[pin].pinMask); - } else{ - return (bool)BSP_GPIO_Get_State(PININFO_LUT[pin].port, PININFO_LUT[pin].pinMask); +bool MinionsRead(Pin pin) { + if ((kPininfoLut[pin].direction == kInput)) { + return (bool)BspGpioReadPin(kPininfoLut[pin].port, + kPininfoLut[pin].pin_mask); } + return (bool)BspGpioGetState(kPininfoLut[pin].port, + kPininfoLut[pin].pin_mask); } -bool Minions_Write(pin_t pin, bool status){ - if(PININFO_LUT[pin].direction == OUTPUT){ - BSP_GPIO_Write_Pin(PININFO_LUT[pin].port, PININFO_LUT[pin].pinMask, status); +bool MinionsWrite(Pin pin, bool status) { + if (kPininfoLut[pin].direction == kOutput) { + BspGpioWritePin(kPininfoLut[pin].port, kPininfoLut[pin].pin_mask, + status); return true; } return false; diff --git a/Drivers/Src/Pedals.c b/Drivers/Src/Pedals.c old mode 100755 new mode 100644 index e28397fdf..770e3fa9a --- a/Drivers/Src/Pedals.c +++ b/Drivers/Src/Pedals.c @@ -1,57 +1,62 @@ /** * @copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar * @file Pedals.c - * @brief - * + * @brief + * */ #include "Pedals.h" // Constants used to tune the pedals -// Indexed using pedal_t +// Indexed using Pedal // Refine in testing -static const int16_t LowerBound[NUMBER_OF_PEDALS] = { - 400, // Accelerator lower bound - 2100, // Brake lower bound +static const int16_t kLowerBound[kNumberOfPedals] = { + 400, // Accelerator lower bound + 2100, // Brake lower bound }; -static const int16_t UpperBound[NUMBER_OF_PEDALS] = { - 900, // Accelerator upper bound - 3300, // Brake upper bound +static const int16_t kUpperBound[kNumberOfPedals] = { + 900, // Accelerator upper bound + 3300, // Brake upper bound }; /** - * @brief Initializes the brake and accelerator by using the - * BSP_ADC_Init function with parameters ACCELERATOR - * and BRAKE + * @brief Initializes the brake and accelerator by using the + * BspAdcInit function with parameters ACCELERATOR + * and BRAKE * @param None * @return None */ -void Pedals_Init(){ - BSP_ADC_Init(); -} +void PedalsInit() { BspAdcInit(); } /** - * @brief Fetches the millivoltage value of the potentiomenter as provided + * @brief Fetches the millivoltage value of the potentiomenter as provided * by the ADC channel of the requested pedal (Accelerator or Brake), - * converts it to a percentage of the total distance pressed using + * converts it to a percentage of the total distance pressed using * data from calibration testing, and returns it - * @param pedal_t, ACCELERATOR or BRAKE as defined in enum + * @param Pedal, ACCELERATOR or BRAKE as defined in enum * @return percent amount the pedal has been pressed in percentage */ -int8_t Pedals_Read(pedal_t pedal){ - if (pedal >= NUMBER_OF_PEDALS) return 0; - int16_t millivoltsPedal = (int16_t) BSP_ADC_Get_Millivoltage(pedal); +int8_t PedalsRead(Pedal pedal) { + if (pedal >= kNumberOfPedals) { + return 0; + } + int16_t millivolts_pedal = + (int16_t)BspAdcGetMillivoltage((pedal == kAccelerator) ? kCh10 : kCh11); int8_t percentage = 0; - - if (millivoltsPedal >= LowerBound[pedal]) { - percentage = (int8_t) ( (int32_t) (millivoltsPedal - LowerBound[pedal]) * 100 / - (UpperBound[pedal] - LowerBound[pedal])); + + if (millivolts_pedal >= kLowerBound[pedal]) { + percentage = (int8_t)((int32_t)(millivolts_pedal - kLowerBound[pedal]) * + 100 / (kUpperBound[pedal] - kLowerBound[pedal])); } - if (percentage > 100) return 100; - if (percentage < 0) return 0; + if (percentage > 100) { + return 100; + } + if (percentage < 0) { + return 0; + } return percentage; } diff --git a/Embedded-Sharepoint b/Embedded-Sharepoint index 7584311df..0d80b95ab 160000 --- a/Embedded-Sharepoint +++ b/Embedded-Sharepoint @@ -1 +1 @@ -Subproject commit 7584311df293c27ac40d60bcb29cb662496a792e +Subproject commit 0d80b95ab47648b09034cc27a8b755bd89a4589b diff --git a/Makefile b/Makefile index 3a5cc919e..a1d76e19c 100644 --- a/Makefile +++ b/Makefile @@ -61,4 +61,10 @@ clean: rm -fR Objects rm -f *.out rm -fr Docs/doxygen - rm -fr Docs/build \ No newline at end of file + rm -fr Docs/build + +tidy: + $(MAKE) -C BSP -C STM32F413 tidy + +format: + $(MAKE) -C BSP -C STM32F413 format From f0227bde39afeb46944a6139e8f601c430cddded Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 20 Jan 2024 12:08:50 -0600 Subject: [PATCH 29/57] Cleaned up driver mocks by including real header to avoid copy-pasting and added #pragma once header guard in mock header files. --- Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h | 76 +------------------ .../UnitTests/Mocks/Drivers/Inc/Contactors.h | 27 +------ Tests/UnitTests/Mocks/Drivers/Inc/Display.h | 70 ++--------------- Tests/UnitTests/Mocks/Drivers/Inc/Minions.h | 35 +-------- Tests/UnitTests/Mocks/Drivers/Inc/Pedals.h | 21 +---- Tests/UnitTests/Mocks/Drivers/Src/CANbus.c | 7 +- .../UnitTests/Mocks/Drivers/Src/Contactors.c | 3 - Tests/UnitTests/Mocks/Drivers/Src/Display.c | 15 ---- Tests/UnitTests/Mocks/Drivers/Src/Minions.c | 2 - Tests/UnitTests/Mocks/Drivers/Src/Pedals.c | 1 - 10 files changed, 20 insertions(+), 237 deletions(-) diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h b/Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h index e4ae5852a..9005f279c 100644 --- a/Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h +++ b/Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h @@ -2,86 +2,14 @@ ////// MOCK ////// ///////////////////////////////////////////// -#ifdef TEST_CANBUS +#pragma once #include_next "CANbus.h" -#else - -#ifndef CAN_H__ -#define CAN_H__ +#ifndef TEST_CANBUS #include "fff.h" -#include "BSP_CAN.h" - - -#define CARCAN CAN_1 //convenience aliases for the CANBuses -#define MOTORCAN CAN_3 - -/** - * This enum is used to signify the ID of the message you want to send. - * It is used internally to index our lookup table (CANLUT.C) and get message-specific fields. - * For user purposes, it selects the message to send. - * - * If changing the order of this enum, make sure to mirror that change in the lookup table, or - * else the driver will not work properly. - * - * If adding new types of CAN messages, add the identifier wherever it fits in - * (the enum is sorted in ascending order on purpose), and then add an entry to the lookup table. - */ -typedef enum { - BPS_TRIP = 0x002, - BPS_CONTACTOR = 0x101, - STATE_OF_CHARGE = 0x106, - SUPPLEMENTAL_VOLTAGE = 0x10B, - MOTOR_DRIVE = 0x221, - MOTOR_POWER = 0x222, - MOTOR_RESET = 0x223, - MOTOR_STATUS = 0x241, - MC_BUS = 0x242, - VELOCITY = 0x243, - MC_PHASE_CURRENT = 0x244, - VOLTAGE_VEC = 0x245, - CURRENT_VEC = 0x246, - BACKEMF = 0x247, - TEMPERATURE = 0x24B, - ODOMETER_AMPHOURS = 0x24E, - ARRAY_CONTACTOR_STATE_CHANGE = 0x24F, - CONTROL_MODE = 0x580, - IO_STATE = 0x581, - MAX_CAN_ID -} CANId_t; - -/** - * @brief Struct to use in CAN MSG LUT - * @param idxEn Whether or not this message is part of a sequence of messages. - * @param size Size of message's data. Should be a maximum of eight (in decimal). - */ -typedef struct { - bool idxEn: 1; - unsigned int size: 7; -} CANLUT_T; - -/** - * Standard CAN packet - * @param ID CANId_t value indicating which message we are trying to send - * @param idx If message is part of a sequence of messages (for messages longer than 64 bits), this indicates the index of the message. - * This is not designed to exceed the 8bit unsigned max value. - * @param data data of the message -*/ -typedef struct { - CANId_t ID; - uint8_t idx; - uint8_t data[8]; -} CANDATA_t; - -//Compatibility macros for deprecated enum -#define CAN_BLOCKING true -#define CAN_NON_BLOCKING false DECLARE_FAKE_VALUE_FUNC(ErrorStatus, CANbus_Init, CAN_t, CANId_t*, uint8_t); - DECLARE_FAKE_VALUE_FUNC(ErrorStatus, CANbus_Send, CANDATA_t, bool, CAN_t); - DECLARE_FAKE_VALUE_FUNC(ErrorStatus, CANbus_Read, CANDATA_t*, bool, CAN_t); -#endif #endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h b/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h index becb65c2a..b616c3834 100644 --- a/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h +++ b/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h @@ -2,33 +2,14 @@ ////// MOCK ////// ///////////////////////////////////////////// -#ifdef TEST_CONTACTORS -#include_next "Contactors.h" // Include the next instance of the file. -// If the real version is in the include search paths after the mock one, it will include it here -#else // Mocked Contactors.h -#ifndef __CONTACTORS_H -#define __CONTACTORS_H +#pragma once +#include_next "Contactors.h" +#ifndef TEST_CONTACTORS #include "fff.h" -#include "common.h" -#include "stm32f4xx_gpio.h" -#include "os.h" - -#define CONTACTORS_PORT PORTC -#define ARRAY_PRECHARGE_BYPASS_PIN GPIO_Pin_10 -#define MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN GPIO_Pin_12 - -#define FOREACH_contactor(contactor) \ - contactor(ARRAY_PRECHARGE_BYPASS_CONTACTOR), \ - contactor(MOTOR_CONTROLLER_PRECHARGE_BYPASS_CONTACTOR), \ - -typedef enum contactor_ENUM { - FOREACH_contactor(GENERATE_ENUM) - NUM_CONTACTORS, -}contactor_t; DECLARE_FAKE_VOID_FUNC(Contactors_Init); DECLARE_FAKE_VALUE_FUNC(bool, Contactors_Get, contactor_t); DECLARE_FAKE_VALUE_FUNC(ErrorStatus, Contactors_Set, contactor_t, bool, bool); #endif -#endif + diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/Display.h b/Tests/UnitTests/Mocks/Drivers/Inc/Display.h index 3bd112235..23b3eb206 100644 --- a/Tests/UnitTests/Mocks/Drivers/Inc/Display.h +++ b/Tests/UnitTests/Mocks/Drivers/Inc/Display.h @@ -1,75 +1,17 @@ -#ifdef TEST_DISPLAY +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#pragma once #include_next "Display.h" -#else -#ifndef __DISPLAY_H -#define __DISPLAY_H +#ifndef TEST_DISPLAY -#include "common.h" // common headers -#include "Tasks.h" #include "fff.h" -#define MAX_ARGS 2 // maximum # of arguments in a command packet - -/** - * Error types - */ -typedef enum{ // Currently only ERR_NONE and ERR_PARSE are used - DISPLAY_ERR_NONE, - DISPLAY_ERR_PARSE, // Error parsing command struct passed to Display_Send - DISPLAY_ERR_INV_INSTR, // Invalid instruction passed to nextion (0x00) - DISPLAY_ERR_INV_COMP, // Invalid component id passed to nextion (0x02) - DISPLAY_ERR_INV_PGID, // Invalid page id passed to nextion (0x03) - DISPLAY_ERR_INV_VAR, // Invalid variable name passed to nextion (0x1A) - DISPLAY_ERR_INV_VAROP, // Invalid variable operation passed to nextion (0x1B) - DISPLAY_ERR_ASSIGN, // Assignment failure nextion (0x1C) - DISPLAY_ERR_PARAMS, // Invalid number of parameters passed to nextion (0x1E) - DISPLAY_ERR_MAX_ARGS, // Command arg list exceeded MAX_ARGS elements - DISPLAY_ERR_OTHER // Other nextion display error -} DisplayError_t; - - -/** - * All three pages on the HMI - */ -typedef enum{ - STARTUP =0, - INFO, - FAULT -} Page_t; - -/** - * Argument types - */ -typedef enum{ - STR_ARG, - INT_ARG -} Arg_e; - -/** - * Packages relevant display command data - */ -typedef struct{ - char* compOrCmd; - char* attr; - char* op; - uint8_t numArgs; - Arg_e argTypes[MAX_ARGS]; // TRUE for integers, FALSE for strings - union{ - char* str; - uint32_t num; - } args[MAX_ARGS]; -} DisplayCmd_t; - - DECLARE_FAKE_VALUE_FUNC(DisplayError_t, Display_Send, DisplayCmd_t); - DECLARE_FAKE_VALUE_FUNC(DisplayError_t, Display_Init); - DECLARE_FAKE_VALUE_FUNC(DisplayError_t, Display_Reset); - DECLARE_FAKE_VALUE_FUNC(DisplayError_t, Display_Error, error_code_t); - DECLARE_FAKE_VALUE_FUNC(DisplayError_t, Display_Evac, uint8_t, uint32_t); #endif -#endif diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h b/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h index e764da880..5869e3fda 100644 --- a/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h +++ b/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h @@ -2,44 +2,13 @@ ////// MOCK ////// ///////////////////////////////////////////// -#ifdef TEST_MINIONS +#pragma once #include_next "Minions.h" -#else +#ifndef TEST_MINIONS -#ifndef MINIONS_H -#define MINIONS_H #include "fff.h" -#include "common.h" -#include -#include "BSP_GPIO.h" - - -// used to index into lookup table -// if changed, PINS_LOOKARR should be changed in Minions.c -#define FOREACH_PIN(PIN) \ - PIN(IGN_1), \ - PIN(IGN_2), \ - PIN(REGEN_SW), \ - PIN(FOR_SW), \ - PIN(REV_SW), \ - PIN(CRUZ_EN), \ - PIN(CRUZ_ST), \ - PIN(BRAKELIGHT), \ - -typedef enum MINIONPIN_ENUM { - FOREACH_PIN(GENERATE_ENUM) - NUM_PINS, -} pin_t; - -typedef struct { - uint16_t pinMask; - port_t port; - direction_t direction; -} pinInfo_t; DECLARE_FAKE_VOID_FUNC(Minions_Init); - DECLARE_FAKE_VALUE_FUNC(bool, Minions_Read, pin_t); -#endif #endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/Pedals.h b/Tests/UnitTests/Mocks/Drivers/Inc/Pedals.h index 89b3d57df..e33814247 100644 --- a/Tests/UnitTests/Mocks/Drivers/Inc/Pedals.h +++ b/Tests/UnitTests/Mocks/Drivers/Inc/Pedals.h @@ -2,30 +2,13 @@ ////// MOCK ////// ///////////////////////////////////////////// -#ifdef TEST_PEDALS +#pragma once #include_next "Pedals.h" -#else +#ifndef TEST_PEDALS -#ifndef __PEDALS_H -#define __PEDALS_H - -#include "BSP_ADC.h" #include "fff.h" -/** - * @brief Stuff - * - */ -typedef enum -{ - ACCELERATOR, - BRAKE, - NUMBER_OF_PEDALS -} pedal_t; - DECLARE_FAKE_VOID_FUNC(Pedals_Init); - DECLARE_FAKE_VALUE_FUNC(int8_t, Pedals_Read, pedal_t); #endif -#endif diff --git a/Tests/UnitTests/Mocks/Drivers/Src/CANbus.c b/Tests/UnitTests/Mocks/Drivers/Src/CANbus.c index fc2a7c56b..b259149b1 100644 --- a/Tests/UnitTests/Mocks/Drivers/Src/CANbus.c +++ b/Tests/UnitTests/Mocks/Drivers/Src/CANbus.c @@ -1,8 +1,9 @@ -#include "fff.h" +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + #include "CANbus.h" DEFINE_FAKE_VALUE_FUNC(ErrorStatus, CANbus_Init, CAN_t, CANId_t*, uint8_t); - DEFINE_FAKE_VALUE_FUNC(ErrorStatus, CANbus_Send, CANDATA_t, bool, CAN_t); - DEFINE_FAKE_VALUE_FUNC(ErrorStatus, CANbus_Read, CANDATA_t*, bool, CAN_t); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c b/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c index 09c5bde45..bb57824d7 100644 --- a/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c +++ b/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c @@ -2,11 +2,8 @@ ////// MOCK ////// ///////////////////////////////////////////// -#include "fff.h" #include "Contactors.h" DEFINE_FAKE_VOID_FUNC(Contactors_Init); - DEFINE_FAKE_VALUE_FUNC(bool, Contactors_Get, contactor_t); - DEFINE_FAKE_VALUE_FUNC(ErrorStatus, Contactors_Set, contactor_t, bool, bool); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Src/Display.c b/Tests/UnitTests/Mocks/Drivers/Src/Display.c index a651293fa..e512b139b 100644 --- a/Tests/UnitTests/Mocks/Drivers/Src/Display.c +++ b/Tests/UnitTests/Mocks/Drivers/Src/Display.c @@ -3,24 +3,9 @@ ///////////////////////////////////////////// #include "Display.h" -#include "bsp.h" // for writing to UART -#include "Tasks.h" // for os and fault error codes -#include "fff.h" - -#define DISP_OUT UART_3 -#define MAX_MSG_LEN 32 -#define MAX_ARG_LEN 16 -// Assignment commands have only 1 arg, an operator, and an attribute -#define isAssignCmd(cmd) (cmd.compOrCmd != NULL && cmd.op != NULL && cmd.attr != NULL && cmd.numArgs == 1) -// Operational commands have no attribute and no operator, just a command and >= 0 arguments -#define isOpCmd(cmd) (cmd.op == NULL && cmd.attr == NULL) DEFINE_FAKE_VALUE_FUNC(DisplayError_t, Display_Send, DisplayCmd_t); - DEFINE_FAKE_VALUE_FUNC(DisplayError_t, Display_Init); - DEFINE_FAKE_VALUE_FUNC(DisplayError_t, Display_Reset); - DEFINE_FAKE_VALUE_FUNC(DisplayError_t, Display_Error, error_code_t); - DEFINE_FAKE_VALUE_FUNC(DisplayError_t, Display_Evac, uint8_t, uint32_t); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Src/Minions.c b/Tests/UnitTests/Mocks/Drivers/Src/Minions.c index 6869f815e..7a71c236c 100644 --- a/Tests/UnitTests/Mocks/Drivers/Src/Minions.c +++ b/Tests/UnitTests/Mocks/Drivers/Src/Minions.c @@ -2,9 +2,7 @@ ////// MOCK ////// ///////////////////////////////////////////// -#include "fff.h" #include "Minions.h" DEFINE_FAKE_VOID_FUNC(Minions_Init); - DEFINE_FAKE_VALUE_FUNC(bool, Minions_Read, pin_t); diff --git a/Tests/UnitTests/Mocks/Drivers/Src/Pedals.c b/Tests/UnitTests/Mocks/Drivers/Src/Pedals.c index 880f7cbc4..d97e784da 100755 --- a/Tests/UnitTests/Mocks/Drivers/Src/Pedals.c +++ b/Tests/UnitTests/Mocks/Drivers/Src/Pedals.c @@ -5,5 +5,4 @@ #include "Pedals.h" DEFINE_FAKE_VOID_FUNC(Pedals_Init); - DEFINE_FAKE_VALUE_FUNC(int8_t, Pedals_Read, pedal_t); \ No newline at end of file From 26f4835898e6551465b437823b7f9050b63ab99c Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 20 Jan 2024 12:24:56 -0600 Subject: [PATCH 30/57] Cleaned up app mocks by including real header to avoid copy-pasting and added #pragma once header guard in mock header files. --- Tests/UnitTests/Mocks/Apps/Inc/ReadCarCAN.h | 23 +--- Tests/UnitTests/Mocks/Apps/Inc/ReadTritium.h | 33 +---- Tests/UnitTests/Mocks/Apps/Inc/SendCarCAN.h | 11 +- Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h | 71 +--------- Tests/UnitTests/Mocks/Apps/Inc/Tasks.h | 122 +----------------- .../UnitTests/Mocks/Apps/Inc/UpdateDisplay.h | 52 +------- Tests/UnitTests/Mocks/Apps/Src/ReadCarCAN.c | 1 - Tests/UnitTests/Mocks/Apps/Src/ReadTritium.c | 2 - Tests/UnitTests/Mocks/Apps/Src/SendCarCAN.c | 3 - Tests/UnitTests/Mocks/Apps/Src/SendTritium.c | 25 ---- Tests/UnitTests/Mocks/Apps/Src/Tasks.c | 29 +---- .../UnitTests/Mocks/Apps/Src/UpdateDisplay.c | 71 +--------- 12 files changed, 26 insertions(+), 417 deletions(-) diff --git a/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCAN.h b/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCAN.h index 49a64a550..ad31466d2 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCAN.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCAN.h @@ -2,31 +2,14 @@ ////// MOCK ////// ///////////////////////////////////////////// -#ifdef TEST_READCARCAN +#pragma once #include_next "ReadCarCAN.h" -#else - -#ifndef __READ_CAR_CAN_H -#define __READ_CAR_CAN_H +#ifndef TEST_READCARCAN #include "fff.h" -#include "common.h" - -/** - * Error types - */ -typedef enum{ - READCARCAN_ERR_NONE, - READCARCAN_ERR_CHARGE_DISABLE, // Received a charge disable msg - READCARCAN_ERR_MISSED_MSG, // Didn't receive a BPS charge msg in time - READCARCAN_ERR_DISABLE_CONTACTORS_MSG, // Ignition is turned to neither (off due to LV) or both at the same time (impossible) are on at - READCARCAN_ERR_BPS_TRIP // Received a BPS trip msg (0 or 1) -} ReadCarCAN_error_code_t; - DECLARE_FAKE_VOID_FUNC(Task_ReadCarCAN, void*); - DECLARE_FAKE_VALUE_FUNC(bool, ChargeEnable_Get); #endif -#endif + diff --git a/Tests/UnitTests/Mocks/Apps/Inc/ReadTritium.h b/Tests/UnitTests/Mocks/Apps/Inc/ReadTritium.h index 6c89a3872..bfe22d849 100755 --- a/Tests/UnitTests/Mocks/Apps/Inc/ReadTritium.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/ReadTritium.h @@ -2,43 +2,14 @@ ////// MOCK ////// ///////////////////////////////////////////// -#ifdef TEST_READTRITIUM +#pragma once #include_next "ReadTritium.h" -#else - -#ifndef __READ_TRITIUM_H -#define __READ_TRITIUM_H +#ifndef TEST_READTRITIUM #include "fff.h" -#include "os.h" -#include "common.h" -#include "Tasks.h" - -/** - * Motor Error States - * Read messages from motor in ReadTritium and trigger appropriate error messages as needed based on bits - * - */ -typedef enum{ - T_HARDWARE_OVER_CURRENT_ERR = (1<<0), - T_SOFTWARE_OVER_CURRENT_ERR = (1<<1), - T_DC_BUS_OVERVOLT_ERR = (1<<2), - T_HALL_SENSOR_ERR = (1<<3), - T_WATCHDOG_LAST_RESET_ERR = (1<<4), - T_CONFIG_READ_ERR = (1<<5), - T_UNDER_VOLTAGE_LOCKOUT_ERR = (1<<6), - T_DESAT_FAULT_ERR = (1<<7), - T_MOTOR_OVER_SPEED_ERR = (1<<8), - T_INIT_FAIL = (1<<9), //motor controller fails to restart or initialize - T_MOTOR_WATCHDOG_TRIP = (1 << 15), - T_NONE = 0x00, -} tritium_error_code_t; DECLARE_FAKE_VOID_FUNC(Task_ReadTritium, void*); - DECLARE_FAKE_VALUE_FUNC(float, Motor_RPM_Get); - DECLARE_FAKE_VALUE_FUNC(float, Motor_Velocity_Get); #endif -#endif diff --git a/Tests/UnitTests/Mocks/Apps/Inc/SendCarCAN.h b/Tests/UnitTests/Mocks/Apps/Inc/SendCarCAN.h index 0d191fb9f..491c18992 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/SendCarCAN.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/SendCarCAN.h @@ -2,21 +2,14 @@ ////// MOCK ////// ///////////////////////////////////////////// -#ifdef TEST_SENDCARCAN +#pragma once #include_next "SendCarCAN.h" -#else - -#ifndef __SENDCARCAN_H -#define __SENDCARCAN_H +#ifndef TEST_SENDCARCAN #include "fff.h" -#include "CANbus.h" DECLARE_FAKE_VOID_FUNC(Task_SendCarCAN, void*); - DECLARE_FAKE_VOID_FUNC(SendCarCAN_Init); - DECLARE_FAKE_VOID_FUNC(SendCarCAN_Put, CANDATA_t); -#endif #endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h b/Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h index 96047b09e..06ec6447a 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h @@ -1,108 +1,43 @@ ///////////////////////////////////////////// ////// MOCK ////// ///////////////////////////////////////////// -#ifdef TEST_SENDTRITIUM -#include_next "SendTritium.h" -#else -#ifndef __SENDTRITIUM_H -#define __SENDTRITIUM_H +#pragma once +#include_next "SendTritium.h" +#ifndef TEST_SENDTRITIUM #include "fff.h" -#include "common.h" - -//#define SENDTRITIUM_PRINT_MES - -#define MOTOR_MSG_PERIOD 100 // in ms -#define FSM_PERIOD 100 // in ms -#define DEBOUNCE_PERIOD 2 // in units of FSM_PERIOD -#define MOTOR_MSG_COUNTER_THRESHOLD (MOTOR_MSG_PERIOD)/(FSM_PERIOD) - -#define FOREACH_Gear(GEAR) \ - GEAR(FORWARD_GEAR), \ - GEAR(NEUTRAL_GEAR), \ - GEAR(REVERSE_GEAR), \ - -typedef enum GEAR_ENUM { - FOREACH_Gear(GENERATE_ENUM) - NUM_GEARS, -} Gear_t; - -// State Names -typedef enum{ - FORWARD_DRIVE, - NEUTRAL_DRIVE, - REVERSE_DRIVE, - RECORD_VELOCITY, - POWERED_CRUISE, - COASTING_CRUISE, - BRAKE_STATE, - ONEPEDAL, - ACCELERATE_CRUISE -} TritiumStateName_t; - -// State Struct for FSM -typedef struct TritiumState{ - TritiumStateName_t name; - void (*stateHandler)(void); - void (*stateDecider)(void); -} TritiumState_t; - DECLARE_FAKE_VOID_FUNC(Task_SendTritium, void*); // Getter functions for local variables in SendTritium.c DECLARE_FAKE_VALUE_FUNC(bool, GetCruiseEnable); - DECLARE_FAKE_VALUE_FUNC(bool, GetCruiseSet); - DECLARE_FAKE_VALUE_FUNC(bool, GetOnePedalEnable); - DECLARE_FAKE_VALUE_FUNC(bool, GetRegenEnable); - DECLARE_FAKE_VALUE_FUNC(uint8_t, GetBrakePedalPercent); - DECLARE_FAKE_VALUE_FUNC(uint8_t, GetAccelPedalPercent); - DECLARE_FAKE_VALUE_FUNC(Gear_t, GetGear); - DECLARE_FAKE_VALUE_FUNC(TritiumState_t, GetState); - DECLARE_FAKE_VALUE_FUNC(float, GetVelocityObserved); - DECLARE_FAKE_VALUE_FUNC(float, GetCruiseVelSetpoint); - DECLARE_FAKE_VALUE_FUNC(float, GetCurrentSetpoint); - DECLARE_FAKE_VALUE_FUNC(float, GetVelocitySetpoint); - // Setter functions for local variables in SendTritium.c #ifdef SENDTRITIUM_EXPOSE_VARS DECLARE_FAKE_VOID_FUNC(SetCruiseEnable, bool); - DECLARE_FAKE_VOID_FUNC(SetCruiseSet, bool); - DECLARE_FAKE_VOID_FUNC(SetOnePedalEnable, bool); - DECLARE_FAKE_VOID_FUNC(SetRegenEnable, bool); - DECLARE_FAKE_VOID_FUNC(SetBrakePedalPercent, uint8_t); - DECLARE_FAKE_VOID_FUNC(SetAccelPedalPercent, uint8_t); - DECLARE_FAKE_VOID_FUNC(SetGear, Gear_t); - DECLARE_FAKE_VOID_FUNC(SetState, TritiumState_t); - DECLARE_FAKE_VOID_FUNC(SetVelocityObserved, float); - DECLARE_FAKE_VOID_FUNC(SetCruiseVelSetpoint, float); - DECLARE_FAKE_VOID_FUNC(SetCurrentSetpoint, float); - DECLARE_FAKE_VOID_FUNC(SetVelocitySetpoint, float); #endif -#endif #endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h b/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h index 0aa364d05..3db864f2d 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h @@ -2,121 +2,11 @@ ////// MOCK ////// ///////////////////////////////////////////// -#ifdef TEST_TASKS +#pragma once #include_next "Tasks.h" -#else -#ifndef __TASKS_H -#define __TASKS_H -#include "fff.h" -#include "os.h" -#include "common.h" - -/** - * Task initialization macro - * @param task name of the task - * @param prio the task's priority - * @param arg the argument to pass to the task - * @param err the local OS_ERR variable - */ - -/** - * Priority Definitions - */ -#define TASK_INIT_PRIO 2 -#define TASK_READ_TRITIUM_PRIO 3 -#define TASK_SEND_TRITIUM_PRIO 4 -#define TASK_READ_CAR_CAN_PRIO 5 -#define TASK_UPDATE_DISPLAY_PRIO 6 -#define TASK_SEND_CAR_CAN_PRIO 7 -#define TASK_DEBUG_DUMP_PRIO 8 -#define TASK_COMMAND_LINE_PRIO 9 - -/** - * Stack Sizes - */ -#define DEFAULT_STACK_SIZE 256 -#define WATERMARK_STACK_LIMIT DEFAULT_STACK_SIZE/2 - -#define TASK_INIT_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_SEND_TRITIUM_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_READ_CAR_CAN_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_UPDATE_DISPLAY_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_READ_TRITIUM_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_SEND_CAR_CAN_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_DEBUG_DUMP_STACK_SIZE DEFAULT_STACK_SIZE -#define TASK_COMMAND_LINE_STACK_SIZE DEFAULT_STACK_SIZE - -/** - * Task error variable type -*/ -typedef uint16_t error_code_t; - -/** - * TCBs - */ -extern OS_TCB Init_TCB; -extern OS_TCB SendTritium_TCB; -extern OS_TCB ReadCarCAN_TCB; -extern OS_TCB UpdateDisplay_TCB; -extern OS_TCB ReadTritium_TCB; -extern OS_TCB SendCarCAN_TCB; -extern OS_TCB DebugDump_TCB; -extern OS_TCB CommandLine_TCB; - - -/** - * Stacks - */ -extern CPU_STK Init_Stk[TASK_INIT_STACK_SIZE]; -extern CPU_STK SendTritium_Stk[TASK_SEND_TRITIUM_STACK_SIZE]; -extern CPU_STK ReadCarCAN_Stk[TASK_READ_CAR_CAN_STACK_SIZE]; -extern CPU_STK UpdateDisplay_Stk[TASK_UPDATE_DISPLAY_STACK_SIZE]; -extern CPU_STK ReadTritium_Stk[TASK_READ_TRITIUM_STACK_SIZE]; -extern CPU_STK SendCarCAN_Stk[TASK_SEND_CAR_CAN_STACK_SIZE]; -extern CPU_STK DebugDump_Stk[TASK_DEBUG_DUMP_STACK_SIZE]; -extern CPU_STK CommandLine_Stk[TASK_COMMAND_LINE_STACK_SIZE]; - -/** - * Queues - */ -extern OS_Q CANBus_MsgQ; +#ifndef TEST_TASKS -/** - * Task trace - * - * Stores the last TASK_TRACE_LENGTH tasks that were run - * The most recent task is at tasks[index], the one before at tasks[index-1], - * wrapping back around at the beginnning - * - */ -#define TASK_TRACE_LENGTH 8 -typedef struct { - OS_TCB *tasks[TASK_TRACE_LENGTH]; - uint32_t index; -} task_trace_t; - -extern task_trace_t PrevTasks; - -// Store error codes that are set in task error assertion functions -extern error_code_t Error_ReadTritium; -extern error_code_t Error_ReadCarCAN; -extern error_code_t Error_UpdateDisplay; - -/** - * Error-handling option enums -*/ - -// Scheduler lock parameter option for asserting a task error -typedef enum { - OPT_NO_LOCK_SCHED, - OPT_LOCK_SCHED -} error_scheduler_lock_opt_t; - -// Recoverable/nonrecoverable parameter option for asserting a task error -typedef enum { - OPT_RECOV, - OPT_NONRECOV -} error_recov_opt_t; +#include "fff.h" #ifndef TEST_MAIN DECLARE_FAKE_VOID_FUNC(Task_Init, void *); @@ -137,12 +27,8 @@ void Task_CommandLine(void* p_arg); #endif DECLARE_FAKE_VOID_FUNC(TaskSwHook_Init); - DECLARE_FAKE_VOID_FUNC(EmergencyContactorOpen); - DECLARE_FAKE_VOID_FUNC(throwTaskError, error_code_t, callback_t, error_scheduler_lock_opt_t, error_recov_opt_t); +DECLARE_FAKE_VOID_FUNC(_assertOSError, OS_ERR); -DECLARE_FAKE_VOID_FUNC(assertOSError, OS_ERR); - -#endif #endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h b/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h index 78ea27536..6bab7bf77 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h @@ -1,68 +1,24 @@ ///////////////////////////////////////////// ////// MOCK ////// ///////////////////////////////////////////// -#ifdef TEST_UPDATEDISPLAY + +#pragma once #include_next "UpdateDisplay.h" -#else -#ifndef __UPDATE_DISPLAY_H -#define __UPDATE_DISPLAY_H +#ifndef TEST_UPDATEDISPLAY -#include "common.h" -#include "Display.h" #include "fff.h" -/** - * Error types - */ -typedef enum{ - UPDATEDISPLAY_ERR_NONE, - UPDATEDISPLAY_ERR_FIFO_PUT, // Error putting command in fifo - UPDATEDISPLAY_ERR_FIFO_POP, // Error popping command from fifo - UPDATEDISPLAY_ERR_PARSE_COMP, // Error parsing component/val in SetComponent - UPDATEDISPLAY_ERR_DRIVER // Driver call returned an error -} UpdateDisplayError_t; - -/** - * For display elements with three states - */ -typedef enum{ - STATE_0 =0, - STATE_1 =1, - STATE_2 =2 -} TriState_t; - -// For cruise control and regen -#define DISP_DISABLED STATE_0 -#define DISP_ENABLED STATE_1 // Able to be used -#define DISP_ACTIVE STATE_2 // Actively being used right now - -// For gear changes -#define DISP_NEUTRAL STATE_0 -#define DISP_FORWARD STATE_1 -#define DISP_REVERSE STATE_2 - DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_Init); - DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetPage, Page_t); - DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetSOC, uint8_t); - DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetSBPV, uint32_t); - DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetVelocity, uint32_t); - DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetAccel, uint8_t); - DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetArray, bool); - DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetMotor, bool); - DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetGear, TriState_t); - DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetRegenState, TriState_t); - DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetCruiseState, TriState_t); - DECLARE_FAKE_VOID_FUNC(UpdateDisplay_ClearQueue); -#endif + #endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Src/ReadCarCAN.c b/Tests/UnitTests/Mocks/Apps/Src/ReadCarCAN.c index c98411ede..71bdaaf14 100644 --- a/Tests/UnitTests/Mocks/Apps/Src/ReadCarCAN.c +++ b/Tests/UnitTests/Mocks/Apps/Src/ReadCarCAN.c @@ -5,5 +5,4 @@ #include "ReadCarCAN.h" DEFINE_FAKE_VOID_FUNC(Task_ReadCarCAN, void*); - DEFINE_FAKE_VALUE_FUNC(bool, ChargeEnable_Get); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Src/ReadTritium.c b/Tests/UnitTests/Mocks/Apps/Src/ReadTritium.c index 60626bb08..9bfd5fa99 100755 --- a/Tests/UnitTests/Mocks/Apps/Src/ReadTritium.c +++ b/Tests/UnitTests/Mocks/Apps/Src/ReadTritium.c @@ -5,7 +5,5 @@ #include "ReadTritium.h" DEFINE_FAKE_VOID_FUNC(Task_ReadTritium, void*); - DEFINE_FAKE_VALUE_FUNC(float, Motor_RPM_Get); - DEFINE_FAKE_VALUE_FUNC(float, Motor_Velocity_Get); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Src/SendCarCAN.c b/Tests/UnitTests/Mocks/Apps/Src/SendCarCAN.c index f32cf26cc..79dee8f1d 100644 --- a/Tests/UnitTests/Mocks/Apps/Src/SendCarCAN.c +++ b/Tests/UnitTests/Mocks/Apps/Src/SendCarCAN.c @@ -4,9 +4,6 @@ #include "SendCarCAN.h" - DEFINE_FAKE_VOID_FUNC(Task_SendCarCAN, void*); - DEFINE_FAKE_VOID_FUNC(SendCarCAN_Init); - DEFINE_FAKE_VOID_FUNC(SendCarCAN_Put, CANDATA_t); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Src/SendTritium.c b/Tests/UnitTests/Mocks/Apps/Src/SendTritium.c index af89fd3a2..fb2b0a049 100644 --- a/Tests/UnitTests/Mocks/Apps/Src/SendTritium.c +++ b/Tests/UnitTests/Mocks/Apps/Src/SendTritium.c @@ -3,57 +3,32 @@ ///////////////////////////////////////////// #include "SendTritium.h" -#include "CANConfig.h" -#include "common.h" DEFINE_FAKE_VOID_FUNC(Task_SendTritium, void*); - DEFINE_FAKE_VALUE_FUNC(bool, GetCruiseEnable); - DEFINE_FAKE_VALUE_FUNC(bool, GetCruiseSet); - DEFINE_FAKE_VALUE_FUNC(bool, GetOnePedalEnable); - DEFINE_FAKE_VALUE_FUNC(bool, GetRegenEnable); - DEFINE_FAKE_VALUE_FUNC(uint8_t, GetBrakePedalPercent); - DEFINE_FAKE_VALUE_FUNC(uint8_t, GetAccelPedalPercent); - DEFINE_FAKE_VALUE_FUNC(Gear_t, GetGear); - DEFINE_FAKE_VALUE_FUNC(TritiumState_t, GetState); - DEFINE_FAKE_VALUE_FUNC(float, GetVelocityObserved); - DEFINE_FAKE_VALUE_FUNC(float, GetCruiseVelSetpoint); - DEFINE_FAKE_VALUE_FUNC(float, GetCurrentSetpoint); - DEFINE_FAKE_VALUE_FUNC(float, GetVelocitySetpoint); #ifdef SENDTRITIUM_EXPOSE_VARS DEFINE_FAKE_VOID_FUNC(SetCruiseEnable, bool); - DEFINE_FAKE_VOID_FUNC(SetCruiseSet, bool); - DEFINE_FAKE_VOID_FUNC(SetOnePedalEnable, bool); - DEFINE_FAKE_VOID_FUNC(SetRegenEnable, bool); - DEFINE_FAKE_VOID_FUNC(SetBrakePedalPercent, uint8_t); - DEFINE_FAKE_VOID_FUNC(SetAccelPedalPercent, uint8_t); - DEFINE_FAKE_VOID_FUNC(SetGear, Gear_t); - DEFINE_FAKE_VOID_FUNC(SetState, TritiumState_t); - DEFINE_FAKE_VOID_FUNC(SetVelocityObserved, float); - DEFINE_FAKE_VOID_FUNC(SetCruiseVelSetpoint, float); - DEFINE_FAKE_VOID_FUNC(SetCurrentSetpoint, float); - DEFINE_FAKE_VOID_FUNC(SetVelocitySetpoint, float); #endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Src/Tasks.c b/Tests/UnitTests/Mocks/Apps/Src/Tasks.c index 61191f959..1e623d188 100644 --- a/Tests/UnitTests/Mocks/Apps/Src/Tasks.c +++ b/Tests/UnitTests/Mocks/Apps/Src/Tasks.c @@ -1,31 +1,17 @@ ///////////////////////////////////////////// ////// MOCK ////// ///////////////////////////////////////////// -#include "fff.h" + #include "Tasks.h" -#include "Minions.h" + +#include "ReadTritium.h" #include "ReadCarCAN.h" #include "UpdateDisplay.h" -#include "ReadTritium.h" - -/** - * TCBs - */ -OS_TCB Init_TCB; -OS_TCB SendTritium_TCB; -OS_TCB ReadCarCAN_TCB; -OS_TCB UpdateDisplay_TCB; -OS_TCB ReadTritium_TCB; -OS_TCB SendCarCAN_TCB; -OS_TCB DebugDump_TCB; -OS_TCB CommandLine_TCB; -error_code_t Error_ReadCarCAN = READCARCAN_ERR_NONE; -error_code_t Error_ReadTritium = T_NONE; +error_code_t Error_ReadCarCAN = READCARCAN_ERR_NONE; // TODO: change this back to the error +error_code_t Error_ReadTritium = T_NONE; // Initialized to no error error_code_t Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; -extern const pinInfo_t PININFO_LUT[]; // For GPIO writes. Externed from Minions Driver C file. - #ifndef TEST_MAIN DEFINE_FAKE_VOID_FUNC(Task_Init, void*); #endif @@ -39,9 +25,6 @@ DEFINE_FAKE_VOID_FUNC(Task_CommandLine, void*); #endif DEFINE_FAKE_VOID_FUNC(TaskSwHook_Init); - DEFINE_FAKE_VOID_FUNC(EmergencyContactorOpen); - DEFINE_FAKE_VOID_FUNC(throwTaskError, error_code_t, callback_t, error_scheduler_lock_opt_t, error_recov_opt_t); - -DEFINE_FAKE_VOID_FUNC(assertOSError, OS_ERR); +DEFINE_FAKE_VOID_FUNC(_assertOSError, OS_ERR); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c b/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c index bf9091ae2..9fe32e50b 100644 --- a/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c +++ b/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c @@ -1,85 +1,18 @@ ///////////////////////////////////////////// ////// MOCK ////// ///////////////////////////////////////////// -#include "UpdateDisplay.h" -#include "Minions.h" -#include -#include "fff.h" - -/** - * Creates queue for display commands. - */ -#define DISP_Q_SIZE 10 - -#define FIFO_TYPE DisplayCmd_t -#define FIFO_SIZE DISP_Q_SIZE -#define FIFO_NAME disp_fifo -#include "fifo.h" - -// For fault handling -#define RESTART_THRESHOLD 3 // number of times to reset before displaying the fault screen - -disp_fifo_t msg_queue; - -/** - * Enum and corresponding array for easy component selection. - */ -typedef enum{ - // Boolean components - ARRAY=0, - MOTOR, - // Non-boolean components - VELOCITY, - ACCEL_METER, - SOC, - SUPP_BATT, - CRUISE_ST, - REGEN_ST, - GEAR, - // Fault code components - OS_CODE, - FAULT_CODE -} Component_t; - -const char* compStrings[15]= { - // Boolean components - "arr", - "mot", - // Non-boolean components - "vel", - "accel", - "soc", - "supp", - "cruiseSt", - "rbsSt", - "gear", - // Fault code components - "oserr", - "faulterr" -}; +#include "UpdateDisplay.h" DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_Init); - DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetPage, Page_t); - DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetSOC, uint8_t); - DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetSBPV, uint32_t); - DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetVelocity, uint32_t); - DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetAccel, uint8_t); - DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetArray, bool); - DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetMotor, bool); - DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetGear, TriState_t); - DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetRegenState, TriState_t); - DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError_t, UpdateDisplay_SetCruiseState, TriState_t); - -DEFINE_FAKE_VOID_FUNC(UpdateDisplay_ClearQueue); - +DEFINE_FAKE_VOID_FUNC(UpdateDisplay_ClearQueue); \ No newline at end of file From 21ddd2b91cad4c45a7b13613657c146ee5b6b30b Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Sat, 20 Jan 2024 20:29:11 +0000 Subject: [PATCH 31/57] Cleaned and deleted shared initializations by including it from non-mocked header files first --- Makefile | 5 +- Tests/UnitTests/Makefile | 9 + Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h | 13 +- Tests/UnitTests/Mocks/BSP/Inc/BSP_CAN.h | 16 +- Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h | 26 +- Tests/UnitTests/Mocks/BSP/Inc/BSP_SPI.h | 16 +- Tests/UnitTests/Mocks/BSP/Inc/BSP_UART.h | 17 +- Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h | 36 -- .../UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h | 530 +----------------- Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c | 8 +- Tests/UnitTests/Mocks/BSP/Src/BSP_CAN.c | 4 - Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c | 10 +- Tests/UnitTests/Mocks/BSP/Src/BSP_SPI.c | 4 - Tests/UnitTests/Mocks/BSP/Src/BSP_UART.c | 5 - .../UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c | 14 - Tests/UnitTests/Tests/Test_Contactors.c | 2 - Tests/UnitTests/Tests/Test_SendTritium.c | 70 +++ 17 files changed, 110 insertions(+), 675 deletions(-) delete mode 100644 Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h create mode 100644 Tests/UnitTests/Tests/Test_SendTritium.c diff --git a/Makefile b/Makefile index 7d5bfa4f3..f444d0990 100644 --- a/Makefile +++ b/Makefile @@ -25,8 +25,9 @@ else endif #Check if unit test file exists (just to inform user if it isn't found) -ifneq (,$(wildcard Tests/UnitTests/Test_$(TEST).c)) - UNITTEST ?= Tests/UnitTests/Test_$(TEST).c +#UNITTEST is solely used for echoing purposes +ifneq (,$(wildcard Tests/UnitTests/Tests/Test_$(TEST).c)) + UNITTEST ?= Tests/UnitTests/Tests/Test_$(TEST).c else UNITTEST ?= no test found endif diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index 3e61d2892..04e37a3e6 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -59,6 +59,9 @@ C_INCLUDES := \ -I../../Apps/Inc \ -I../../Drivers/Inc \ -I../../BSP/Inc \ +-I../../BSP/STM32F413/STM32F4xx_StdPeriph_Driver/Inc \ +-I../../CMSIS/Device/ST/STM32F4xx/Include \ +-I../../CMSIS/Include \ -I../../Config/Inc \ -I../../Tests/UnitTests \ -I../../Tests/UnitTests/Unity \ @@ -71,6 +74,12 @@ C_INCLUDES := \ $(foreach src,$(C_INCLUDES),$(info --- $(src))) +# C defines +C_DEFS = \ +-DSTM32F413_423xx + +CFLAGS += $(C_DEFS) + ifeq ($(DEBUG), 1) CFLAGS += -g3 -gdwarf-2 -DDEBUG endif diff --git a/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h b/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h index 43f3707ab..329599444 100644 --- a/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h +++ b/Tests/UnitTests/Mocks/BSP/Inc/BSP_ADC.h @@ -1,16 +1,11 @@ ///////////////////////////////////////////// ////// MOCK ////// ///////////////////////////////////////////// -#ifndef __BSP_ADC_H -#define __BSP_ADC_H -#include "common.h" +#pragma once +#include_next "BSP_ADC.h" #include "fff.h" - - DECLARE_FAKE_VOID_FUNC(BSP_ADC_Init); -DECLARE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Millivoltage, int); -DECLARE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Value, int); - -#endif \ No newline at end of file +DECLARE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Millivoltage, ADC_t); +DECLARE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Value, ADC_t); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Inc/BSP_CAN.h b/Tests/UnitTests/Mocks/BSP/Inc/BSP_CAN.h index a4f98b09d..e58be274c 100644 --- a/Tests/UnitTests/Mocks/BSP/Inc/BSP_CAN.h +++ b/Tests/UnitTests/Mocks/BSP/Inc/BSP_CAN.h @@ -2,20 +2,10 @@ ////// MOCK ////// ///////////////////////////////////////////// -#ifndef __BSP_CAN_H -#define __BSP_CAN_H - +#pragma once +#include_next "BSP_CAN.h" #include "fff.h" -#include "common.h" -#include "config.h" -//#include - -typedef enum {CAN_1=0, CAN_3, NUM_CAN} CAN_t; DECLARE_FAKE_VOID_FUNC(BSP_CAN_Init, CAN_t, callback_t, callback_t, uint16_t*, uint8_t); - DECLARE_FAKE_VALUE_FUNC(ErrorStatus, BSP_CAN_Write, CAN_t, uint32_t, uint8_t*, uint8_t); - -DECLARE_FAKE_VALUE_FUNC(ErrorStatus, BSP_CAN_Read, CAN_t, uint32_t*, uint8_t*); - -#endif +DECLARE_FAKE_VALUE_FUNC(ErrorStatus, BSP_CAN_Read, CAN_t, uint32_t*, uint8_t*); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h b/Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h index 0d00f6085..1d5b92466 100644 --- a/Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h +++ b/Tests/UnitTests/Mocks/BSP/Inc/BSP_GPIO.h @@ -1,28 +1,14 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// -#ifndef __BSP_GPIO_H -#define __BSP_GPIO_H - -#include "common.h" +#pragma once +#include_next "BSP_GPIO.h" #include "fff.h" - -typedef enum {PORTA = 0, PORTB, PORTC, PORTD, NUM_PORTS} port_t; -typedef enum {INPUT = 0, OUTPUT} direction_t; - DECLARE_FAKE_VOID_FUNC(BSP_GPIO_Init, port_t, uint16_t, direction_t); - DECLARE_FAKE_VALUE_FUNC(uint16_t, BSP_GPIO_Read, port_t); - DECLARE_FAKE_VOID_FUNC(BSP_GPIO_Write, port_t, uint16_t); - DECLARE_FAKE_VALUE_FUNC(uint8_t, BSP_GPIO_Read_Pin, port_t, uint16_t); - DECLARE_FAKE_VOID_FUNC(BSP_GPIO_Write_Pin, port_t, uint16_t, bool); - -DECLARE_FAKE_VALUE_FUNC(uint8_t, BSP_GPIO_Get_State, port_t, uint16_t); - - -#endif - - -/* @} */ +DECLARE_FAKE_VALUE_FUNC(uint8_t, BSP_GPIO_Get_State, port_t, uint16_t); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Inc/BSP_SPI.h b/Tests/UnitTests/Mocks/BSP/Inc/BSP_SPI.h index 80801863b..a3f96da97 100644 --- a/Tests/UnitTests/Mocks/BSP/Inc/BSP_SPI.h +++ b/Tests/UnitTests/Mocks/BSP/Inc/BSP_SPI.h @@ -2,20 +2,10 @@ ////// MOCK ////// ///////////////////////////////////////////// -#ifndef __BSP_SPI_H -#define __BSP_SPI_H - +#pragma once +#include_next "BSP_SPI.h" #include "fff.h" -#include "common.h" - - DECLARE_FAKE_VOID_FUNC(BSP_SPI_Init); - DECLARE_FAKE_VOID_FUNC(BSP_SPI_Write, uint8_t*, uint8_t); - -DECLARE_FAKE_VOID_FUNC(BSP_SPI_Read, uint8_t*, uint8_t); - -#endif - - +DECLARE_FAKE_VOID_FUNC(BSP_SPI_Read, uint8_t*, uint8_t); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Inc/BSP_UART.h b/Tests/UnitTests/Mocks/BSP/Inc/BSP_UART.h index 15c9dd999..baf1331b1 100644 --- a/Tests/UnitTests/Mocks/BSP/Inc/BSP_UART.h +++ b/Tests/UnitTests/Mocks/BSP/Inc/BSP_UART.h @@ -2,21 +2,10 @@ ////// MOCK ////// ///////////////////////////////////////////// -#ifndef __BSP_UART_H -#define __BSP_UART_H - +#pragma once +#include_next "BSP_UART.h" #include "fff.h" -#include "common.h" -//#include - -typedef enum {UART_2, UART_3, NUM_UART} UART_t; DECLARE_FAKE_VOID_FUNC(BSP_UART_Init, UART_t); - DECLARE_FAKE_VALUE_FUNC(uint32_t, BSP_UART_Read, UART_t, char*); - -DECLARE_FAKE_VALUE_FUNC(uint32_t, BSP_UART_Write, UART_t, char*, uint32_t); - -#endif - - +DECLARE_FAKE_VALUE_FUNC(uint32_t, BSP_UART_Write, UART_t, char*, uint32_t); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h b/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h deleted file mode 100644 index 01e1d4f9e..000000000 --- a/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx.h +++ /dev/null @@ -1,36 +0,0 @@ - -///////////////////////////////////////////// -////// MOCK ////// -///////////////////////////////////////////// - -#ifndef __STM32F4xx_H -#define __STM32F4xx_H - -#include - - -#ifndef __CONFIG_H -typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; -#endif - -#define __IO volatile - -/** - * @brief General Purpose I/O - */ - -typedef struct -{ - __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ - __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ - __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ - __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ - __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ - __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ - __IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */ - __IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */ - __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ - __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ -} GPIO_TypeDef; - -#endif diff --git a/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h b/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h index fc1368098..c9c066b8c 100644 --- a/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h +++ b/Tests/UnitTests/Mocks/BSP/Inc/stm32f4xx_gpio.h @@ -1,530 +1,15 @@ -//////// MOCK ///////////////// +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_GPIO_H -#define __STM32F4xx_GPIO_H +#pragma once +#include_next "stm32f4xx_gpio.h" +#include "fff.h" #ifdef __cplusplus extern "C" { #endif -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx.h" -#include "fff.h" - -/** @addtogroup STM32F4xx_StdPeriph_Driver - * @{ - */ - -/** @addtogroup GPIO - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ - -#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) || \ - ((PERIPH) == GPIOB) || \ - ((PERIPH) == GPIOC) || \ - ((PERIPH) == GPIOD) || \ - ((PERIPH) == GPIOE) || \ - ((PERIPH) == GPIOF) || \ - ((PERIPH) == GPIOG) || \ - ((PERIPH) == GPIOH) || \ - ((PERIPH) == GPIOI) || \ - ((PERIPH) == GPIOJ) || \ - ((PERIPH) == GPIOK)) - -/** - * @brief GPIO Configuration Mode enumeration - */ -typedef enum -{ - GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ - GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ - GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ - GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */ -}GPIOMode_TypeDef; -#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN) || ((MODE) == GPIO_Mode_OUT) || \ - ((MODE) == GPIO_Mode_AF)|| ((MODE) == GPIO_Mode_AN)) - -/** - * @brief GPIO Output type enumeration - */ -typedef enum -{ - GPIO_OType_PP = 0x00, - GPIO_OType_OD = 0x01 -}GPIOOType_TypeDef; -#define IS_GPIO_OTYPE(OTYPE) (((OTYPE) == GPIO_OType_PP) || ((OTYPE) == GPIO_OType_OD)) - - -/** - * @brief GPIO Output Maximum frequency enumeration - */ -typedef enum -{ - GPIO_Low_Speed = 0x00, /*!< Low speed */ - GPIO_Medium_Speed = 0x01, /*!< Medium speed */ - GPIO_Fast_Speed = 0x02, /*!< Fast speed */ - GPIO_High_Speed = 0x03 /*!< High speed */ -}GPIOSpeed_TypeDef; - -/* Add legacy definition */ -#define GPIO_Speed_2MHz GPIO_Low_Speed -#define GPIO_Speed_25MHz GPIO_Medium_Speed -#define GPIO_Speed_50MHz GPIO_Fast_Speed -#define GPIO_Speed_100MHz GPIO_High_Speed - -#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_Low_Speed) || ((SPEED) == GPIO_Medium_Speed) || \ - ((SPEED) == GPIO_Fast_Speed)|| ((SPEED) == GPIO_High_Speed)) - -/** - * @brief GPIO Configuration PullUp PullDown enumeration - */ -typedef enum -{ - GPIO_PuPd_NOPULL = 0x00, - GPIO_PuPd_UP = 0x01, - GPIO_PuPd_DOWN = 0x02 -}GPIOPuPd_TypeDef; -#define IS_GPIO_PUPD(PUPD) (((PUPD) == GPIO_PuPd_NOPULL) || ((PUPD) == GPIO_PuPd_UP) || \ - ((PUPD) == GPIO_PuPd_DOWN)) - -/** - * @brief GPIO Bit SET and Bit RESET enumeration - */ -typedef enum -{ - Bit_RESET = 0, - Bit_SET -}BitAction; -#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) - - -/** - * @brief GPIO Init structure definition - */ -typedef struct -{ - uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured. - This parameter can be any value of @ref GPIO_pins_define */ - - GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. - This parameter can be a value of @ref GPIOMode_TypeDef */ - - GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins. - This parameter can be a value of @ref GPIOSpeed_TypeDef */ - - GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins. - This parameter can be a value of @ref GPIOOType_TypeDef */ - - GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. - This parameter can be a value of @ref GPIOPuPd_TypeDef */ -}GPIO_InitTypeDef; - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup GPIO_Exported_Constants - * @{ - */ - -/** @defgroup GPIO_pins_define - * @{ - */ -#define GPIO_Pin_0 ((uint16_t)0x0001) /* Pin 0 selected */ -#define GPIO_Pin_1 ((uint16_t)0x0002) /* Pin 1 selected */ -#define GPIO_Pin_2 ((uint16_t)0x0004) /* Pin 2 selected */ -#define GPIO_Pin_3 ((uint16_t)0x0008) /* Pin 3 selected */ -#define GPIO_Pin_4 ((uint16_t)0x0010) /* Pin 4 selected */ -#define GPIO_Pin_5 ((uint16_t)0x0020) /* Pin 5 selected */ -#define GPIO_Pin_6 ((uint16_t)0x0040) /* Pin 6 selected */ -#define GPIO_Pin_7 ((uint16_t)0x0080) /* Pin 7 selected */ -#define GPIO_Pin_8 ((uint16_t)0x0100) /* Pin 8 selected */ -#define GPIO_Pin_9 ((uint16_t)0x0200) /* Pin 9 selected */ -#define GPIO_Pin_10 ((uint16_t)0x0400) /* Pin 10 selected */ -#define GPIO_Pin_11 ((uint16_t)0x0800) /* Pin 11 selected */ -#define GPIO_Pin_12 ((uint16_t)0x1000) /* Pin 12 selected */ -#define GPIO_Pin_13 ((uint16_t)0x2000) /* Pin 13 selected */ -#define GPIO_Pin_14 ((uint16_t)0x4000) /* Pin 14 selected */ -#define GPIO_Pin_15 ((uint16_t)0x8000) /* Pin 15 selected */ -#define GPIO_Pin_All ((uint16_t)0xFFFF) /* All pins selected */ - -#define GPIO_PIN_MASK ((uint32_t)0x0000FFFF) /* PIN mask for assert test */ -#define IS_GPIO_PIN(PIN) (((PIN) & GPIO_PIN_MASK ) != (uint32_t)0x00) -#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \ - ((PIN) == GPIO_Pin_1) || \ - ((PIN) == GPIO_Pin_2) || \ - ((PIN) == GPIO_Pin_3) || \ - ((PIN) == GPIO_Pin_4) || \ - ((PIN) == GPIO_Pin_5) || \ - ((PIN) == GPIO_Pin_6) || \ - ((PIN) == GPIO_Pin_7) || \ - ((PIN) == GPIO_Pin_8) || \ - ((PIN) == GPIO_Pin_9) || \ - ((PIN) == GPIO_Pin_10) || \ - ((PIN) == GPIO_Pin_11) || \ - ((PIN) == GPIO_Pin_12) || \ - ((PIN) == GPIO_Pin_13) || \ - ((PIN) == GPIO_Pin_14) || \ - ((PIN) == GPIO_Pin_15)) -/** - * @} - */ - - -/** @defgroup GPIO_Pin_sources - * @{ - */ -#define GPIO_PinSource0 ((uint8_t)0x00) -#define GPIO_PinSource1 ((uint8_t)0x01) -#define GPIO_PinSource2 ((uint8_t)0x02) -#define GPIO_PinSource3 ((uint8_t)0x03) -#define GPIO_PinSource4 ((uint8_t)0x04) -#define GPIO_PinSource5 ((uint8_t)0x05) -#define GPIO_PinSource6 ((uint8_t)0x06) -#define GPIO_PinSource7 ((uint8_t)0x07) -#define GPIO_PinSource8 ((uint8_t)0x08) -#define GPIO_PinSource9 ((uint8_t)0x09) -#define GPIO_PinSource10 ((uint8_t)0x0A) -#define GPIO_PinSource11 ((uint8_t)0x0B) -#define GPIO_PinSource12 ((uint8_t)0x0C) -#define GPIO_PinSource13 ((uint8_t)0x0D) -#define GPIO_PinSource14 ((uint8_t)0x0E) -#define GPIO_PinSource15 ((uint8_t)0x0F) - -#define IS_GPIO_PIN_SOURCE(PINSOURCE) (((PINSOURCE) == GPIO_PinSource0) || \ - ((PINSOURCE) == GPIO_PinSource1) || \ - ((PINSOURCE) == GPIO_PinSource2) || \ - ((PINSOURCE) == GPIO_PinSource3) || \ - ((PINSOURCE) == GPIO_PinSource4) || \ - ((PINSOURCE) == GPIO_PinSource5) || \ - ((PINSOURCE) == GPIO_PinSource6) || \ - ((PINSOURCE) == GPIO_PinSource7) || \ - ((PINSOURCE) == GPIO_PinSource8) || \ - ((PINSOURCE) == GPIO_PinSource9) || \ - ((PINSOURCE) == GPIO_PinSource10) || \ - ((PINSOURCE) == GPIO_PinSource11) || \ - ((PINSOURCE) == GPIO_PinSource12) || \ - ((PINSOURCE) == GPIO_PinSource13) || \ - ((PINSOURCE) == GPIO_PinSource14) || \ - ((PINSOURCE) == GPIO_PinSource15)) -/** - * @} - */ - -/** @defgroup GPIO_Alternat_function_selection_define - * @{ - */ -/** - * @brief AF 0 selection - */ -#define GPIO_AF_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ -#define GPIO_AF_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ -#define GPIO_AF_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ -#define GPIO_AF_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ -#define GPIO_AF_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ -#if defined(STM32F446xx) -#define GPIO_AF0_TIM2 ((uint8_t)0x00) /* TIM2 Alternate Function mapping */ -#endif /* STM32F446xx */ - -/** - * @brief AF 1 selection - */ -#define GPIO_AF_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ -#define GPIO_AF_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ -#if defined(STM32F410xx) || defined(STM32F413_423xx) -#define GPIO_AF_LPTIM ((uint8_t)0x01) /* LPTIM Alternate Function mapping */ -#endif /* STM32F410xx || STM32F413_423xx */ -/** - * @brief AF 2 selection - */ -#define GPIO_AF_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ -#define GPIO_AF_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ -#define GPIO_AF_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ - -/** - * @brief AF 3 selection - */ -#define GPIO_AF_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */ -#define GPIO_AF_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */ -#define GPIO_AF_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */ -#define GPIO_AF_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */ -#if defined(STM32F446xx) -#define GPIO_AF3_CEC ((uint8_t)0x03) /* CEC Alternate Function mapping */ -#endif /* STM32F446xx */ -#if defined(STM32F413_423xx) -#define GPIO_AF3_DFSDM2 ((uint8_t)0x03) /* DFSDM2 Alternate Function mapping */ -#endif /* STM32F413_423xx */ -/** - * @brief AF 4 selection - */ -#define GPIO_AF_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ -#define GPIO_AF_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ -#define GPIO_AF_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ -#if defined(STM32F446xx) -#define GPIO_AF4_CEC ((uint8_t)0x04) /* CEC Alternate Function mapping */ -#endif /* STM32F446xx */ -#if defined(STM32F410xx) || defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) -#define GPIO_AF_FMPI2C ((uint8_t)0x04) /* FMPI2C Alternate Function mapping */ -#endif /* STM32F410xx || STM32F446xx */ - -/** - * @brief AF 5 selection - */ -#define GPIO_AF_SPI1 ((uint8_t)0x05) /* SPI1/I2S1 Alternate Function mapping */ -#define GPIO_AF_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */ -#define GPIO_AF5_SPI3 ((uint8_t)0x05) /* SPI3/I2S3 Alternate Function mapping (Only for STM32F411xE and STM32F413_423xx Devices) */ -#define GPIO_AF_SPI4 ((uint8_t)0x05) /* SPI4/I2S4 Alternate Function mapping */ -#define GPIO_AF_SPI5 ((uint8_t)0x05) /* SPI5 Alternate Function mapping */ -#define GPIO_AF_SPI6 ((uint8_t)0x05) /* SPI6 Alternate Function mapping */ - -/** - * @brief AF 6 selection - */ -#define GPIO_AF_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */ -#define GPIO_AF6_SPI1 ((uint8_t)0x06) /* SPI1 Alternate Function mapping (Only for STM32F410xx Devices) */ -#define GPIO_AF6_SPI2 ((uint8_t)0x06) /* SPI2 Alternate Function mapping (Only for STM32F410xx/STM32F411xE Devices) */ -#define GPIO_AF6_SPI4 ((uint8_t)0x06) /* SPI4 Alternate Function mapping (Only for STM32F411xE Devices) */ -#define GPIO_AF6_SPI5 ((uint8_t)0x06) /* SPI5 Alternate Function mapping (Only for STM32F410xx/STM32F411xE Devices) */ -#define GPIO_AF_SAI1 ((uint8_t)0x06) /* SAI1 Alternate Function mapping */ -#define GPIO_AF_I2S2ext ((uint8_t)0x06) /* I2S2ext_SD Alternate Function mapping (only for STM32F412xG and STM32F413_423xx Devices) */ -#if defined(STM32F412xG) || defined(STM32F413_423xx) -#define GPIO_AF6_DFSDM1 ((uint8_t)0x06) /* DFSDM1 Alternate Function mapping */ -#endif /* STM32F412xG || STM32F413_423xx */ -#if defined(STM32F413_423xx) -#define GPIO_AF6_DFSDM2 ((uint8_t)0x06) /* DFSDM2 Alternate Function mapping */ -#endif /* STM32F413_423xx */ - -/** - * @brief AF 7 selection - */ -#define GPIO_AF_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ -#define GPIO_AF_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ -#define GPIO_AF_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */ -#define GPIO_AF7_SPI3 ((uint8_t)0x07) /* SPI3/I2S3ext Alternate Function mapping */ -#if defined(STM32F413_423xx) -#define GPIO_AF7_DFSDM2 ((uint8_t)0x07) /* DFSDM2 Alternate Function mapping */ -#define GPIO_AF7_SAI1 ((uint8_t)0x07) /* SAI1 Alternate Function mapping */ -#endif /* STM32F413_423xx */ - -/** - * @brief AF 7 selection Legacy - */ -#define GPIO_AF_I2S3ext GPIO_AF7_SPI3 - -/** - * @brief AF 8 selection - */ -#define GPIO_AF_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */ -#define GPIO_AF_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */ -#define GPIO_AF_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */ -#define GPIO_AF_UART7 ((uint8_t)0x08) /* UART7 Alternate Function mapping */ -#define GPIO_AF_UART8 ((uint8_t)0x08) /* UART8 Alternate Function mapping */ -#if defined(STM32F412xG) || defined(STM32F413_423xx) -#define GPIO_AF8_USART3 ((uint8_t)0x08) /* USART3 Alternate Function mapping */ -#define GPIO_AF8_DFSDM1 ((uint8_t)0x08) /* DFSDM Alternate Function mapping */ -#define GPIO_AF8_CAN1 ((uint8_t)0x08) /* CAN1 Alternate Function mapping */ -#endif /* STM32F412xG || STM32F413_423xx */ -#if defined(STM32F446xx) -#define GPIO_AF8_SAI2 ((uint8_t)0x08) /* SAI2 Alternate Function mapping */ -#define GPIO_AF_SPDIF ((uint8_t)0x08) /* SPDIF Alternate Function mapping */ -#endif /* STM32F446xx */ - -/** - * @brief AF 9 selection - */ -#define GPIO_AF_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */ -#define GPIO_AF_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */ -#define GPIO_AF_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */ -#define GPIO_AF_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */ -#define GPIO_AF_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ -#define GPIO_AF9_I2C2 ((uint8_t)0x09) /* I2C2 Alternate Function mapping (Only for STM32F401xx/STM32F410xx/STM32F411xE/STM32F412xG/STM32F413_423xx Devices) */ -#define GPIO_AF9_I2C3 ((uint8_t)0x09) /* I2C3 Alternate Function mapping (Only for STM32F401xx/STM32F411xE/STM32F412xG and STM32F413_423xx Devices) */ -#if defined(STM32F446xx) -#define GPIO_AF9_SAI2 ((uint8_t)0x09) /* SAI2 Alternate Function mapping */ -#endif /* STM32F446xx */ -#define GPIO_AF9_LTDC ((uint8_t)0x09) /* LTDC Alternate Function mapping */ -#if defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) || defined(STM32F469_479xx) -#define GPIO_AF9_QUADSPI ((uint8_t)0x09) /* QuadSPI Alternate Function mapping */ -#endif /* STM32F412xG || STM32F413_423xx || STM32F446xx || STM32F469_479xx */ -#if defined(STM32F410xx) || defined(STM32F412xG) || defined(STM32F413_423xx) -#define GPIO_AF9_FMPI2C ((uint8_t)0x09) /* FMPI2C Alternate Function mapping (Only for STM32F410xx Devices) */ -#endif /* STM32F410xx || STM32F412xG || STM32F413_423xx */ - -/** - * @brief AF 10 selection - */ -#define GPIO_AF_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ -#define GPIO_AF_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */ -#if defined(STM32F446xx) -#define GPIO_AF10_SAI2 ((uint8_t)0x0A) /* SAI2 Alternate Function mapping */ -#endif /* STM32F446xx */ -#if defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) || defined(STM32F469_479xx) -#define GPIO_AF10_QUADSPI ((uint8_t)0x0A) /* QuadSPI Alternate Function mapping */ -#endif /* STM32F412xG || STM32F413_423xx || STM32F446xx || STM32F469_479xx */ -#if defined(STM32F412xG) || defined(STM32F413_423xx) -#define GPIO_AF10_FMC ((uint8_t)0xA) /* FMC Alternate Function mapping */ -#define GPIO_AF10_DFSDM1 ((uint8_t)0xA) /* DFSDM Alternate Function mapping */ -#endif /* STM32F412xG || STM32F413_423xx */ -#if defined(STM32F413_423xx) -#define GPIO_AF10_DFSDM2 ((uint8_t)0x0A) /* DFSDM2 Alternate Function mapping */ -#define GPIO_AF10_SAI1 ((uint8_t)0x0A) /* SAI1 Alternate Function mapping */ -#endif /* STM32F413_423xx */ -/** - * @brief AF 11 selection - */ -#define GPIO_AF_ETH ((uint8_t)0x0B) /* ETHERNET Alternate Function mapping */ -#if defined(STM32F413_423xx) -#define GPIO_AF11_UART4 ((uint8_t)0x0B) /* UART4 Alternate Function mapping */ -#define GPIO_AF11_UART5 ((uint8_t)0x0B) /* UART5 Alternate Function mapping */ -#define GPIO_AF11_UART9 ((uint8_t)0x0B) /* UART9 Alternate Function mapping */ -#define GPIO_AF11_UART10 ((uint8_t)0x0B) /* UART10 Alternate Function mapping */ -#define GPIO_AF11_CAN3 ((uint8_t)0x0B) /* CAN3 Alternate Function mapping */ -#endif /* STM32F413_423xx */ - -/** - * @brief AF 12 selection - */ -#if defined(STM32F40_41xxx) || defined(STM32F412xG) || defined(STM32F413_423xx) -#define GPIO_AF_FSMC ((uint8_t)0xC) /* FSMC Alternate Function mapping */ -#endif /* STM32F40_41xxx || STM32F412xG || STM32F413_423xx */ - -#if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx) -#define GPIO_AF_FMC ((uint8_t)0xC) /* FMC Alternate Function mapping */ -#endif /* STM32F427_437xx || STM32F429_439xx || STM32F446xx || STM32F469_479xx */ - -#define GPIO_AF_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */ -#define GPIO_AF_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */ - -/** - * @brief AF 13 selection - */ -#define GPIO_AF_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */ -#if defined(STM32F469_479xx) -#define GPIO_AF_DSI ((uint8_t)0x0D) /* DSI Alternate Function mapping */ -#endif /* STM32F469_479xx */ -/** - * @brief AF 14 selection - */ -#define GPIO_AF_LTDC ((uint8_t)0x0E) /* LCD-TFT Alternate Function mapping */ -#if defined(STM32F413_423xx) -#define GPIO_AF14_RNG ((uint8_t)0x0E) /* RNG Alternate Function mapping */ -#endif /* STM32F413_423xx */ - -/** - * @brief AF 15 selection - */ -#define GPIO_AF_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ - -#if defined(STM32F40_41xxx) -#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ - ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ - ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ - ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ - ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ - ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ - ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ - ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ - ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ - ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ - ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ - ((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \ - ((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \ - ((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \ - ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ - ((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_OTG_HS_FS) || \ - ((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_DCMI) || \ - ((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_FSMC)) -#endif /* STM32F40_41xxx */ - -#if defined(STM32F401xx) -#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ - ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ - ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ - ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ - ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ - ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ - ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ - ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ - ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ - ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ - ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ - ((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_USART6) || \ - ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ - ((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_SPI4)) -#endif /* STM32F401xx */ - -#if defined(STM32F411xE) -#define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 13) && ((AF) != 14)) -#endif /* STM32F411xE */ - -#if defined(STM32F410xx) -#define IS_GPIO_AF(AF) (((AF) < 10) || ((AF) == 15)) -#endif /* STM32F410xx */ - -#if defined(STM32F427_437xx) || defined(STM32F429_439xx) -#define IS_GPIO_AF(AF) (((AF) == GPIO_AF_RTC_50Hz) || ((AF) == GPIO_AF_TIM14) || \ - ((AF) == GPIO_AF_MCO) || ((AF) == GPIO_AF_TAMPER) || \ - ((AF) == GPIO_AF_SWJ) || ((AF) == GPIO_AF_TRACE) || \ - ((AF) == GPIO_AF_TIM1) || ((AF) == GPIO_AF_TIM2) || \ - ((AF) == GPIO_AF_TIM3) || ((AF) == GPIO_AF_TIM4) || \ - ((AF) == GPIO_AF_TIM5) || ((AF) == GPIO_AF_TIM8) || \ - ((AF) == GPIO_AF_I2C1) || ((AF) == GPIO_AF_I2C2) || \ - ((AF) == GPIO_AF_I2C3) || ((AF) == GPIO_AF_SPI1) || \ - ((AF) == GPIO_AF_SPI2) || ((AF) == GPIO_AF_TIM13) || \ - ((AF) == GPIO_AF_SPI3) || ((AF) == GPIO_AF_TIM14) || \ - ((AF) == GPIO_AF_USART1) || ((AF) == GPIO_AF_USART2) || \ - ((AF) == GPIO_AF_USART3) || ((AF) == GPIO_AF_UART4) || \ - ((AF) == GPIO_AF_UART5) || ((AF) == GPIO_AF_USART6) || \ - ((AF) == GPIO_AF_CAN1) || ((AF) == GPIO_AF_CAN2) || \ - ((AF) == GPIO_AF_OTG_FS) || ((AF) == GPIO_AF_OTG_HS) || \ - ((AF) == GPIO_AF_ETH) || ((AF) == GPIO_AF_OTG_HS_FS) || \ - ((AF) == GPIO_AF_SDIO) || ((AF) == GPIO_AF_DCMI) || \ - ((AF) == GPIO_AF_EVENTOUT) || ((AF) == GPIO_AF_SPI4) || \ - ((AF) == GPIO_AF_SPI5) || ((AF) == GPIO_AF_SPI6) || \ - ((AF) == GPIO_AF_UART7) || ((AF) == GPIO_AF_UART8) || \ - ((AF) == GPIO_AF_FMC) || ((AF) == GPIO_AF_SAI1) || \ - ((AF) == GPIO_AF_LTDC)) -#endif /* STM32F427_437xx || STM32F429_439xx */ - -#if defined(STM32F412xG) -#define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 14)) -#endif /* STM32F412xG */ - -#if defined(STM32F413_423xx) -#define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 13)) -#endif /* STM32F413_423xx */ - -#if defined(STM32F446xx) -#define IS_GPIO_AF(AF) (((AF) < 16) && ((AF) != 11) && ((AF) != 14)) -#endif /* STM32F446xx */ - -#if defined(STM32F469_479xx) -#define IS_GPIO_AF(AF) ((AF) < 16) -#endif /* STM32F469_479xx */ - -/** - * @} - */ - -/** @defgroup GPIO_Legacy - * @{ - */ - -#define GPIO_Mode_AIN GPIO_Mode_AN - -#define GPIO_AF_OTG1_FS GPIO_AF_OTG_FS -#define GPIO_AF_OTG2_HS GPIO_AF_OTG_HS -#define GPIO_AF_OTG2_FS GPIO_AF_OTG_HS_FS - -/** - * @} - */ - -/** - * @} - */ - /* Exported macro ------------------------------------------------------------*/ /* Exported functions --------------------------------------------------------*/ @@ -563,9 +48,6 @@ DECLARE_FAKE_VOID_FUNC(GPIO_PinAFConfig, GPIO_TypeDef*, uint16_t, uint8_t); #ifdef __cplusplus } #endif - -#endif /*__STM32F4xx_GPIO_H */ - /** * @} */ diff --git a/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c b/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c index 879063215..0feeb99bd 100644 --- a/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c +++ b/Tests/UnitTests/Mocks/BSP/Src/BSP_ADC.c @@ -2,12 +2,8 @@ ////// MOCK ////// ///////////////////////////////////////////// -#include "common.h" -#include "fff.h" #include "BSP_ADC.h" DEFINE_FAKE_VOID_FUNC(BSP_ADC_Init); - -DEFINE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Millivoltage, int); - -DEFINE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Value, int); \ No newline at end of file +DEFINE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Millivoltage, ADC_t); +DEFINE_FAKE_VALUE_FUNC(int16_t, BSP_ADC_Get_Value, ADC_t); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Src/BSP_CAN.c b/Tests/UnitTests/Mocks/BSP/Src/BSP_CAN.c index 07f3ac54c..73b9aa04b 100644 --- a/Tests/UnitTests/Mocks/BSP/Src/BSP_CAN.c +++ b/Tests/UnitTests/Mocks/BSP/Src/BSP_CAN.c @@ -3,11 +3,7 @@ ///////////////////////////////////////////// #include "BSP_CAN.h" -//#include "stm32f4xx.h" -//#include "os.h" DEFINE_FAKE_VOID_FUNC(BSP_CAN_Init, CAN_t, callback_t, callback_t, uint16_t*, uint8_t); - DEFINE_FAKE_VALUE_FUNC(ErrorStatus, BSP_CAN_Write, CAN_t, uint32_t, uint8_t*, uint8_t); - DEFINE_FAKE_VALUE_FUNC(ErrorStatus, BSP_CAN_Read, CAN_t, uint32_t*, uint8_t*); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c b/Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c index 98b89ff89..63a644b67 100644 --- a/Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c +++ b/Tests/UnitTests/Mocks/BSP/Src/BSP_GPIO.c @@ -3,18 +3,10 @@ ///////////////////////////////////////////// #include "BSP_GPIO.h" -#include "fff.h" - DEFINE_FAKE_VOID_FUNC(BSP_GPIO_Init, port_t, uint16_t, direction_t); - DEFINE_FAKE_VALUE_FUNC(uint16_t, BSP_GPIO_Read, port_t); - DEFINE_FAKE_VOID_FUNC(BSP_GPIO_Write, port_t, uint16_t); - DEFINE_FAKE_VALUE_FUNC(uint8_t, BSP_GPIO_Read_Pin, port_t, uint16_t); - DEFINE_FAKE_VOID_FUNC(BSP_GPIO_Write_Pin, port_t, uint16_t, bool); - -DEFINE_FAKE_VALUE_FUNC(uint8_t, BSP_GPIO_Get_State, port_t, uint16_t); - +DEFINE_FAKE_VALUE_FUNC(uint8_t, BSP_GPIO_Get_State, port_t, uint16_t); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Src/BSP_SPI.c b/Tests/UnitTests/Mocks/BSP/Src/BSP_SPI.c index 14f3cf9d0..cb7b9b586 100644 --- a/Tests/UnitTests/Mocks/BSP/Src/BSP_SPI.c +++ b/Tests/UnitTests/Mocks/BSP/Src/BSP_SPI.c @@ -4,10 +4,6 @@ #include "BSP_SPI.h" - - DEFINE_FAKE_VOID_FUNC(BSP_SPI_Init); - DEFINE_FAKE_VOID_FUNC(BSP_SPI_Write, uint8_t*, uint8_t); - DEFINE_FAKE_VOID_FUNC(BSP_SPI_Read, uint8_t*, uint8_t); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Src/BSP_UART.c b/Tests/UnitTests/Mocks/BSP/Src/BSP_UART.c index 3f6129d04..10e001851 100644 --- a/Tests/UnitTests/Mocks/BSP/Src/BSP_UART.c +++ b/Tests/UnitTests/Mocks/BSP/Src/BSP_UART.c @@ -3,12 +3,7 @@ ///////////////////////////////////////////// #include "BSP_UART.h" -//#include "stm32f4xx.h" -//#include "os.h" - DEFINE_FAKE_VOID_FUNC(BSP_UART_Init, UART_t); - DEFINE_FAKE_VALUE_FUNC(uint32_t, BSP_UART_Read, UART_t, char*); - DEFINE_FAKE_VALUE_FUNC(uint32_t, BSP_UART_Write, UART_t, char*, uint32_t); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c b/Tests/UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c index 2be8770d3..bb1f9afc4 100644 --- a/Tests/UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c +++ b/Tests/UnitTests/Mocks/BSP/Src/stm32f4xx_gpio.c @@ -2,34 +2,20 @@ ////// MOCK ////// ///////////////////////////////////////////// - /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx_gpio.h" DEFINE_FAKE_VOID_FUNC(GPIO_DeInit, GPIO_TypeDef*); - DEFINE_FAKE_VOID_FUNC(GPIO_Init, GPIO_TypeDef*, GPIO_InitTypeDef*); - DEFINE_FAKE_VOID_FUNC(GPIO_StructInit, GPIO_InitTypeDef*); - DEFINE_FAKE_VOID_FUNC(GPIO_PinLockConfig, GPIO_TypeDef*, uint16_t); - DEFINE_FAKE_VALUE_FUNC(uint8_t, GPIO_ReadInputDataBit, GPIO_TypeDef*, uint16_t); - DEFINE_FAKE_VALUE_FUNC(uint16_t, GPIO_ReadInputData, GPIO_TypeDef*); - DEFINE_FAKE_VALUE_FUNC(uint8_t, GPIO_ReadOutputDataBit, GPIO_TypeDef*, uint16_t); - DEFINE_FAKE_VALUE_FUNC(uint16_t, GPIO_ReadOutputData, GPIO_TypeDef*); - DEFINE_FAKE_VOID_FUNC(GPIO_SetBits, GPIO_TypeDef*, uint16_t); - DEFINE_FAKE_VOID_FUNC(GPIO_ResetBits, GPIO_TypeDef*, uint16_t); - DEFINE_FAKE_VOID_FUNC(GPIO_WriteBit, GPIO_TypeDef*, uint16_t, BitAction); - DEFINE_FAKE_VOID_FUNC(GPIO_Write, GPIO_TypeDef*, uint16_t); - DEFINE_FAKE_VOID_FUNC(GPIO_ToggleBits, GPIO_TypeDef*, uint16_t); - DEFINE_FAKE_VOID_FUNC(GPIO_PinAFConfig, GPIO_TypeDef*, uint16_t, uint8_t); \ No newline at end of file diff --git a/Tests/UnitTests/Tests/Test_Contactors.c b/Tests/UnitTests/Tests/Test_Contactors.c index 50e1656bc..a62311edb 100644 --- a/Tests/UnitTests/Tests/Test_Contactors.c +++ b/Tests/UnitTests/Tests/Test_Contactors.c @@ -42,8 +42,6 @@ void test_UnitTestContactors_Set(void){ } - - /*=======MAIN=====*/ int main(void) { diff --git a/Tests/UnitTests/Tests/Test_SendTritium.c b/Tests/UnitTests/Tests/Test_SendTritium.c new file mode 100644 index 000000000..b2c4deb71 --- /dev/null +++ b/Tests/UnitTests/Tests/Test_SendTritium.c @@ -0,0 +1,70 @@ +////////////////////////////////////////// +////////////////////////////////////////// +// Unity required for this testing format +#include "unity.h" +////////////////////////////////////////// +////////////////////////////////////////// +// The header file we are unit testing: +#include "SendTritium.h" +////////////////////////////////////////// +// fff header so we can DEFINE_FFF_GLOBALS +// (can only happen once per test) +#include "fff.h" +///////////////////// +// Mock headers +#include "UpdateDisplay.h" + +DEFINE_FFF_GLOBALS; + + + +void setUp(void) { + FFF_RESET_HISTORY(); +} + +void tearDown(void) {} + +ErrorStatus CANbus_Custom_(CANDATA_t* data, bool blocking, CAN_t bus){ + *data = bps_trip_msg; + return SUCCESS; +} + +ErrorStatus CANbus_Custom_fake_bpscontactor(CANDATA_t* data, bool blocking, CAN_t bus){ + *data = HV_Disable_Msg; + return SUCCESS; +} + +void test_UnitTest_bsptrip(void){ + Task_Init(NULL); + CANbus_Read_fake.custom_fake = CANbus_Custom_fake_bps; + Task_ReadCarCAN(NULL); + printf("\n\r%d\n\r", CANbus_Read_fake.call_count); + // + TEST_ASSERT_EQUAL(3, throwTaskError_fake.arg0_history[0]); + TEST_ASSERT_EQUAL(4, throwTaskError_fake.arg0_history[1]); + printf("%d", throwTaskError_fake.call_count); + TEST_ASSERT_EQUAL(false, UpdateDisplay_SetArray_fake.arg0_history[0]); + TEST_ASSERT_EQUAL(2, Display_Evac_fake.call_count); +} + +void test_UnitTest_bspcontactor(void){ + Task_Init(NULL); + CANbus_Read_fake.custom_fake = CANbus_Custom_fake_bpscontactor; + Task_ReadCarCAN(NULL); + printf("\n\r%d\n\r", CANbus_Read_fake.call_count); + // + TEST_ASSERT_EQUAL(3, throwTaskError_fake.arg0_history[0]); + //TEST_ASSERT_EQUAL(4, throwTaskError_fake.arg0_history[1]); + printf("%d", throwTaskError_fake.call_count); + TEST_ASSERT_EQUAL(false, UpdateDisplay_SetArray_fake.arg0_history[0]); +} + + +/*=======MAIN=====*/ +int main(void) +{ + UNITY_BEGIN(); + RUN_TEST(test_UnitTest_bspcontactor); + RUN_TEST(test_UnitTest_bsptrip); + return UNITY_END(); +} From 69f956dc01839f702d3ab606422c8f0b68c5495f Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Sat, 20 Jan 2024 20:29:42 +0000 Subject: [PATCH 32/57] Cleaned and deleted shared initializations by including it from non-mocked header files first --- Tests/UnitTests/Tests/Test_SendTritium.c | 70 ------------------------ 1 file changed, 70 deletions(-) delete mode 100644 Tests/UnitTests/Tests/Test_SendTritium.c diff --git a/Tests/UnitTests/Tests/Test_SendTritium.c b/Tests/UnitTests/Tests/Test_SendTritium.c deleted file mode 100644 index b2c4deb71..000000000 --- a/Tests/UnitTests/Tests/Test_SendTritium.c +++ /dev/null @@ -1,70 +0,0 @@ -////////////////////////////////////////// -////////////////////////////////////////// -// Unity required for this testing format -#include "unity.h" -////////////////////////////////////////// -////////////////////////////////////////// -// The header file we are unit testing: -#include "SendTritium.h" -////////////////////////////////////////// -// fff header so we can DEFINE_FFF_GLOBALS -// (can only happen once per test) -#include "fff.h" -///////////////////// -// Mock headers -#include "UpdateDisplay.h" - -DEFINE_FFF_GLOBALS; - - - -void setUp(void) { - FFF_RESET_HISTORY(); -} - -void tearDown(void) {} - -ErrorStatus CANbus_Custom_(CANDATA_t* data, bool blocking, CAN_t bus){ - *data = bps_trip_msg; - return SUCCESS; -} - -ErrorStatus CANbus_Custom_fake_bpscontactor(CANDATA_t* data, bool blocking, CAN_t bus){ - *data = HV_Disable_Msg; - return SUCCESS; -} - -void test_UnitTest_bsptrip(void){ - Task_Init(NULL); - CANbus_Read_fake.custom_fake = CANbus_Custom_fake_bps; - Task_ReadCarCAN(NULL); - printf("\n\r%d\n\r", CANbus_Read_fake.call_count); - // - TEST_ASSERT_EQUAL(3, throwTaskError_fake.arg0_history[0]); - TEST_ASSERT_EQUAL(4, throwTaskError_fake.arg0_history[1]); - printf("%d", throwTaskError_fake.call_count); - TEST_ASSERT_EQUAL(false, UpdateDisplay_SetArray_fake.arg0_history[0]); - TEST_ASSERT_EQUAL(2, Display_Evac_fake.call_count); -} - -void test_UnitTest_bspcontactor(void){ - Task_Init(NULL); - CANbus_Read_fake.custom_fake = CANbus_Custom_fake_bpscontactor; - Task_ReadCarCAN(NULL); - printf("\n\r%d\n\r", CANbus_Read_fake.call_count); - // - TEST_ASSERT_EQUAL(3, throwTaskError_fake.arg0_history[0]); - //TEST_ASSERT_EQUAL(4, throwTaskError_fake.arg0_history[1]); - printf("%d", throwTaskError_fake.call_count); - TEST_ASSERT_EQUAL(false, UpdateDisplay_SetArray_fake.arg0_history[0]); -} - - -/*=======MAIN=====*/ -int main(void) -{ - UNITY_BEGIN(); - RUN_TEST(test_UnitTest_bspcontactor); - RUN_TEST(test_UnitTest_bsptrip); - return UNITY_END(); -} From 972caef09a02f5fc34000cfdd07f4306e50d759a Mon Sep 17 00:00:00 2001 From: Nathaniel Delgado <89701060+NathanielDelgado@users.noreply.github.com> Date: Sat, 20 Jan 2024 15:27:05 -0600 Subject: [PATCH 33/57] Modifed workflow to enforce clang and format (#408) --- .github/workflows/c-cpp.yml | 12 +++++++----- BSP/STM32F413/Makefile | 6 ++++++ Makefile | 9 +++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index a03547c65..3329fd716 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -21,10 +21,12 @@ jobs: run: make clean - name: make leader run: make leader - # Run tidy and format and then tidy again in case format moves any NOLINTs to other lines, thus creating warnings/errors - - name: tidy - run: make tidy + # Check that format was ran and has no errors + - name: format-check + run: make format-check + # Apply format in case newline changes create tidy warnings (NOLINT comments change lines) - name: format run: make format - - name: tidy - run: make tidy + # Check that tidy was ran and has no errors + - name: tidy-check + run: make tidy-check diff --git a/BSP/STM32F413/Makefile b/BSP/STM32F413/Makefile index f5ee202bc..a3475492d 100644 --- a/BSP/STM32F413/Makefile +++ b/BSP/STM32F413/Makefile @@ -206,6 +206,9 @@ TIDYCFLAGS += -m32 tidy: clang-tidy-17 $(TIDYFLAGS) $(CLANGINPUTS) --fix -- $(C_INCLUDES) $(TIDYCFLAGS) +tidy-check: + clang-tidy-17 $(TIDYFLAGS) $(CLANGINPUTS) --warnings-as-errors=* -- $(C_INCLUDES) $(TIDYCFLAGS) + ####################################### # format ####################################### @@ -214,6 +217,9 @@ FORMATFLAGS = --config-file=../../.clang-format format: clang-format-17 -i $(CLANGINPUTS) +format-check: + clang-format-17 -i --Werror --dry-run $(CLANGINPUTS) + ####################################### # clean up ####################################### diff --git a/Makefile b/Makefile index a1d76e19c..0e1fa1ce2 100644 --- a/Makefile +++ b/Makefile @@ -68,3 +68,12 @@ tidy: format: $(MAKE) -C BSP -C STM32F413 format + +tidy-check: + $(MAKE) -C BSP -C STM32F413 tidy-check + +format-check: + $(MAKE) -C BSP -C STM32F413 format-check + +check: format-check format tidy-check + From d8a31ac3df83caef018a1e811ffac28e629c0019 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 20 Jan 2024 15:31:37 -0600 Subject: [PATCH 34/57] Began working on a more thorough unit test example for Contactors. --- Tests/UnitTests/Tests/Test_Contactors demo.c | 61 ++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 Tests/UnitTests/Tests/Test_Contactors demo.c diff --git a/Tests/UnitTests/Tests/Test_Contactors demo.c b/Tests/UnitTests/Tests/Test_Contactors demo.c new file mode 100644 index 000000000..592c08dfe --- /dev/null +++ b/Tests/UnitTests/Tests/Test_Contactors demo.c @@ -0,0 +1,61 @@ +/** + * @copyright Copyright (c) 2018-2024 UT Longhorn Racing Solar + * @file Test_Contactors.c + * @brief An annotated example unit test written for the driver Contactors.c + * + */ + +#include "unity.h" // Contains assertions for testing +#include "Contactors.h" // Header of the source file to test +//#include "fff.h" // Fake Function Framework for working with mocks + +// Global variables for FFF; must be included once per unit-test file +DEFINE_FFF_GLOBALS; + + +// Special function required by Unity that will run before each test +void setUp(void){ + // Reset the fakes' call and argument history between tests + RESET_FAKE(BSP_GPIO_Write_Pin) // not really needed + RESET_FAKE(BSP_GPIO_Init) // technically not needed since we only use this in one test + RESET_FAKE(OSMutexCreate) // "" + RESET_FAKE(BSP_GPIO_Get_State) // same here + RESET_FAKE(OSMutexPend) //"" + RESET_FAKE(OSMutexPost) // "" + // Would like to make this part less tedious but also you'll need to deal with all of these anyways +} + + +// Another required function from Unity that will run after each test +void tearDown(void){ + // Left blank because we don't need it +} + + +void test_Contactors_Init(){ + // Check that BSP_GPIO_Init was called to initialize + // Contactors port for Array and Motor Precharge pins to be outputs + TEST_ASSERT_EQUAL(BSP_GPIO_Init_fake.arg0_history[0], CONTACTORS_PORT) + TEST_ASSERT_EQUAL(BSP_GPIO_Init_fake.arg1_history[0], (ARRAY_PRECHARGE_BYPASS_PIN | MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN)) + TEST_ASSERT_EQUAL (BSP_GPIO_Init_fake.arg2_history[0], (1)) + + // umm set contactor says it should only be called if a mutex is held...? + // also I don't know how to test the order in which functions were called + + + // Check that all contactors were set to "off" + // for (int contactor = 0; contactor < NUM_CONTACTORS; ++contactor) { + // TEST_ASSERT_EQUAL(BSP_GPIO_Write_Pin_fake.arg0_history[0], CONTACTORS_PORT) + // TEST_ASSERT_EQUAL(BSP_GPIO_Write_Pin_fake.arg1_history[0], ARRAY_PRECHARGE_BYPASS_PIN) + // } + TEST_ASSERT_EQUAL(BSP_GPIO_Write_Pin_fake.arg0_history[0], CONTACTORS_PORT) + TEST_ASSERT_EQUAL(BSP_GPIO_Write_Pin_fake.arg1_history[0], ARRAY_PRECHARGE_BYPASS_PIN) + TEST_ASSERT_EQUAL(BSP_GPIO_Write_Pin_fake.arg2_history[0], OFF) + + BSP_GPIO_Turn_Array_Off_Args = {CONTACTORS_PORT, ARRAY_PRECHARGE_BYPASS_PIN, OFF} + for (int i = 0; i < 3; i++) { // number of arguments + //hmmm #define FUNC_PARAM BSP_GPIO_Write_Pin_fake.arg##i##_history[0] + TEST_ASSERT_EQUAL(FUNC_PARAM, BSP_GPIO_Turn_Array_Off_Args[i]) + } +} + From 47e5b4ac0cb35d7011b4a0c484f8ad1e59734def Mon Sep 17 00:00:00 2001 From: Diya Rajon Date: Tue, 23 Jan 2024 17:31:37 +0000 Subject: [PATCH 35/57] Modified mocks used by RCC. RCC unit test merge in progress. Co-authored-by: Madeleine Lee --- Tests/UnitTests/Mocks/Apps/Inc/ReadCarCan.h | 4 +++- Tests/UnitTests/Mocks/Apps/Src/ReadCarCan.c | 2 ++ Tests/UnitTests/Mocks/Drivers/Inc/{CANbus.h => CanBus.h} | 0 Tests/UnitTests/Mocks/Drivers/Src/{CANbus.c => CanBus.c} | 2 +- Tests/UnitTests/Tests/Test_ReadCarCAN.c | 5 +++-- 5 files changed, 9 insertions(+), 4 deletions(-) rename Tests/UnitTests/Mocks/Drivers/Inc/{CANbus.h => CanBus.h} (100%) rename Tests/UnitTests/Mocks/Drivers/Src/{CANbus.c => CanBus.c} (94%) diff --git a/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCan.h b/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCan.h index e0110a0df..5fabf3d1f 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCan.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCan.h @@ -6,7 +6,9 @@ #include_next "ReadCarCan.h" #ifndef TEST_READCARCAN -#include "fff.h" +#include "common.h" + +//#include "fff.h" DECLARE_FAKE_VOID_FUNC(TaskReadCarCan, void*); DECLARE_FAKE_VALUE_FUNC(bool, ChargeEnableGet); diff --git a/Tests/UnitTests/Mocks/Apps/Src/ReadCarCan.c b/Tests/UnitTests/Mocks/Apps/Src/ReadCarCan.c index 3163d22b7..f7e2ebad1 100644 --- a/Tests/UnitTests/Mocks/Apps/Src/ReadCarCan.c +++ b/Tests/UnitTests/Mocks/Apps/Src/ReadCarCan.c @@ -3,6 +3,8 @@ ///////////////////////////////////////////// #include "ReadCarCan.h" +#include "fff.h" + DEFINE_FAKE_VOID_FUNC(TaskReadCarCan, void*); DEFINE_FAKE_VALUE_FUNC(bool, ChargeEnableGet); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h b/Tests/UnitTests/Mocks/Drivers/Inc/CanBus.h similarity index 100% rename from Tests/UnitTests/Mocks/Drivers/Inc/CANbus.h rename to Tests/UnitTests/Mocks/Drivers/Inc/CanBus.h diff --git a/Tests/UnitTests/Mocks/Drivers/Src/CANbus.c b/Tests/UnitTests/Mocks/Drivers/Src/CanBus.c similarity index 94% rename from Tests/UnitTests/Mocks/Drivers/Src/CANbus.c rename to Tests/UnitTests/Mocks/Drivers/Src/CanBus.c index 87d9b8d02..147d5ef51 100644 --- a/Tests/UnitTests/Mocks/Drivers/Src/CANbus.c +++ b/Tests/UnitTests/Mocks/Drivers/Src/CanBus.c @@ -2,7 +2,7 @@ ////// MOCK ////// ///////////////////////////////////////////// -#include "CANbus.h" +#include "CanBus.h" DEFINE_FAKE_VALUE_FUNC(ErrorStatus, CanBusInit, Can, CanId*, uint8_t); DEFINE_FAKE_VALUE_FUNC(ErrorStatus, CanBusSend, CanData, bool, Can); diff --git a/Tests/UnitTests/Tests/Test_ReadCarCAN.c b/Tests/UnitTests/Tests/Test_ReadCarCAN.c index 284784007..41fde83d8 100644 --- a/Tests/UnitTests/Tests/Test_ReadCarCAN.c +++ b/Tests/UnitTests/Tests/Test_ReadCarCAN.c @@ -13,16 +13,17 @@ ///////////////////// // Mock headers #include "UpdateDisplay.h" +#include "CanBus.h" DEFINE_FFF_GLOBALS; /*** CAN Messages ***/ -static CanData bps_trip_msg = {.id=BPS_TRIP, .idx=0, .data={1}}; +static CanData bps_trip_msg = {.id=kBpsTrip, .idx=0, .data={1}}; //static CANDATA_t supp_voltage_msg = {.ID=SUPPLEMENTAL_VOLTAGE, .idx=0, .data={100}}; // static CANDATA_t state_of_charge_msg = {.ID=STATE_OF_CHARGE, .idx=0, .data={0}}; // static CANDATA_t HV_Array_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b001}}; -static CanData HV_Disable_Msg = {.id=BPS_CONTACTOR, .idx=0, .data={0b000}}; +static CanData HV_Disable_Msg = {.id=kBpsContactor, .idx=0, .data={0b000}}; // static CANDATA_t HV_MC_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b110}}; // static CANDATA_t HV_Enabled_Msg = {.ID=BPS_CONTACTOR, .idx=0, .data={0b111}}; From 4fd024b2f0d7e0f116f0bd97591d09905ac7e939 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 23 Jan 2024 17:55:21 -0600 Subject: [PATCH 36/57] Renamed functions, tasks, and mock test file and otherwise made changes so that things work with the new cleaned-up codebase. --- Apps/Inc/ReadCarCan.h | 5 +++++ Apps/Inc/ReadTritium.h | 5 +++++ Apps/Inc/SendCarCan.h | 2 +- Apps/Inc/SendTritium.h | 6 ++++++ Apps/Inc/Tasks.h | 15 +++++---------- Apps/Inc/UpdateDisplay.h | 2 +- Apps/Src/Tasks.c | 2 +- Tests/UnitTests/Mocks/Apps/Inc/ReadCarCan.h | 4 +--- Tests/UnitTests/Mocks/Apps/Inc/SendCarCan.h | 2 +- Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h | 2 +- Tests/UnitTests/Mocks/Apps/Inc/Tasks.h | 10 +++++----- Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h | 6 ++++-- Tests/UnitTests/Mocks/Apps/Src/SendCarCan.c | 2 +- Tests/UnitTests/Mocks/Apps/Src/SendTritium.c | 2 +- Tests/UnitTests/Mocks/Apps/Src/Tasks.c | 12 ++++++------ Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c | 6 ++++-- Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h | 6 +++--- Tests/UnitTests/Mocks/Drivers/Inc/Minions.h | 4 ++-- Tests/UnitTests/Mocks/Drivers/Src/Contactors.c | 6 +++--- Tests/UnitTests/Mocks/Drivers/Src/Minions.c | 4 ++-- .../{Test_ReadCarCAN.c => Test_ReadCarCan.c} | 4 ++-- 21 files changed, 60 insertions(+), 47 deletions(-) rename Tests/UnitTests/Tests/{Test_ReadCarCAN.c => Test_ReadCarCan.c} (98%) diff --git a/Apps/Inc/ReadCarCan.h b/Apps/Inc/ReadCarCan.h index 51cb9fa4a..42ab32ce1 100644 --- a/Apps/Inc/ReadCarCan.h +++ b/Apps/Inc/ReadCarCan.h @@ -13,6 +13,11 @@ #include "common.h" +/** + * Task Prototype +*/ +void TaskReadCarCan(void* p_arg); + /** * Error types */ diff --git a/Apps/Inc/ReadTritium.h b/Apps/Inc/ReadTritium.h index 3a6fe947f..b4e007a3b 100644 --- a/Apps/Inc/ReadTritium.h +++ b/Apps/Inc/ReadTritium.h @@ -31,6 +31,11 @@ typedef enum { kNone = 0x00, } TritiumErrorCode; +/** + * Task Prototype +*/ +void TaskReadTritium(void* p_arg); + float MotorRpmGet(); float MotorVelocityGet(); diff --git a/Apps/Inc/SendCarCan.h b/Apps/Inc/SendCarCan.h index 0bbfede59..661399769 100644 --- a/Apps/Inc/SendCarCan.h +++ b/Apps/Inc/SendCarCan.h @@ -6,7 +6,7 @@ /** * Task Prototype */ -void Task_SendCarCAN(void* p_arg); +void TaskSendCarCAN(void* p_arg); /** diff --git a/Apps/Inc/SendTritium.h b/Apps/Inc/SendTritium.h index 0568d8749..ed1455fc3 100644 --- a/Apps/Inc/SendTritium.h +++ b/Apps/Inc/SendTritium.h @@ -47,6 +47,12 @@ typedef struct TritiumState { void (*stateDecider)(void); } TritiumState; +/** + * Task Prototype +*/ +void TaskSendTritium(void* p_arg); + + // Getter functions for static variables bool GetCruiseEnable(void); bool GetCruiseSet(void); diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 948f2bc78..47571fe61 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -60,11 +60,6 @@ typedef uint16_t ErrorCode; * Task Prototypes */ void TaskInit(void* p_arg); -void TaskSendTritium(void* p_arg); -void TaskReadCarCan(void* p_arg); -void TaskUpdateDisplay(void* p_arg); -void TaskReadTritium(void* p_arg); -void TaskSendCarCan(void* p_arg); void TaskDebugDump(void* p_arg); void TaskCommandLine(void* p_arg); @@ -167,11 +162,11 @@ void AssertOsError(OS_ERR err); #if DEBUG == 1 #define ASSERT_OS_ERROR(err) \ - // if (err != OS_ERR_NONE) { \ - // printf("Error asserted at %s, line %d: %d\n\r", __FILE__, __LINE__, \ - // err); \ - // } \ - // AssertOsError(err); + if (err != OS_ERR_NONE) { \ + printf("Error asserted at %s, line %d: %d\n\r", __FILE__, __LINE__, \ + err); \ + } \ + AssertOsError(err); #else #define ASSERT_OS_ERROR(err) AssertOsError(err); #endif diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index a58c3852f..28f273620 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -48,7 +48,7 @@ typedef enum { kState0 = 0, kState1 = 1, kState2 = 2 } TriState; /** * Task Prototype */ -void Task_UpdateDisplay(void* p_arg); +void TaskUpdateDisplay(void* p_arg); /** diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 383967958..eb54a5b79 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -45,7 +45,7 @@ CPU_STK command_line_stk[TASK_COMMAND_LINE_STACK_SIZE]; // Variables to store error codes, stored and cleared in task error assert // functions -ErrorCode error_read_car_can = 0; // TODO: change this back to the error +ErrorCode error_read_car_can = kReadCarCanErrNone; ErrorCode error_read_tritium = kNone; // Initialized to no error ErrorCode error_update_display = kUpdateDisplayErrNone; diff --git a/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCan.h b/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCan.h index 5fabf3d1f..e0110a0df 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCan.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/ReadCarCan.h @@ -6,9 +6,7 @@ #include_next "ReadCarCan.h" #ifndef TEST_READCARCAN -#include "common.h" - -//#include "fff.h" +#include "fff.h" DECLARE_FAKE_VOID_FUNC(TaskReadCarCan, void*); DECLARE_FAKE_VALUE_FUNC(bool, ChargeEnableGet); diff --git a/Tests/UnitTests/Mocks/Apps/Inc/SendCarCan.h b/Tests/UnitTests/Mocks/Apps/Inc/SendCarCan.h index c209c6568..21fa30979 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/SendCarCan.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/SendCarCan.h @@ -8,7 +8,7 @@ #include "fff.h" -DECLARE_FAKE_VOID_FUNC(Task_SendCarCAN, void*); +DECLARE_FAKE_VOID_FUNC(TaskSendCarCan, void*); DECLARE_FAKE_VOID_FUNC(SendCarCanInit); DECLARE_FAKE_VOID_FUNC(SendCarCanPut, CanData); diff --git a/Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h b/Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h index 256091832..872f2aa5b 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/SendTritium.h @@ -8,7 +8,7 @@ #include "fff.h" -DECLARE_FAKE_VOID_FUNC(Task_SendTritium, void*); +DECLARE_FAKE_VOID_FUNC(TaskSendTritium, void*); // Getter functions for local variables in SendTritium.c DECLARE_FAKE_VALUE_FUNC(bool, GetCruiseEnable); diff --git a/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h b/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h index 0629ccdde..c4f04b54b 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/Tasks.h @@ -9,19 +9,19 @@ #include "fff.h" #ifndef TEST_MAIN -DECLARE_FAKE_VOID_FUNC(Task_Init, void *); +DECLARE_FAKE_VOID_FUNC(TaskInit, void *); #else -void Task_Init(void* p_arg); +void TaskInit(void* p_arg); #endif #ifndef TEST_DEBUGDUMP -DECLARE_FAKE_VOID_FUNC(Task_DebugDump, void*); +DECLARE_FAKE_VOID_FUNC(TaskDebugDump, void*); #else -void Task_DebugDump(void *p_arg); +void TaskDebugDump(void *p_arg); #endif #ifndef TEST_COMMANDLINE -DECLARE_FAKE_VOID_FUNC(Task_CommandLine, void*); +DECLARE_FAKE_VOID_FUNC(TaskCommandLine, void*); #else void Task_CommandLine(void* p_arg); #endif diff --git a/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h b/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h index f6538dbc4..f71ed0b23 100644 --- a/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h +++ b/Tests/UnitTests/Mocks/Apps/Inc/UpdateDisplay.h @@ -8,10 +8,12 @@ #include "fff.h" +DECLARE_FAKE_VOID_FUNC(TaskUpdateDisplay, void*); + DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplayInit); DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetPage, Page); -DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetSOC, uint8_t); -DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetSBPV, uint32_t); +DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetSoc, uint8_t); +DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetSbpv, uint32_t); DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetVelocity, uint32_t); DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetAccel, uint8_t); DECLARE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetArray, bool); diff --git a/Tests/UnitTests/Mocks/Apps/Src/SendCarCan.c b/Tests/UnitTests/Mocks/Apps/Src/SendCarCan.c index c0ce6687e..750e101c4 100644 --- a/Tests/UnitTests/Mocks/Apps/Src/SendCarCan.c +++ b/Tests/UnitTests/Mocks/Apps/Src/SendCarCan.c @@ -4,6 +4,6 @@ #include "SendCarCan.h" -DEFINE_FAKE_VOID_FUNC(Task_SendCarCAN, void*); +DEFINE_FAKE_VOID_FUNC(TaskSendCarCan, void*); DEFINE_FAKE_VOID_FUNC(SendCarCanInit); DEFINE_FAKE_VOID_FUNC(SendCarCanPut, CanData); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Apps/Src/SendTritium.c b/Tests/UnitTests/Mocks/Apps/Src/SendTritium.c index 56582e933..49df5b3b3 100644 --- a/Tests/UnitTests/Mocks/Apps/Src/SendTritium.c +++ b/Tests/UnitTests/Mocks/Apps/Src/SendTritium.c @@ -4,7 +4,7 @@ #include "SendTritium.h" -DEFINE_FAKE_VOID_FUNC(Task_SendTritium, void*); +DEFINE_FAKE_VOID_FUNC(TaskSendTritium, void*); DEFINE_FAKE_VALUE_FUNC(bool, GetCruiseEnable); DEFINE_FAKE_VALUE_FUNC(bool, GetCruiseSet); DEFINE_FAKE_VALUE_FUNC(bool, GetOnePedalEnable); diff --git a/Tests/UnitTests/Mocks/Apps/Src/Tasks.c b/Tests/UnitTests/Mocks/Apps/Src/Tasks.c index 59f968f0c..cd26e7400 100644 --- a/Tests/UnitTests/Mocks/Apps/Src/Tasks.c +++ b/Tests/UnitTests/Mocks/Apps/Src/Tasks.c @@ -8,20 +8,20 @@ #include "ReadCarCan.h" #include "UpdateDisplay.h" -// ErrorCode Error_ReadCarCAN = READCARCAN_ERR_NONE; // TODO: change this back to the error -// ErrorCode Error_ReadTritium = T_NONE; // Initialized to no error -// ErrorCode Error_UpdateDisplay = UPDATEDISPLAY_ERR_NONE; +ErrorCode error_read_car_can = kReadCarCanErrNone; +ErrorCode error_read_tritium = kNone; // Initialized to no error +ErrorCode error_update_display = kUpdateDisplayErrNone; #ifndef TEST_MAIN -DEFINE_FAKE_VOID_FUNC(Task_Init, void*); +DEFINE_FAKE_VOID_FUNC(TaskInit, void*); #endif #ifndef TEST_DEBUGDUMP -DEFINE_FAKE_VOID_FUNC(Task_DebugDump, void*); +DEFINE_FAKE_VOID_FUNC(TaskDebugDump, void*); #endif #ifndef TEST_COMMANDLINE -DEFINE_FAKE_VOID_FUNC(Task_CommandLine, void*); +DEFINE_FAKE_VOID_FUNC(TaskCommandLine, void*); #endif DEFINE_FAKE_VOID_FUNC(TaskSwHookInit); diff --git a/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c b/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c index 415eb36d6..aa0666a68 100644 --- a/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c +++ b/Tests/UnitTests/Mocks/Apps/Src/UpdateDisplay.c @@ -4,10 +4,12 @@ #include "UpdateDisplay.h" +DEFINE_FAKE_VOID_FUNC(TaskUpdateDisplay, void*); + DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplayInit); DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetPage, Page); -DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetSOC, uint8_t); -DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetSBPV, uint32_t); +DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetSoc, uint8_t); +DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetSbpv, uint32_t); DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetVelocity, uint32_t); DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetAccel, uint8_t); DEFINE_FAKE_VALUE_FUNC(UpdateDisplayError, UpdateDisplaySetArray, bool); diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h b/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h index 08efa3c5e..fe0b975c0 100644 --- a/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h +++ b/Tests/UnitTests/Mocks/Drivers/Inc/Contactors.h @@ -7,9 +7,9 @@ #ifndef TEST_CONTACTORS #include "fff.h" -DECLARE_FAKE_VOID_FUNC(Contactors_Init); -DECLARE_FAKE_VALUE_FUNC(bool, Contactors_Get, Contactor); -DECLARE_FAKE_VALUE_FUNC(ErrorStatus, Contactors_Set, Contactor, bool, bool); +DECLARE_FAKE_VOID_FUNC(ContactorsInit); +DECLARE_FAKE_VALUE_FUNC(bool, ContactorsGet, Contactor); +DECLARE_FAKE_VALUE_FUNC(ErrorStatus, ContactorsSet, Contactor, bool, bool); #endif diff --git a/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h b/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h index ad5d1518f..4adb54bee 100644 --- a/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h +++ b/Tests/UnitTests/Mocks/Drivers/Inc/Minions.h @@ -8,7 +8,7 @@ #include "fff.h" -DECLARE_FAKE_VOID_FUNC(Minions_Init); -DECLARE_FAKE_VALUE_FUNC(bool, Minions_Read, Pin); +DECLARE_FAKE_VOID_FUNC(MinionsInit); +DECLARE_FAKE_VALUE_FUNC(bool, MinionsRead, Pin); #endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c b/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c index 4560209f6..aedae3ee6 100644 --- a/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c +++ b/Tests/UnitTests/Mocks/Drivers/Src/Contactors.c @@ -4,6 +4,6 @@ #include "Contactors.h" -DEFINE_FAKE_VOID_FUNC(Contactors_Init); -DEFINE_FAKE_VALUE_FUNC(bool, Contactors_Get, Contactor); -DEFINE_FAKE_VALUE_FUNC(ErrorStatus, Contactors_Set, Contactor, bool, bool); \ No newline at end of file +DEFINE_FAKE_VOID_FUNC(ContactorsInit); +DEFINE_FAKE_VALUE_FUNC(bool, ContactorsGet, Contactor); +DEFINE_FAKE_VALUE_FUNC(ErrorStatus, ContactorsSet, Contactor, bool, bool); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/Drivers/Src/Minions.c b/Tests/UnitTests/Mocks/Drivers/Src/Minions.c index d8465dba9..d2e4138f0 100644 --- a/Tests/UnitTests/Mocks/Drivers/Src/Minions.c +++ b/Tests/UnitTests/Mocks/Drivers/Src/Minions.c @@ -4,5 +4,5 @@ #include "Minions.h" -DEFINE_FAKE_VOID_FUNC(Minions_Init); -DEFINE_FAKE_VALUE_FUNC(bool, Minions_Read, Pin); +DEFINE_FAKE_VOID_FUNC(MinionsInit); +DEFINE_FAKE_VALUE_FUNC(bool, MinionsRead, Pin); diff --git a/Tests/UnitTests/Tests/Test_ReadCarCAN.c b/Tests/UnitTests/Tests/Test_ReadCarCan.c similarity index 98% rename from Tests/UnitTests/Tests/Test_ReadCarCAN.c rename to Tests/UnitTests/Tests/Test_ReadCarCan.c index 41fde83d8..6a04392b7 100644 --- a/Tests/UnitTests/Tests/Test_ReadCarCAN.c +++ b/Tests/UnitTests/Tests/Test_ReadCarCan.c @@ -44,7 +44,7 @@ ErrorStatus CANbus_Custom_fake_bpscontactor(CanData* data, bool blocking, Can bu } void test_UnitTest_bsptrip(void){ - Task_Init(NULL); + TaskInit(NULL); CanBusRead_fake.custom_fake = CANbus_Custom_fake_bps; TaskReadCarCan(NULL); printf("\n\r%d\n\r", CanBusRead_fake.call_count); @@ -57,7 +57,7 @@ void test_UnitTest_bsptrip(void){ } void test_UnitTest_bspcontactor(void){ - Task_Init(NULL); + TaskInit(NULL); CanBusRead_fake.custom_fake = CANbus_Custom_fake_bpscontactor; TaskReadCarCan(NULL); printf("\n\r%d\n\r", CanBusRead_fake.call_count); From b1a8afebb3cdc5671b11df02ecedef7c13b5a3be Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Tue, 23 Jan 2024 18:05:59 -0600 Subject: [PATCH 37/57] Added back in the LOOP macro so that we don't infinite loop in unit tests, fixed other small changes related to merge issues so that the unit tests run. --- Apps/Inc/SendCarCan.h | 2 +- Apps/Src/ReadCarCan.c | 10 ++++++---- Apps/Src/SendCarCan.c | 4 ++-- Apps/Src/Tasks.c | 4 ++-- Apps/Src/main.c | 5 ++++- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Apps/Inc/SendCarCan.h b/Apps/Inc/SendCarCan.h index 661399769..c826be8d8 100644 --- a/Apps/Inc/SendCarCan.h +++ b/Apps/Inc/SendCarCan.h @@ -6,7 +6,7 @@ /** * Task Prototype */ -void TaskSendCarCAN(void* p_arg); +void TaskSendCarCan(void* p_arg); /** diff --git a/Apps/Src/ReadCarCan.c b/Apps/Src/ReadCarCan.c index 5617fce2b..308bd04e4 100644 --- a/Apps/Src/ReadCarCan.c +++ b/Apps/Src/ReadCarCan.c @@ -368,7 +368,7 @@ void TaskReadCarCan(void *p_arg) { memset(hv_plus_minus_charge_msg_buffer, DISABLE_SATURATION_MSG, sizeof(hv_plus_minus_charge_msg_buffer)); - while (1) { + LOOP { UpdatePrechargeContactors(); // Sets array and motor controller PBC if // all conditions (PBC Status, Threshold, // Precharge Complete) permit @@ -376,7 +376,9 @@ void TaskReadCarCan(void *p_arg) { // BPS sent a message ErrorStatus status = CanBusRead(&data_buf, true, CARCAN); if (status != SUCCESS) { - continue; + #ifndef MOCKING + continue; + #endif } switch (data_buf.id) { // Switch case based on BPS msg received @@ -453,7 +455,7 @@ static void handlerReadCarCanChargeDisable(void) { if (ret) { // Contactor failed to turn off; display the evac screen and // infinite loop DisplayEvac(soc, sbpv); - while (1) {} + LOOP {} } } @@ -489,7 +491,7 @@ static void handlerReadCarCanContactorsDisable(void) { if (ret) { // Contactor failed to turn off; display the evac screen and // infinite loop DisplayEvac(soc, sbpv); - while (1) {} + LOOP {} } } diff --git a/Apps/Src/SendCarCan.c b/Apps/Src/SendCarCan.c index 086a0a70b..f19d251d6 100644 --- a/Apps/Src/SendCarCan.c +++ b/Apps/Src/SendCarCan.c @@ -116,7 +116,7 @@ void TaskSendCarCan(void *p_arg) { (OS_ERR *)&err); ASSERT_OS_ERROR(err); - while (1) { + LOOP { // Check if there's something to send in the queue (either IOState or // Car state from sendTritium) OSSemPend(&car_can_sem4, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); @@ -168,7 +168,7 @@ static void putIOState(void) { */ static void taskPutIoState(void *p_arg) { OS_ERR err = 0; - while (1) { + LOOP { putIOState(); OSTimeDlyHMSM(0, 0, 0, IO_STATE_DLY_MS, OS_OPT_TIME_HMSM_STRICT, &err); ASSERT_OS_ERROR(err); diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index eb54a5b79..529470643 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -61,7 +61,7 @@ void AssertOsError(volatile OS_ERR err) { // brakelight to indicate an emergency DisplayFault(err); // Display the location and error code printf("%d\n\r", err); - while (1) {} // nonrecoverable + LOOP {} // nonrecoverable } } @@ -113,7 +113,7 @@ void ThrowTaskError(ErrorCode error_code, Callback error_callback, } if (nonrecoverable == kOptNonrecov) { // Enter an infinite while loop - while (1) {} + LOOP {} } if (lock_sched == kOptLockSched) { // Only happens on recoverable errors diff --git a/Apps/Src/main.c b/Apps/Src/main.c index eab47a1ac..9cb0c110b 100644 --- a/Apps/Src/main.c +++ b/Apps/Src/main.c @@ -13,6 +13,9 @@ #include "Minions.h" #include "Pedals.h" #include "SendCarCan.h" +#include "ReadCarCan.h" +#include "ReadTritium.h" +#include "SendTritium.h" #include "Tasks.h" #include "UpdateDisplay.h" #include "common.h" @@ -46,7 +49,7 @@ int main(void) { OSStart(&err); ASSERT_OS_ERROR(err); - while (1) {} + LOOP {} } void TaskInit(void *p_arg) { From b50d3d07e24e3fdd9eaa219146baa6e134adff7f Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 27 Jan 2024 01:57:40 -0600 Subject: [PATCH 38/57] Completed (ish?) Contactors unit test. Probably could be improved, but this at least tests the logic we probably want to test for a unit test. Also moved some makefile define flags into C_DEFS since only those flags will be compiled with clang format/tidy (we were failing those checks before. --- BSP/STM32F413/Makefile | 18 +- Tests/UnitTests/Tests/Test_Contactors demo.c | 61 ------- Tests/UnitTests/Tests/Test_Contactors.c | 175 ++++++++++++++----- 3 files changed, 143 insertions(+), 111 deletions(-) delete mode 100644 Tests/UnitTests/Tests/Test_Contactors demo.c diff --git a/BSP/STM32F413/Makefile b/BSP/STM32F413/Makefile index 48bd01052..6301677fd 100644 --- a/BSP/STM32F413/Makefile +++ b/BSP/STM32F413/Makefile @@ -113,25 +113,25 @@ C_INCLUDES = \ -I../../RTOS/uCOS-III-STM32F4/uC-LIB/ \ -I../../Tests/Inc/ \ -# compile gcc flags -ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections - -CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -Werror -fdata-sections -ffunction-sections - ifeq ($(DEBUG), 1) -CFLAGS += -g3 -gdwarf-2 -DDEBUG +C_DEFS += -g3 -gdwarf-2 -DDEBUG endif ifeq ($(MOTOR_LOOPBACK), 1) -CFLAGS += -DMOTOR_LOOPBACK +C_DEFS += -DMOTOR_LOOPBACK endif ifeq ($(CAR_LOOPBACK), 1) -CFLAGS += -DCAR_LOOPBACK +C_DEFS += -DCAR_LOOPBACK endif # Not mocking -> LOOP = while(1) -CFLAGS += -D'LOOP=while(1)' +C_DEFS += -D'LOOP=while(1)' + +# compile gcc flags +ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections + +CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -Werror -fdata-sections -ffunction-sections # Generate dependency information CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" diff --git a/Tests/UnitTests/Tests/Test_Contactors demo.c b/Tests/UnitTests/Tests/Test_Contactors demo.c deleted file mode 100644 index 592c08dfe..000000000 --- a/Tests/UnitTests/Tests/Test_Contactors demo.c +++ /dev/null @@ -1,61 +0,0 @@ -/** - * @copyright Copyright (c) 2018-2024 UT Longhorn Racing Solar - * @file Test_Contactors.c - * @brief An annotated example unit test written for the driver Contactors.c - * - */ - -#include "unity.h" // Contains assertions for testing -#include "Contactors.h" // Header of the source file to test -//#include "fff.h" // Fake Function Framework for working with mocks - -// Global variables for FFF; must be included once per unit-test file -DEFINE_FFF_GLOBALS; - - -// Special function required by Unity that will run before each test -void setUp(void){ - // Reset the fakes' call and argument history between tests - RESET_FAKE(BSP_GPIO_Write_Pin) // not really needed - RESET_FAKE(BSP_GPIO_Init) // technically not needed since we only use this in one test - RESET_FAKE(OSMutexCreate) // "" - RESET_FAKE(BSP_GPIO_Get_State) // same here - RESET_FAKE(OSMutexPend) //"" - RESET_FAKE(OSMutexPost) // "" - // Would like to make this part less tedious but also you'll need to deal with all of these anyways -} - - -// Another required function from Unity that will run after each test -void tearDown(void){ - // Left blank because we don't need it -} - - -void test_Contactors_Init(){ - // Check that BSP_GPIO_Init was called to initialize - // Contactors port for Array and Motor Precharge pins to be outputs - TEST_ASSERT_EQUAL(BSP_GPIO_Init_fake.arg0_history[0], CONTACTORS_PORT) - TEST_ASSERT_EQUAL(BSP_GPIO_Init_fake.arg1_history[0], (ARRAY_PRECHARGE_BYPASS_PIN | MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN)) - TEST_ASSERT_EQUAL (BSP_GPIO_Init_fake.arg2_history[0], (1)) - - // umm set contactor says it should only be called if a mutex is held...? - // also I don't know how to test the order in which functions were called - - - // Check that all contactors were set to "off" - // for (int contactor = 0; contactor < NUM_CONTACTORS; ++contactor) { - // TEST_ASSERT_EQUAL(BSP_GPIO_Write_Pin_fake.arg0_history[0], CONTACTORS_PORT) - // TEST_ASSERT_EQUAL(BSP_GPIO_Write_Pin_fake.arg1_history[0], ARRAY_PRECHARGE_BYPASS_PIN) - // } - TEST_ASSERT_EQUAL(BSP_GPIO_Write_Pin_fake.arg0_history[0], CONTACTORS_PORT) - TEST_ASSERT_EQUAL(BSP_GPIO_Write_Pin_fake.arg1_history[0], ARRAY_PRECHARGE_BYPASS_PIN) - TEST_ASSERT_EQUAL(BSP_GPIO_Write_Pin_fake.arg2_history[0], OFF) - - BSP_GPIO_Turn_Array_Off_Args = {CONTACTORS_PORT, ARRAY_PRECHARGE_BYPASS_PIN, OFF} - for (int i = 0; i < 3; i++) { // number of arguments - //hmmm #define FUNC_PARAM BSP_GPIO_Write_Pin_fake.arg##i##_history[0] - TEST_ASSERT_EQUAL(FUNC_PARAM, BSP_GPIO_Turn_Array_Off_Args[i]) - } -} - diff --git a/Tests/UnitTests/Tests/Test_Contactors.c b/Tests/UnitTests/Tests/Test_Contactors.c index 9dfb75ca7..998f5b016 100644 --- a/Tests/UnitTests/Tests/Test_Contactors.c +++ b/Tests/UnitTests/Tests/Test_Contactors.c @@ -1,53 +1,146 @@ -////////////////////////////////////////// -////////////////////////////////////////// -// Unity required for this testing format -#include "unity.h" -////////////////////////////////////////// -////////////////////////////////////////// -// The header file we are unit testing: -#include "Contactors.h" -////////////////////////////////////////// -// fff header so we can DEFINE_FFF_GLOBALS -// (can only happen once per test) -#include "fff.h" - -DEFINE_FFF_GLOBALS; - -void setUp(void) {} - -void tearDown(void) {} - -void test_UnitTestContactors_Init(void){ - ContactorsInit(); +/** + * @copyright Copyright (c) 2018-2024 UT Longhorn Racing Solar + * @file Test_Contactors.c + * @brief An annotated example unit test written for the driver Contactors.c + * + */ + +#include "unity.h" // Contains assertions for testing +#include "Contactors.h" // Header of the source file to test +#include "os.h" + +// Global variables for FFF; must be included once per unit-test file +DEFINE_FFF_GLOBALS; + +// Defines for the test +#define BOOL_STATES 2 + + +// Special function required by Unity that will run before each test +void setUp(void){ + // Reset the fakes' call and argument history between tests + RESET_FAKE(BspGpioWritePin) // not really needed + RESET_FAKE(BspGpioInit) // technically not needed since we only use this in one test + RESET_FAKE(BspGpioGetState) // same here + RESET_FAKE(OSMutexPend) // "" + RESET_FAKE(OSMutexPost) // "" + // Would like to make this part less tedious but also you'll need to deal with all of these anyways +} + + +// Another required function from Unity that will run after each test +void tearDown(void){ + // Left blank because we don't need it +} + + +// Helper functions +static uint32_t count_instances_int(int match, int* array, uint32_t numElems) { + uint32_t num = 0; + for (uint16_t i = 0; i < numElems; i++) { + if (array[i] == match) { + num++; + } + } + return num; } -void test_UnitTestContactors_Get(void){ - // Contactors_Get(1); - BspGpioGetState_fake.return_val = 1; - printf("VALUE:%d\n", ContactorsGet(1)); +static uint32_t count_instances_uint16(uint16_t match, uint16_t* array, uint32_t numElems) { + uint32_t num = 0; + for (uint16_t i = 0; i < numElems; i++) { + if (array[i] == match) { + num++; + } + } + return num; +} - BspGpioGetState_fake.return_val = 0; - printf("VALUE:%d\n", ContactorsGet(1)); - for(int x = 500; x < 1000; x+=100){ - + +static uint32_t count_instances_bool(bool match, bool* array, uint32_t numElems) { + uint32_t num = 0; + for (uint16_t i = 0; i < numElems; i++) { + if (array[i] == match) { + num++; + } } + return num; } -void test_UnitTestContactors_Set(void){ - printf("VALUE:%d\n", ContactorsSet(1, 1, 1)); +// Tests +void test_ContactorsInit(){ + ContactorsInit(); + // Check that BspGpioInit was called to initialize + // Contactors port for Array and Motor Precharge pins to be outputs + TEST_ASSERT_EQUAL(1, BspGpioInit_fake.call_count); + TEST_ASSERT_EQUAL(CONTACTORS_PORT, BspGpioInit_fake.arg0_val); + TEST_ASSERT_EQUAL((ARRAY_PRECHARGE_BYPASS_PIN | MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN), BspGpioInit_fake.arg1_val); + TEST_ASSERT_EQUAL (1, BspGpioInit_fake.arg2_val); - BspGpioGetState_fake.return_val = 1; - printf("VALUE:%d\n", ContactorsSet(1, 1, 1)); - + // Check that all pins were set to OFF + TEST_ASSERT_EQUAL(BspGpioWritePin_fake.call_count, kNumContactors); + TEST_ASSERT_EQUAL(kNumContactors, count_instances_int(CONTACTORS_PORT, (int *)BspGpioWritePin_fake.arg0_history, kNumContactors)); + TEST_ASSERT_EQUAL(1, count_instances_uint16(ARRAY_PRECHARGE_BYPASS_PIN, BspGpioWritePin_fake.arg1_history, kNumContactors)); + TEST_ASSERT_EQUAL(1, count_instances_uint16(MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN, BspGpioWritePin_fake.arg1_history, kNumContactors)); + TEST_ASSERT_EQUAL(2, count_instances_bool(OFF, (bool *)BspGpioWritePin_fake.arg2_history, kNumContactors)); +} + +void test_ContactorsGet(){ + // When BspGpio_Read is called with a certain pin, we want to make sure ContactorsGet returns the right thing + BspGpioGetState_fake.return_val = ON; // Test array and motor contactor when ON + TEST_ASSERT_EQUAL(ON, ContactorsGet(kArrayPrechargeBypassContactor)); + TEST_ASSERT_EQUAL(ON, ContactorsGet(kMotorControllerPrechargeBypassContactor)); + BspGpioGetState_fake.return_val = OFF; // Test array and motor contactor when OFF + TEST_ASSERT_EQUAL(OFF, ContactorsGet(kArrayPrechargeBypassContactor)); + TEST_ASSERT_EQUAL(OFF, ContactorsGet(kMotorControllerPrechargeBypassContactor)); + + TEST_ASSERT_EQUAL(4, BspGpioGetState_fake.call_count); +} + +void test_ContactorsSet(){ + + int mutex_calls = 0; + + // Test all input combinations + for (uint8_t contactor = 0; contactor < kNumContactors; contactor++) { + for (uint8_t state = 0; state < BOOL_STATES; state++) { + for (uint8_t blocking = 0; blocking < BOOL_STATES; blocking++) { + + uint16_t pin_mask = 0; + + if (contactor == kArrayPrechargeBypassContactor) { + pin_mask = ARRAY_PRECHARGE_BYPASS_PIN; + } else if (contactor == kMotorControllerPrechargeBypassContactor) { + pin_mask = MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN; + } + + ContactorsSet((Contactor)contactor, (bool)state, (bool)blocking); + TEST_ASSERT_EQUAL(CONTACTORS_PORT, BspGpioWritePin_fake.arg0_val); + TEST_ASSERT_EQUAL(pin_mask, BspGpioWritePin_fake.arg1_val); + TEST_ASSERT_EQUAL(state, BspGpioWritePin_fake.arg2_val); + + if (blocking){ + TEST_ASSERT_EQUAL(OS_OPT_PEND_BLOCKING, OSMutexPend_fake.arg1_val); + } else { + TEST_ASSERT_EQUAL(OS_OPT_PEND_BLOCKING, OSMutexPend_fake.arg1_val); + } + + mutex_calls++; + TEST_ASSERT_EQUAL(mutex_calls, OSMutexPend_fake.call_count); + TEST_ASSERT_EQUAL(mutex_calls, OSMutexPost_fake.call_count); + + } + } + } + + TEST_ASSERT_EQUAL(kNumContactors * BOOL_STATES * BOOL_STATES, BspGpioWritePin_fake.call_count); } -/*=======MAIN=====*/ -int main(void) -{ - UNITY_BEGIN(); - RUN_TEST(test_UnitTestContactors_Init); - RUN_TEST(test_UnitTestContactors_Get); - RUN_TEST(test_UnitTestContactors_Set); +// Runs the tests +int main(void) { + UNITY_BEGIN(); // UNITY_BEGIN and UNITY_END are required + RUN_TEST(test_ContactorsInit); + RUN_TEST(test_ContactorsGet); + RUN_TEST(test_ContactorsSet); return UNITY_END(); } \ No newline at end of file From 1cef3f22f2ec16725c7176f3342b9d9f998a6b6d Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 27 Jan 2024 02:14:49 -0600 Subject: [PATCH 39/57] Used clang checks. Still fails at ASSERT_OS_ERROR. --- Apps/Inc/ReadCarCan.h | 2 +- Apps/Inc/ReadTritium.h | 2 +- Apps/Inc/SendCarCan.h | 1 - Apps/Inc/SendTritium.h | 3 +-- Apps/Inc/UpdateDisplay.h | 1 - Apps/Src/DebugDump.c | 1 - Apps/Src/ReadCarCan.c | 6 +++--- Apps/Src/Tasks.c | 2 +- Apps/Src/UpdateDisplay.c | 4 +--- Apps/Src/main.c | 2 +- 10 files changed, 9 insertions(+), 15 deletions(-) diff --git a/Apps/Inc/ReadCarCan.h b/Apps/Inc/ReadCarCan.h index 42ab32ce1..8b56ee8dd 100644 --- a/Apps/Inc/ReadCarCan.h +++ b/Apps/Inc/ReadCarCan.h @@ -15,7 +15,7 @@ /** * Task Prototype -*/ + */ void TaskReadCarCan(void* p_arg); /** diff --git a/Apps/Inc/ReadTritium.h b/Apps/Inc/ReadTritium.h index b4e007a3b..4c61bc945 100644 --- a/Apps/Inc/ReadTritium.h +++ b/Apps/Inc/ReadTritium.h @@ -33,7 +33,7 @@ typedef enum { /** * Task Prototype -*/ + */ void TaskReadTritium(void* p_arg); float MotorRpmGet(); diff --git a/Apps/Inc/SendCarCan.h b/Apps/Inc/SendCarCan.h index c826be8d8..aedfabc8d 100644 --- a/Apps/Inc/SendCarCan.h +++ b/Apps/Inc/SendCarCan.h @@ -8,7 +8,6 @@ */ void TaskSendCarCan(void* p_arg); - /** * @brief Initialize SendCarCAN */ diff --git a/Apps/Inc/SendTritium.h b/Apps/Inc/SendTritium.h index ed1455fc3..df675c8c6 100644 --- a/Apps/Inc/SendTritium.h +++ b/Apps/Inc/SendTritium.h @@ -49,10 +49,9 @@ typedef struct TritiumState { /** * Task Prototype -*/ + */ void TaskSendTritium(void* p_arg); - // Getter functions for static variables bool GetCruiseEnable(void); bool GetCruiseSet(void); diff --git a/Apps/Inc/UpdateDisplay.h b/Apps/Inc/UpdateDisplay.h index 28f273620..81460bb15 100644 --- a/Apps/Inc/UpdateDisplay.h +++ b/Apps/Inc/UpdateDisplay.h @@ -50,7 +50,6 @@ typedef enum { kState0 = 0, kState1 = 1, kState2 = 2 } TriState; */ void TaskUpdateDisplay(void* p_arg); - /** * @brief Initializes UpdateDisplay application * @returns UpdateDisplayError_t diff --git a/Apps/Src/DebugDump.c b/Apps/Src/DebugDump.c index 7561dd12b..22a40171f 100644 --- a/Apps/Src/DebugDump.c +++ b/Apps/Src/DebugDump.c @@ -24,7 +24,6 @@ void TaskDebugDump(void *p_arg) { OS_ERR err = 0; LOOP { - // Get pedal information int8_t accel_pedal = PedalsRead(kAccelerator); printf("kAccelerator: %d\n\r", accel_pedal); diff --git a/Apps/Src/ReadCarCan.c b/Apps/Src/ReadCarCan.c index 308bd04e4..af849379a 100644 --- a/Apps/Src/ReadCarCan.c +++ b/Apps/Src/ReadCarCan.c @@ -376,9 +376,9 @@ void TaskReadCarCan(void *p_arg) { // BPS sent a message ErrorStatus status = CanBusRead(&data_buf, true, CARCAN); if (status != SUCCESS) { - #ifndef MOCKING - continue; - #endif +#ifndef MOCKING + continue; +#endif } switch (data_buf.id) { // Switch case based on BPS msg received diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 529470643..cdfa10d5f 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -45,7 +45,7 @@ CPU_STK command_line_stk[TASK_COMMAND_LINE_STACK_SIZE]; // Variables to store error codes, stored and cleared in task error assert // functions -ErrorCode error_read_car_can = kReadCarCanErrNone; +ErrorCode error_read_car_can = kReadCarCanErrNone; ErrorCode error_read_tritium = kNone; // Initialized to no error ErrorCode error_update_display = kUpdateDisplayErrNone; diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index a472b4341..f938028f6 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -320,9 +320,7 @@ void UpdateDisplayClearQueue() { * @brief Loops through the display queue and sends all messages */ void TaskUpdateDisplay(void* p_arg) { - LOOP { - updateDisplayPopNext(); - } + LOOP { updateDisplayPopNext(); } } /** diff --git a/Apps/Src/main.c b/Apps/Src/main.c index 9cb0c110b..7d3418d48 100644 --- a/Apps/Src/main.c +++ b/Apps/Src/main.c @@ -12,9 +12,9 @@ #include "Display.h" #include "Minions.h" #include "Pedals.h" -#include "SendCarCan.h" #include "ReadCarCan.h" #include "ReadTritium.h" +#include "SendCarCan.h" #include "SendTritium.h" #include "Tasks.h" #include "UpdateDisplay.h" From aa23619c12a630a5e9e0269bbe398a2f5d6f8460 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 27 Jan 2024 02:20:57 -0600 Subject: [PATCH 40/57] Finished making checks; things now formatted properly --- Apps/Inc/Tasks.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Apps/Inc/Tasks.h b/Apps/Inc/Tasks.h index 47571fe61..2f1267387 100644 --- a/Apps/Inc/Tasks.h +++ b/Apps/Inc/Tasks.h @@ -162,7 +162,7 @@ void AssertOsError(OS_ERR err); #if DEBUG == 1 #define ASSERT_OS_ERROR(err) \ - if (err != OS_ERR_NONE) { \ + if ((err) != OS_ERR_NONE) { \ printf("Error asserted at %s, line %d: %d\n\r", __FILE__, __LINE__, \ err); \ } \ From c765defb4ad67ab111d8beb80cc63a1cda780106 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 27 Jan 2024 09:32:49 -0600 Subject: [PATCH 41/57] Small comment changes. --- Tests/UnitTests/Tests/Test_Contactors.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Tests/UnitTests/Tests/Test_Contactors.c b/Tests/UnitTests/Tests/Test_Contactors.c index 998f5b016..6a16ffda6 100644 --- a/Tests/UnitTests/Tests/Test_Contactors.c +++ b/Tests/UnitTests/Tests/Test_Contactors.c @@ -19,12 +19,13 @@ DEFINE_FFF_GLOBALS; // Special function required by Unity that will run before each test void setUp(void){ // Reset the fakes' call and argument history between tests + // Would eventually like to make this part less tedious, + // but also you'll need to deal with all of these anyways RESET_FAKE(BspGpioWritePin) // not really needed RESET_FAKE(BspGpioInit) // technically not needed since we only use this in one test - RESET_FAKE(BspGpioGetState) // same here + RESET_FAKE(BspGpioGetState) // "" RESET_FAKE(OSMutexPend) // "" RESET_FAKE(OSMutexPost) // "" - // Would like to make this part less tedious but also you'll need to deal with all of these anyways } @@ -66,17 +67,19 @@ static uint32_t count_instances_bool(bool match, bool* array, uint32_t numElems) return num; } + // Tests void test_ContactorsInit(){ ContactorsInit(); // Check that BspGpioInit was called to initialize // Contactors port for Array and Motor Precharge pins to be outputs - TEST_ASSERT_EQUAL(1, BspGpioInit_fake.call_count); - TEST_ASSERT_EQUAL(CONTACTORS_PORT, BspGpioInit_fake.arg0_val); + TEST_ASSERT_EQUAL(1, BspGpioInit_fake.call_count); // Should have called BspGpioInit once + TEST_ASSERT_EQUAL(CONTACTORS_PORT, BspGpioInit_fake.arg0_val); TEST_ASSERT_EQUAL((ARRAY_PRECHARGE_BYPASS_PIN | MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN), BspGpioInit_fake.arg1_val); TEST_ASSERT_EQUAL (1, BspGpioInit_fake.arg2_val); // Check that all pins were set to OFF + // Don't worry about order as long both pins show up in the last two call arguments TEST_ASSERT_EQUAL(BspGpioWritePin_fake.call_count, kNumContactors); TEST_ASSERT_EQUAL(kNumContactors, count_instances_int(CONTACTORS_PORT, (int *)BspGpioWritePin_fake.arg0_history, kNumContactors)); TEST_ASSERT_EQUAL(1, count_instances_uint16(ARRAY_PRECHARGE_BYPASS_PIN, BspGpioWritePin_fake.arg1_history, kNumContactors)); @@ -85,7 +88,7 @@ void test_ContactorsInit(){ } void test_ContactorsGet(){ - // When BspGpio_Read is called with a certain pin, we want to make sure ContactorsGet returns the right thing + // Make sure ContactorsGet returns the right thing BspGpioGetState_fake.return_val = ON; // Test array and motor contactor when ON TEST_ASSERT_EQUAL(ON, ContactorsGet(kArrayPrechargeBypassContactor)); TEST_ASSERT_EQUAL(ON, ContactorsGet(kMotorControllerPrechargeBypassContactor)); @@ -97,6 +100,7 @@ void test_ContactorsGet(){ TEST_ASSERT_EQUAL(4, BspGpioGetState_fake.call_count); } + void test_ContactorsSet(){ int mutex_calls = 0; From 25b2669b0936723ac81cfba69233fd3b834c3d10 Mon Sep 17 00:00:00 2001 From: Madeleine Lee <74027612+KnockbackNemo@users.noreply.github.com> Date: Sat, 27 Jan 2024 14:40:29 -0600 Subject: [PATCH 42/57] Update README.md (#412) Add "integration" to integration document link so that we can ctr+f it --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7de6b781a..32a8cbaa7 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ make clean ### Usage -Follow our [documentation](https://utexas.sharepoint.com/:w:/s/ENGR-LonghornRacing/EUx6dS9swT1Js18ZlOrAfJIBKsM_7dLuQ818EnGZKrpbAQ?e=PyRIyh) to set up the Controls test rig, power the board with 12V, and use ```make flash``` to flash the board with your ```Objects/controls-leader.elf``` executable, either built from source using ```make leader``` or placed in the Objects folder from your intended release. +Follow our [integration documentation](https://utexas.sharepoint.com/:w:/s/ENGR-LonghornRacing/EUx6dS9swT1Js18ZlOrAfJIBKsM_7dLuQ818EnGZKrpbAQ?e=PyRIyh) to set up the Controls test rig, power the board with 12V, and use ```make flash``` to flash the board with your ```Objects/controls-leader.elf``` executable, either built from source using ```make leader``` or placed in the Objects folder from your intended release. ### Running Tests @@ -200,4 +200,4 @@ This project is licensed under the MIT License - see [LICENSE](LICENSE) file for See the list of [contributors](https://github.com/lhr-solar/Controls/contributors) who participated in this project. -**[Back to top](#table-of-contents)** \ No newline at end of file +**[Back to top](#table-of-contents)** From d6520c43036113d50d8af48297de730979d000e9 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Wed, 31 Jan 2024 13:18:28 -0600 Subject: [PATCH 43/57] Added more annotations to the test files. --- Tests/UnitTests/Tests/Test_Contactors.c | 35 ++++++++++------ Tests/UnitTests/Tests/Test_Pedals.c | 56 ++++++++++++++++++------- Tests/UnitTests/Tests/Test_ReadCarCan.c | 32 +++++++++----- 3 files changed, 84 insertions(+), 39 deletions(-) diff --git a/Tests/UnitTests/Tests/Test_Contactors.c b/Tests/UnitTests/Tests/Test_Contactors.c index 6a16ffda6..1003f28c2 100644 --- a/Tests/UnitTests/Tests/Test_Contactors.c +++ b/Tests/UnitTests/Tests/Test_Contactors.c @@ -2,7 +2,8 @@ * @copyright Copyright (c) 2018-2024 UT Longhorn Racing Solar * @file Test_Contactors.c * @brief An annotated example unit test written for the driver Contactors.c - * + * Thing tested: Contactors functions + * Mocks used: BSP, OS (though all things not tested are still mocked) */ #include "unity.h" // Contains assertions for testing @@ -19,13 +20,14 @@ DEFINE_FFF_GLOBALS; // Special function required by Unity that will run before each test void setUp(void){ // Reset the fakes' call and argument history between tests - // Would eventually like to make this part less tedious, - // but also you'll need to deal with all of these anyways - RESET_FAKE(BspGpioWritePin) // not really needed - RESET_FAKE(BspGpioInit) // technically not needed since we only use this in one test - RESET_FAKE(BspGpioGetState) // "" - RESET_FAKE(OSMutexPend) // "" - RESET_FAKE(OSMutexPost) // "" + // This is important if you'll be using this functions in multiple tests + // In our case we don't need them since we don't use functions between tests, + // but this is what you would do: + RESET_FAKE(BspGpioWritePin) + RESET_FAKE(BspGpioInit) + RESET_FAKE(BspGpioGetState) + RESET_FAKE(OSMutexPend) + RESET_FAKE(OSMutexPost) } @@ -35,7 +37,7 @@ void tearDown(void){ } -// Helper functions +// **** Helper functions **** // static uint32_t count_instances_int(int match, int* array, uint32_t numElems) { uint32_t num = 0; for (uint16_t i = 0; i < numElems; i++) { @@ -68,13 +70,15 @@ static uint32_t count_instances_bool(bool match, bool* array, uint32_t numElems) } -// Tests + +// **** Tests ****// + void test_ContactorsInit(){ ContactorsInit(); // Check that BspGpioInit was called to initialize // Contactors port for Array and Motor Precharge pins to be outputs TEST_ASSERT_EQUAL(1, BspGpioInit_fake.call_count); // Should have called BspGpioInit once - TEST_ASSERT_EQUAL(CONTACTORS_PORT, BspGpioInit_fake.arg0_val); + TEST_ASSERT_EQUAL(CONTACTORS_PORT, BspGpioInit_fake.arg0_val); // First argument to BspGpioInit should be CONTACTORS_PORT TEST_ASSERT_EQUAL((ARRAY_PRECHARGE_BYPASS_PIN | MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN), BspGpioInit_fake.arg1_val); TEST_ASSERT_EQUAL (1, BspGpioInit_fake.arg2_val); @@ -112,23 +116,27 @@ void test_ContactorsSet(){ uint16_t pin_mask = 0; + // Set which pin we should see targeted if (contactor == kArrayPrechargeBypassContactor) { pin_mask = ARRAY_PRECHARGE_BYPASS_PIN; } else if (contactor == kMotorControllerPrechargeBypassContactor) { pin_mask = MOTOR_CONTROLLER_PRECHARGE_BYPASS_PIN; } + // Run ContactorsSet and check that BspGpioWritePin was called with the correct parameters ContactorsSet((Contactor)contactor, (bool)state, (bool)blocking); TEST_ASSERT_EQUAL(CONTACTORS_PORT, BspGpioWritePin_fake.arg0_val); TEST_ASSERT_EQUAL(pin_mask, BspGpioWritePin_fake.arg1_val); TEST_ASSERT_EQUAL(state, BspGpioWritePin_fake.arg2_val); + // Check if the call followed the blocking/non-blocking parameter value if (blocking){ - TEST_ASSERT_EQUAL(OS_OPT_PEND_BLOCKING, OSMutexPend_fake.arg1_val); + TEST_ASSERT_EQUAL(OS_OPT_PEND_BLOCKING, OSMutexPend_fake.arg2_val); } else { - TEST_ASSERT_EQUAL(OS_OPT_PEND_BLOCKING, OSMutexPend_fake.arg1_val); + TEST_ASSERT_EQUAL(OS_OPT_PEND_NON_BLOCKING, OSMutexPend_fake.arg2_val); } + // Check that we pended and posted to a mutex mutex_calls++; TEST_ASSERT_EQUAL(mutex_calls, OSMutexPend_fake.call_count); TEST_ASSERT_EQUAL(mutex_calls, OSMutexPost_fake.call_count); @@ -137,6 +145,7 @@ void test_ContactorsSet(){ } } + // Check that BspGpioWritePin was called once for each call to ContactorsSet TEST_ASSERT_EQUAL(kNumContactors * BOOL_STATES * BOOL_STATES, BspGpioWritePin_fake.call_count); } diff --git a/Tests/UnitTests/Tests/Test_Pedals.c b/Tests/UnitTests/Tests/Test_Pedals.c index 55dac3880..cf3c5b859 100644 --- a/Tests/UnitTests/Tests/Test_Pedals.c +++ b/Tests/UnitTests/Tests/Test_Pedals.c @@ -1,46 +1,72 @@ -////////////////////////////////////////// -////////////////////////////////////////// -// Unity required for this testing format +/** + * + *@copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar + * @file Test_Pedals.c + * @brief An example containing the basic format of a unit test. + * Though not a functional test, it still contains some major elements + * that are necessary in any unit test. + * Thing tested (if test were complete): Pedals functions + * Mocks used:BSP functions (though all things not tested are still mocked) +*/ + +// Unity: the unit testing framework we are using +// Unity contains the assertions required for this testing format #include "unity.h" -////////////////////////////////////////// -////////////////////////////////////////// -// The header file we are unit testing: + +// The header file we are unit testing #include "Pedals.h" -////////////////////////////////////////// -// fff header so we can DEFINE_FFF_GLOBALS -// (can only happen once per test) + +// Fake Function Framework: helps us generate mocks and store data +// We need the header here for DEFINE_FFF_GLOBALS #include "fff.h" +// This defines global variables used for test data +// (and therefore can't be defined multiple times in a build) DEFINE_FFF_GLOBALS; +// Special function from Unity that runs before each test void setUp(void) {} +// Special function from Unity that runs after each test void tearDown(void) {} -void test_UnitTestPedals_Init(void){ +// A test for PedalsInit which we wrote ourselves and which gets called in main +// This example calls PedalsInit but doesn't actually verify anthing +void test_UnitTestPedalsInit(void){ PedalsInit(); } -void test_UnitTestPedals_Read(void){ +// Another test, this time for PedalsRead, which just demos using fake functions +void test_UnitTestPedalsRead(void){ for(int x = 500; x < 1000; x+=100){ - BspAdcGetMillivoltage_fake.return_val = x; + + // We have defined mock functions (found in the Mocks folder) using fff + // When we unit test, we include the mock functions in place of the real ones + // One of the things we can do with mocks is set their return value + BspAdcGetMillivoltage_fake.return_val = x; + // Now whenever BspAdcGetMillivoltage is called, the mock will return x + PedalsRead(1); printf("\n\r%d\r", PedalsRead(1)); } } +// A test that will always fail void test_UnitTestPedals_Read_This_Will_Fail(void){ - TEST_ASSERT_EQUAL(PedalsRead(1), 30); + // Unity gives us asserts to verify values + // When an assert fails, Unity will tell us our test has failed + TEST_ASSERT_EQUAL(PedalsRead(1), 30); } /*=======MAIN=====*/ +// Here we use Unity's framework to run the tests we've written int main(void) { UNITY_BEGIN(); - RUN_TEST(test_UnitTestPedals_Init); - RUN_TEST(test_UnitTestPedals_Read); + RUN_TEST(test_UnitTestPedalsInit); + RUN_TEST(test_UnitTestPedalsRead); RUN_TEST(test_UnitTestPedals_Read_This_Will_Fail); return UNITY_END(); } \ No newline at end of file diff --git a/Tests/UnitTests/Tests/Test_ReadCarCan.c b/Tests/UnitTests/Tests/Test_ReadCarCan.c index 6a04392b7..6dcc6fce6 100644 --- a/Tests/UnitTests/Tests/Test_ReadCarCan.c +++ b/Tests/UnitTests/Tests/Test_ReadCarCan.c @@ -1,16 +1,23 @@ -////////////////////////////////////////// -////////////////////////////////////////// +/** + * + *@copyright Copyright (c) 2018-2023 UT Longhorn Racing Solar + * @file Test_ReadCarCan.c + * @brief Additional unit testing example for ReadCanCan. + * While not a full test, it introduces a couple test strategies + * Thing tested (if test were complete): ReadCarCan + * Mocks used:CanBus, UpdateDisplay (though all things not tested are still mocked) + * Note: not a real test, so we don't really mind that it fails +*/ // Unity required for this testing format #include "unity.h" -////////////////////////////////////////// -////////////////////////////////////////// + // The header file we are unit testing: #include "ReadCarCan.h" -////////////////////////////////////////// + // fff header so we can DEFINE_FFF_GLOBALS // (can only happen once per test) #include "fff.h" -///////////////////// + // Mock headers #include "UpdateDisplay.h" #include "CanBus.h" @@ -33,6 +40,9 @@ void setUp(void) { void tearDown(void) {} +// We can use a custom fake to dictate what happens when our mock function is called +// A default mock doesn't do anything, but defining a custom mock lets us do things +// like store a message in a CanData argument to simulate a message being read ErrorStatus CANbus_Custom_fake_bps(CanData* data, bool blocking, Can bus){ *data = bps_trip_msg; return SUCCESS; @@ -45,10 +55,10 @@ ErrorStatus CANbus_Custom_fake_bpscontactor(CanData* data, bool blocking, Can bu void test_UnitTest_bsptrip(void){ TaskInit(NULL); - CanBusRead_fake.custom_fake = CANbus_Custom_fake_bps; + CanBusRead_fake.custom_fake = CANbus_Custom_fake_bps; // Set CanBusRead to use our custom fake TaskReadCarCan(NULL); printf("\n\r%d\n\r", CanBusRead_fake.call_count); - // + TEST_ASSERT_EQUAL(3, ThrowTaskError_fake.arg0_history[0]); TEST_ASSERT_EQUAL(4, ThrowTaskError_fake.arg0_history[1]); printf("%d", ThrowTaskError_fake.call_count); @@ -58,12 +68,12 @@ void test_UnitTest_bsptrip(void){ void test_UnitTest_bspcontactor(void){ TaskInit(NULL); - CanBusRead_fake.custom_fake = CANbus_Custom_fake_bpscontactor; + CanBusRead_fake.custom_fake = CANbus_Custom_fake_bpscontactor; // Set CanBusRead to a different custom fake TaskReadCarCan(NULL); printf("\n\r%d\n\r", CanBusRead_fake.call_count); - // + TEST_ASSERT_EQUAL(3, ThrowTaskError_fake.arg0_history[0]); - //TEST_ASSERT_EQUAL(4, ThrowTaskError_fake.arg0_history[1]); + TEST_ASSERT_EQUAL(4, ThrowTaskError_fake.arg0_history[1]); printf("%d", ThrowTaskError_fake.call_count); TEST_ASSERT_EQUAL(false, UpdateDisplaySetArray_fake.arg0_history[0]); } From d2c2c7a1f359f180506ac9fad4ac8eac16082ec4 Mon Sep 17 00:00:00 2001 From: Nathaniel Delgado <89701060+NathanielDelgado@users.noreply.github.com> Date: Sat, 10 Feb 2024 13:59:52 -0600 Subject: [PATCH 44/57] Reversed polarity on minion ignition readings (#417) --- Apps/Src/DebugDump.c | 3 +-- Apps/Src/ReadCarCan.c | 4 ++-- Apps/Src/SendCarCan.c | 2 +- Drivers/Src/Minions.c | 5 +++++ 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Apps/Src/DebugDump.c b/Apps/Src/DebugDump.c index 362015776..06abe5922 100644 --- a/Apps/Src/DebugDump.c +++ b/Apps/Src/DebugDump.c @@ -34,9 +34,8 @@ void TaskDebugDump(void *p_arg) { // Get minion information for (Pin pin = 0; pin < kNumPins; pin++) { bool pin_state = MinionsRead(pin); - // Ignition pins are negative logic, special-case them printf("%s: %s\n\r", minionpin_string[pin], - pin_state ^ (pin == kIgn1 || pin == kIgn2) ? "on" : "off"); + pin_state ? "on" : "off"); } // Get contactor info diff --git a/Apps/Src/ReadCarCan.c b/Apps/Src/ReadCarCan.c index 5617fce2b..6da7c6cb0 100644 --- a/Apps/Src/ReadCarCan.c +++ b/Apps/Src/ReadCarCan.c @@ -295,8 +295,8 @@ void TurnMotorControllerPbcOff(void) { * @param None */ void UpdatePrechargeContactors(void) { - arr_ign_status = (!MinionsRead(kIgn1)); - mc_ign_status = (!MinionsRead(kIgn2)); + arr_ign_status = MinionsRead(kIgn1); + mc_ign_status = MinionsRead(kIgn2); // Logic helper in cases both are off or (impossible) on bool both_status_off = !mc_ign_status && !arr_ign_status; diff --git a/Apps/Src/SendCarCan.c b/Apps/Src/SendCarCan.c index 086a0a70b..c00517013 100644 --- a/Apps/Src/SendCarCan.c +++ b/Apps/Src/SendCarCan.c @@ -158,7 +158,7 @@ static void putIOState(void) { } // Tell BPS if the array contactor should be on - message.data[3] |= (!MinionsRead(kIgn1) || !MinionsRead(kIgn2)) << 2; + message.data[3] |= (MinionsRead(kIgn1) || MinionsRead(kIgn2)) << 2; CanBusSend(message, true, CARCAN); } diff --git a/Drivers/Src/Minions.c b/Drivers/Src/Minions.c index 6a97d03b5..983f38bae 100644 --- a/Drivers/Src/Minions.c +++ b/Drivers/Src/Minions.c @@ -22,6 +22,11 @@ void MinionsInit(void) { bool MinionsRead(Pin pin) { if ((kPininfoLut[pin].direction == kInput)) { + // Ignition pins are negative logic, special-case them + if (pin == kIgn1 || pin == kIgn2) { + return !((bool)BspGpioReadPin(kPininfoLut[pin].port, + kPininfoLut[pin].pin_mask)); + } return (bool)BspGpioReadPin(kPininfoLut[pin].port, kPininfoLut[pin].pin_mask); } From cd3403e88c1955a35458fe434a9aed9dc9149818 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 2 Mar 2024 00:52:56 -0600 Subject: [PATCH 45/57] Removed/restored files that were committed by accident. --- .vscode/LHR.code-workspace | 18 --- Tests/UnitTests/MakefileBSPAnnotated | 209 --------------------------- 2 files changed, 227 deletions(-) delete mode 100644 Tests/UnitTests/MakefileBSPAnnotated diff --git a/.vscode/LHR.code-workspace b/.vscode/LHR.code-workspace index d09f12fea..9e5310e01 100644 --- a/.vscode/LHR.code-workspace +++ b/.vscode/LHR.code-workspace @@ -17,24 +17,6 @@ "args": ["-i"] }, }, - "files.associations": { - "*.db": "sql", - "contactors.h": "c", - "pedals.h": "c", - "bsp_adc.h": "c", - "config.h": "c", - "unity.h": "c", - "fff.h": "c", - "common.h": "c", - "stdio.h": "c", - "stm32f4xx.h": "c", - "bsp_gpio.h": "c", - "os.h": "c", - "tasks.h": "c", - "canbus.h": "c", - "readcarcan.h": "c", - "minions.h": "c" - }, }, "tasks": { "version": "2.0.0", diff --git a/Tests/UnitTests/MakefileBSPAnnotated b/Tests/UnitTests/MakefileBSPAnnotated deleted file mode 100644 index 20c594793..000000000 --- a/Tests/UnitTests/MakefileBSPAnnotated +++ /dev/null @@ -1,209 +0,0 @@ -###################################### -# target -###################################### -TARGET = controls-leader - - -###################################### -# building variables -###################################### -# optimization -ifeq ($(DEBUG), 0) -OPT = -O3 -else -OPT = -Og -g3 -endif - -####################################### -# paths -####################################### -# Build path -BUILD_DIR = ../../Objects - -###################################### -# source -###################################### -# C sources -# since current path is in the BSP folder, go to the top level with ../../ -C_SOURCES = \ #C_SOURCES is a long space-separated lists of a bunch of files -$(wildcard ../../Drivers/Src/*.c) \ -$(wildcard ../../BSP/STM32F413/Src/*.c) \ -$(wildcard ../../BSP/STM32F413/STM32F4xx_StdPeriph_Driver/Src/*.c) \ -$(wildcard ../../CMSIS/DSP_Lib/Source/*.c) \ -$(wildcard ../../RTOS/uCOS-III-STM32F4/uCOS-III/Source/*.c) \ -$(wildcard ../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/*.c) \ -$(wildcard ../../RTOS/uCOS-III-STM32F4/uC-CPU/*.c) \ -$(wildcard ../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/*.c) \ -$(wildcard ../../RTOS/uCOS-III-STM32F4/uC-LIB/*.c) - -# This line adds everything in Apps/Src/*.c except for main.c, then adds the test file -C_SOURCES += \ -$(filter-out ../../Apps/Src/main.c, $(wildcard ../../Apps/Src/*.c)) \ -../../$(TEST) - -# ASM sources -ASM_SOURCES = \ -../../BSP/STM32F413/Src/startup_stm32f413xx.s \ -../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/os_cpu_a.s \ -../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/cpu_a.s - - -####################################### -# binaries -####################################### -PREFIX = arm-none-eabi- -# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) -# either it can be added to the PATH environment variable. -ifdef GCC_PATH -CC = $(GCC_PATH)/$(PREFIX)gcc #Set CC as the given compiler for implicit rules -AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp -CP = $(GCC_PATH)/$(PREFIX)objcopy -SZ = $(GCC_PATH)/$(PREFIX)size -else -CC = $(PREFIX)gcc -AS = $(PREFIX)gcc -x assembler-with-cpp -CP = $(PREFIX)objcopy -SZ = $(PREFIX)size -endif -HEX = $(CP) -O ihex -BIN = $(CP) -O binary -S - -SF = st-flash - -####################################### -# CFLAGS -####################################### -# cpu -CPU = -mcpu=cortex-m4 - -# float-abi -FLOAT-ABI = -mfloat-abi=soft - -# mcu -MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) - -# macros for gcc -# AS defines -AS_DEFS = - -# C defines -C_DEFS = \ --DSTM32F413_423xx \ --DUSE_STDPERIPH_DRIVER \ --D__FPU_PRESENT - - -# AS includes -AS_INCLUDES = - -# C includes -# since current path is in the BSP folder, go to the top level with ../../ -C_INCLUDES = \ --I../../Apps/Inc \ --I../../Drivers/Inc \ --I../../Config/Inc \ --I../../BSP/Inc \ --I../../CMSIS/Device/ST/STM32F4xx/Include \ --I../../CMSIS/Include \ --I../../BSP/STM32F413/STM32F4xx_StdPeriph_Driver/Inc \ --I../../RTOS/uCOS-III-STM32F4/uCOS-III/Source/ \ --I../../RTOS/uCOS-III-STM32F4/uCOS-III/Ports/ARM-Cortex-M4/Generic/GNU/ \ --I../../RTOS/uCOS-III-STM32F4/uC-CPU/ \ --I../../RTOS/uCOS-III-STM32F4/uC-CPU/ARM-Cortex-M4/GNU/ \ --I../../RTOS/uCOS-III-STM32F4/uC-LIB/ \ --I../../Tests/Inc/ \ - -# compile gcc flags -ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections - -CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -Werror -fdata-sections -ffunction-sections - -ifeq ($(DEBUG), 1) -CFLAGS += -g3 -gdwarf-2 -DDEBUG -endif - -ifeq ($(MOTOR_LOOPBACK), 1) -CFLAGS += -DMOTOR_LOOPBACK -endif - -ifeq ($(CAR_LOOPBACK), 1) -CFLAGS += -DCAR_LOOPBACK -endif - -# Generate dependency information -CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" - - -####################################### -# LDFLAGS -####################################### -# link script -LDSCRIPT = ./GCC/STM32F413RHTx_FLASH.ld - -# libraries -LIBS = -lc -lm -lnosys -LIBDIR = -LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections - -# default action: build all -all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin -#Above are prereqruisites - -####################################### -# build the application -####################################### -# list of objects -OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) #Objects variable is ../../Objcts/*name*.o, using list of C sources but replacing c with o -vpath %.c $(sort $(dir $(C_SOURCES))) #I think this is saying .c files can be found in -# list of ASM program objects -OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) #Add assembly files (as .o) to the objects variable -vpath %.s $(sort $(dir $(ASM_SOURCES))) # Also list out where they can be found -# ////////////// I don't know why we need vpath if we list out the sources in C_SOURCES and ASM_SOURCES - -#Make all the .o files from the .c files -$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) # | means order only- don't check if BUILD_DIR is out of date, just make sure it exists before running this target - @echo "CC $(<:../../%=%)" - @$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ - - -# Compiles any .o file in Objects/ from assembly files -$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) - @echo "AS $(<:../../%=%)" - @$(AS) -c $(CFLAGS) $< -o $@ - -# Makes the .elf file from the .o files listed in OBJECTS which were compiled in the .o targets -$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile - @echo "LD $(<:../../%=%)" - @$(CC) $(OBJECTS) $(LDFLAGS) -o $@ #I guess this links stuff? Don't know about the LDFLAGS - @echo "SZ $(<:../../%=%)" - @$(SZ) $@ - -$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) - @echo "HEX $(<:../../%=%)" - @$(HEX) $< $@ - -$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) - @echo "BIN $(<:../../%=%)" - @$(BIN) $< $@ - -$(BUILD_DIR): - mkdir $@ - -####################################### -# clean up -####################################### -clean: - -rm -fR $(BUILD_DIR) - -####################################### -# flash -####################################### -flash: - $(SF) write $(BUILD_DIR)/$(TARGET).bin 0x8000000 - -####################################### -# dependencies -####################################### --include $(wildcard $(BUILD_DIR)/*.d) - -# *** EOF *** From b0cc9e38a660ed4dd5bc7a89160cf625a7b184a8 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 2 Mar 2024 01:29:41 -0600 Subject: [PATCH 46/57] Changed conditional while(1) to add a break if MOCKING instead of using a LOOP macro that replaces while(1). --- Apps/Src/CommandLine.c | 6 +++++- Apps/Src/DebugDump.c | 6 +++++- Apps/Src/ReadCarCan.c | 16 +++++++++++----- Apps/Src/ReadTritium.c | 5 ++++- Apps/Src/SendCarCan.c | 10 ++++++++-- Apps/Src/SendTritium.c | 6 +++++- Apps/Src/Tasks.c | 9 +++++++-- Apps/Src/UpdateDisplay.c | 8 +++++++- Apps/Src/main.c | 5 ++++- BSP/STM32F413/Makefile | 3 --- Tests/UnitTests/Makefile | 3 --- 11 files changed, 56 insertions(+), 21 deletions(-) diff --git a/Apps/Src/CommandLine.c b/Apps/Src/CommandLine.c index 0f7251e3a..fd2d92b53 100644 --- a/Apps/Src/CommandLine.c +++ b/Apps/Src/CommandLine.c @@ -106,7 +106,7 @@ void TaskCommandLine(void *p_arg) { // output welcome/help screen printf("%s", help); - LOOP { + while(1) { printf("> "); BspUartRead(kUart2, input); printf("\n\r"); @@ -121,6 +121,10 @@ void TaskCommandLine(void *p_arg) { if (err != OS_ERR_NONE) { ASSERT_OS_ERROR(err); } + + #ifdef MOCKING + break; + #endif } // Function Implementations diff --git a/Apps/Src/DebugDump.c b/Apps/Src/DebugDump.c index 22a40171f..353bd5947 100644 --- a/Apps/Src/DebugDump.c +++ b/Apps/Src/DebugDump.c @@ -23,7 +23,7 @@ static const char *gear_string[] = {FOREACH_GEAR(GENERATE_STRING)}; void TaskDebugDump(void *p_arg) { OS_ERR err = 0; - LOOP { + while(1) { // Get pedal information int8_t accel_pedal = PedalsRead(kAccelerator); printf("kAccelerator: %d\n\r", accel_pedal); @@ -65,5 +65,9 @@ void TaskDebugDump(void *p_arg) { if (err != OS_ERR_NONE) { ASSERT_OS_ERROR(err); } + + #ifdef MOCKING + break; + #endif } } \ No newline at end of file diff --git a/Apps/Src/ReadCarCan.c b/Apps/Src/ReadCarCan.c index af849379a..b1e790e5a 100644 --- a/Apps/Src/ReadCarCan.c +++ b/Apps/Src/ReadCarCan.c @@ -368,7 +368,7 @@ void TaskReadCarCan(void *p_arg) { memset(hv_plus_minus_charge_msg_buffer, DISABLE_SATURATION_MSG, sizeof(hv_plus_minus_charge_msg_buffer)); - LOOP { + while(1) { UpdatePrechargeContactors(); // Sets array and motor controller PBC if // all conditions (PBC Status, Threshold, // Precharge Complete) permit @@ -376,9 +376,7 @@ void TaskReadCarCan(void *p_arg) { // BPS sent a message ErrorStatus status = CanBusRead(&data_buf, true, CARCAN); if (status != SUCCESS) { -#ifndef MOCKING continue; -#endif } switch (data_buf.id) { // Switch case based on BPS msg received @@ -430,6 +428,10 @@ void TaskReadCarCan(void *p_arg) { break; // Unhandled CAN message IDs, do nothing } } + + #ifdef MOCKING + break; + #endif } } @@ -455,7 +457,9 @@ static void handlerReadCarCanChargeDisable(void) { if (ret) { // Contactor failed to turn off; display the evac screen and // infinite loop DisplayEvac(soc, sbpv); - LOOP {} + #ifndef MOCKING + while(1); + #endif } } @@ -491,7 +495,9 @@ static void handlerReadCarCanContactorsDisable(void) { if (ret) { // Contactor failed to turn off; display the evac screen and // infinite loop DisplayEvac(soc, sbpv); - LOOP {} + #ifndef MOCKING + while(1); + #endif } } diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index 0abb4f8d3..d892c40d4 100644 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -46,7 +46,7 @@ void TaskReadTritium(void *p_arg) { // Timer doesn't seem to trigger without initial delay? Might be an RTOS bug static bool watchdog_created = false; - LOOP { + while(1) { ErrorStatus status = CanBusRead(&data_buf, true, MOTORCAN); if (status == SUCCESS) { @@ -105,6 +105,9 @@ void TaskReadTritium(void *p_arg) { SendCarCanPut(data_buf); // Forward message on CarCAN for telemetry } + #ifdef MOCKING + break; + #endif } } diff --git a/Apps/Src/SendCarCan.c b/Apps/Src/SendCarCan.c index f19d251d6..077e0c3d1 100644 --- a/Apps/Src/SendCarCan.c +++ b/Apps/Src/SendCarCan.c @@ -116,7 +116,7 @@ void TaskSendCarCan(void *p_arg) { (OS_ERR *)&err); ASSERT_OS_ERROR(err); - LOOP { + while(1) { // Check if there's something to send in the queue (either IOState or // Car state from sendTritium) OSSemPend(&car_can_sem4, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); @@ -133,6 +133,9 @@ void TaskSendCarCan(void *p_arg) { if (res) { CanBusSend(message, true, CARCAN); } + #ifdef MOCKING + break; + #endif } } @@ -168,9 +171,12 @@ static void putIOState(void) { */ static void taskPutIoState(void *p_arg) { OS_ERR err = 0; - LOOP { + while(1) { putIOState(); OSTimeDlyHMSM(0, 0, 0, IO_STATE_DLY_MS, OS_OPT_TIME_HMSM_STRICT, &err); ASSERT_OS_ERROR(err); +#ifdef MOCKING + break; +#endif } } diff --git a/Apps/Src/SendTritium.c b/Apps/Src/SendTritium.c index 3478e8ae2..8038858a6 100644 --- a/Apps/Src/SendTritium.c +++ b/Apps/Src/SendTritium.c @@ -715,7 +715,7 @@ void TaskSendTritium(void* p_arg) { }; #endif - LOOP { + while(1) { prev_state = state; state.stateHandler(); // do what the current state does @@ -752,5 +752,9 @@ void TaskSendTritium(void* p_arg) { if (err != OS_ERR_NONE) { ASSERT_OS_ERROR(err); } + + #ifdef MOCKING + break; + #endif } } diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index cdfa10d5f..5b473f70f 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -61,7 +61,10 @@ void AssertOsError(volatile OS_ERR err) { // brakelight to indicate an emergency DisplayFault(err); // Display the location and error code printf("%d\n\r", err); - LOOP {} // nonrecoverable + #ifndef MOCKING + while(1) {} // nonrecoverable + #endif + } } @@ -113,7 +116,9 @@ void ThrowTaskError(ErrorCode error_code, Callback error_callback, } if (nonrecoverable == kOptNonrecov) { // Enter an infinite while loop - LOOP {} + #ifndef MOCKING + while(1){}; + #endif } if (lock_sched == kOptLockSched) { // Only happens on recoverable errors diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index f938028f6..648632e1e 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -320,7 +320,13 @@ void UpdateDisplayClearQueue() { * @brief Loops through the display queue and sends all messages */ void TaskUpdateDisplay(void* p_arg) { - LOOP { updateDisplayPopNext(); } + while(1) { + updateDisplayPopNext(); + + #ifdef MOCKING + break; + #endif + } } /** diff --git a/Apps/Src/main.c b/Apps/Src/main.c index 7d3418d48..0fa446fd3 100644 --- a/Apps/Src/main.c +++ b/Apps/Src/main.c @@ -49,7 +49,10 @@ int main(void) { OSStart(&err); ASSERT_OS_ERROR(err); - LOOP {} + #ifndef MOCKING + while(1) {} + #endif + } void TaskInit(void *p_arg) { diff --git a/BSP/STM32F413/Makefile b/BSP/STM32F413/Makefile index 6301677fd..cf3073dd1 100644 --- a/BSP/STM32F413/Makefile +++ b/BSP/STM32F413/Makefile @@ -125,9 +125,6 @@ ifeq ($(CAR_LOOPBACK), 1) C_DEFS += -DCAR_LOOPBACK endif -# Not mocking -> LOOP = while(1) -C_DEFS += -D'LOOP=while(1)' - # compile gcc flags ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index 04e37a3e6..863b2333e 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -95,9 +95,6 @@ endif MOCKING=1 CFLAGS += -DMOCKING -# mocking -> LOOP = '' -CFLAGS += -D'LOOP=' - FILETOTEST = $(shell echo '$(TEST)' | tr '[:lower:]' '[:upper:]') #Uses shell to make TEST file uppercase to define a macro CFLAGS += -DTEST_$(FILETOTEST) #Defines a macro TEST_ to determine if we should use a mock or regular header file From 0bd0a330acd8b5aa9a1ce684ae62d4175713fbd8 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 2 Mar 2024 01:33:55 -0600 Subject: [PATCH 47/57] Ran make check and make format. --- Apps/Src/CommandLine.c | 6 +++--- Apps/Src/DebugDump.c | 6 +++--- Apps/Src/ReadCarCan.c | 18 +++++++++--------- Apps/Src/ReadTritium.c | 6 +++--- Apps/Src/SendCarCan.c | 8 ++++---- Apps/Src/SendTritium.c | 6 +++--- Apps/Src/Tasks.c | 13 ++++++------- Apps/Src/UpdateDisplay.c | 8 ++++---- Apps/Src/main.c | 7 +++---- 9 files changed, 38 insertions(+), 40 deletions(-) diff --git a/Apps/Src/CommandLine.c b/Apps/Src/CommandLine.c index fd2d92b53..ca6d18a25 100644 --- a/Apps/Src/CommandLine.c +++ b/Apps/Src/CommandLine.c @@ -106,7 +106,7 @@ void TaskCommandLine(void *p_arg) { // output welcome/help screen printf("%s", help); - while(1) { + while (1) { printf("> "); BspUartRead(kUart2, input); printf("\n\r"); @@ -122,9 +122,9 @@ void TaskCommandLine(void *p_arg) { ASSERT_OS_ERROR(err); } - #ifdef MOCKING +#ifdef MOCKING break; - #endif +#endif } // Function Implementations diff --git a/Apps/Src/DebugDump.c b/Apps/Src/DebugDump.c index 353bd5947..e4d20a034 100644 --- a/Apps/Src/DebugDump.c +++ b/Apps/Src/DebugDump.c @@ -23,7 +23,7 @@ static const char *gear_string[] = {FOREACH_GEAR(GENERATE_STRING)}; void TaskDebugDump(void *p_arg) { OS_ERR err = 0; - while(1) { + while (1) { // Get pedal information int8_t accel_pedal = PedalsRead(kAccelerator); printf("kAccelerator: %d\n\r", accel_pedal); @@ -66,8 +66,8 @@ void TaskDebugDump(void *p_arg) { ASSERT_OS_ERROR(err); } - #ifdef MOCKING +#ifdef MOCKING break; - #endif +#endif } } \ No newline at end of file diff --git a/Apps/Src/ReadCarCan.c b/Apps/Src/ReadCarCan.c index b1e790e5a..ae765d625 100644 --- a/Apps/Src/ReadCarCan.c +++ b/Apps/Src/ReadCarCan.c @@ -368,7 +368,7 @@ void TaskReadCarCan(void *p_arg) { memset(hv_plus_minus_charge_msg_buffer, DISABLE_SATURATION_MSG, sizeof(hv_plus_minus_charge_msg_buffer)); - while(1) { + while (1) { UpdatePrechargeContactors(); // Sets array and motor controller PBC if // all conditions (PBC Status, Threshold, // Precharge Complete) permit @@ -429,9 +429,9 @@ void TaskReadCarCan(void *p_arg) { } } - #ifdef MOCKING +#ifdef MOCKING break; - #endif +#endif } } @@ -457,9 +457,9 @@ static void handlerReadCarCanChargeDisable(void) { if (ret) { // Contactor failed to turn off; display the evac screen and // infinite loop DisplayEvac(soc, sbpv); - #ifndef MOCKING - while(1); - #endif +#ifndef MOCKING + while (1) {} +#endif } } @@ -495,9 +495,9 @@ static void handlerReadCarCanContactorsDisable(void) { if (ret) { // Contactor failed to turn off; display the evac screen and // infinite loop DisplayEvac(soc, sbpv); - #ifndef MOCKING - while(1); - #endif +#ifndef MOCKING + while (1) {} +#endif } } diff --git a/Apps/Src/ReadTritium.c b/Apps/Src/ReadTritium.c index d892c40d4..e83b1b3af 100644 --- a/Apps/Src/ReadTritium.c +++ b/Apps/Src/ReadTritium.c @@ -46,7 +46,7 @@ void TaskReadTritium(void *p_arg) { // Timer doesn't seem to trigger without initial delay? Might be an RTOS bug static bool watchdog_created = false; - while(1) { + while (1) { ErrorStatus status = CanBusRead(&data_buf, true, MOTORCAN); if (status == SUCCESS) { @@ -105,9 +105,9 @@ void TaskReadTritium(void *p_arg) { SendCarCanPut(data_buf); // Forward message on CarCAN for telemetry } - #ifdef MOCKING +#ifdef MOCKING break; - #endif +#endif } } diff --git a/Apps/Src/SendCarCan.c b/Apps/Src/SendCarCan.c index 077e0c3d1..6cd924503 100644 --- a/Apps/Src/SendCarCan.c +++ b/Apps/Src/SendCarCan.c @@ -116,7 +116,7 @@ void TaskSendCarCan(void *p_arg) { (OS_ERR *)&err); ASSERT_OS_ERROR(err); - while(1) { + while (1) { // Check if there's something to send in the queue (either IOState or // Car state from sendTritium) OSSemPend(&car_can_sem4, 0, OS_OPT_PEND_BLOCKING, &ticks, &err); @@ -133,9 +133,9 @@ void TaskSendCarCan(void *p_arg) { if (res) { CanBusSend(message, true, CARCAN); } - #ifdef MOCKING +#ifdef MOCKING break; - #endif +#endif } } @@ -171,7 +171,7 @@ static void putIOState(void) { */ static void taskPutIoState(void *p_arg) { OS_ERR err = 0; - while(1) { + while (1) { putIOState(); OSTimeDlyHMSM(0, 0, 0, IO_STATE_DLY_MS, OS_OPT_TIME_HMSM_STRICT, &err); ASSERT_OS_ERROR(err); diff --git a/Apps/Src/SendTritium.c b/Apps/Src/SendTritium.c index 8038858a6..414271860 100644 --- a/Apps/Src/SendTritium.c +++ b/Apps/Src/SendTritium.c @@ -715,7 +715,7 @@ void TaskSendTritium(void* p_arg) { }; #endif - while(1) { + while (1) { prev_state = state; state.stateHandler(); // do what the current state does @@ -753,8 +753,8 @@ void TaskSendTritium(void* p_arg) { ASSERT_OS_ERROR(err); } - #ifdef MOCKING +#ifdef MOCKING break; - #endif +#endif } } diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 5b473f70f..8a9fcaa2b 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -61,10 +61,9 @@ void AssertOsError(volatile OS_ERR err) { // brakelight to indicate an emergency DisplayFault(err); // Display the location and error code printf("%d\n\r", err); - #ifndef MOCKING - while(1) {} // nonrecoverable - #endif - +#ifndef MOCKING + while (1) {} // nonrecoverable +#endif } } @@ -116,9 +115,9 @@ void ThrowTaskError(ErrorCode error_code, Callback error_callback, } if (nonrecoverable == kOptNonrecov) { // Enter an infinite while loop - #ifndef MOCKING - while(1){}; - #endif +#ifndef MOCKING + while (1) {} +#endif } if (lock_sched == kOptLockSched) { // Only happens on recoverable errors diff --git a/Apps/Src/UpdateDisplay.c b/Apps/Src/UpdateDisplay.c index 648632e1e..c1b37a75e 100644 --- a/Apps/Src/UpdateDisplay.c +++ b/Apps/Src/UpdateDisplay.c @@ -320,12 +320,12 @@ void UpdateDisplayClearQueue() { * @brief Loops through the display queue and sends all messages */ void TaskUpdateDisplay(void* p_arg) { - while(1) { - updateDisplayPopNext(); + while (1) { + updateDisplayPopNext(); - #ifdef MOCKING +#ifdef MOCKING break; - #endif +#endif } } diff --git a/Apps/Src/main.c b/Apps/Src/main.c index 0fa446fd3..b6ea9c342 100644 --- a/Apps/Src/main.c +++ b/Apps/Src/main.c @@ -49,10 +49,9 @@ int main(void) { OSStart(&err); ASSERT_OS_ERROR(err); - #ifndef MOCKING - while(1) {} - #endif - +#ifndef MOCKING + while (1) {} +#endif } void TaskInit(void *p_arg) { From 1f4a1c15c4d06f89f040a65483fc68468412d002 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 2 Mar 2024 02:07:26 -0600 Subject: [PATCH 48/57] Re-removed workspace file associations. --- .vscode/LHR.code-workspace | 296 ------------------------------------- 1 file changed, 296 deletions(-) delete mode 100644 .vscode/LHR.code-workspace diff --git a/.vscode/LHR.code-workspace b/.vscode/LHR.code-workspace deleted file mode 100644 index 9e5310e01..000000000 --- a/.vscode/LHR.code-workspace +++ /dev/null @@ -1,296 +0,0 @@ -{ - "folders": [ - { - "path": "../" - }, - { - "path": "../../BPS" - } - ], - "settings": { - "liveServer.settings.multiRootWorkspaceName": "renode", - "terminal.integrated.defaultProfile.linux": "bash", - "terminal.integrated.profiles.linux": { - "bash": { - "path": "bash", - "icon": "terminal-bash", - "args": ["-i"] - }, - }, - }, - "tasks": { - "version": "2.0.0", - "tasks": [ - { - "label": "Build Controls", - "type": "process", - "command": "make", - "args": [ - "${input:target}", - "TEST=${input:test}", - "DEBUG=${input:debug}" - ], - "presentation": { - "echo": false, - "reveal": "always", - "panel": "dedicated", - "focus": true, - "clear": true, - "group": "build" - }, - "group": { - "kind": "build", - "isDefault": true - }, - "problemMatcher": [] - }, - { - "label": "Start Renode", - "type": "shell", - "command": "${workspaceFolder:Controls}/Scripts/start_renode.sh", - "presentation": { - "echo": false, - "reveal": "always", - "panel": "dedicated", - "focus": true, - "clear": true, - "group": "debug" - }, - "isBackground": true, - "problemMatcher": { - "owner": "custom", - "pattern": { - "regexp": ".", - "file": 1, - "location": 2, - "message": 3 - }, - "background": { - "activeOnStart": true, - "beginsPattern": "^.*", - "endsPattern": "^\"Renode Simulator is now active\".*" - } - } - }, - { - "label": "Open UART2 Telnet", - "type": "shell", - "command": "echo \"Controls Leaderboard UART2\"; while ! nc -z localhost ${RENODE_UART2_TELNET}; do sleep 2; echo .; done; echo Connected && nc localhost ${RENODE_UART2_TELNET}", - "presentation": { - "echo": false, - "reveal": "always", - "panel": "dedicated", - "focus": true, - "group": "debug" - }, - "isBackground": true, - "problemMatcher": { - "owner": "custom", - "pattern": { - "regexp": ".", - "file": 1, - "location": 2, - "message": 3 - }, - "background": { - "activeOnStart": true, - "beginsPattern": ".", - "endsPattern": "." - } - } - }, - { - "label": "Start OpenOCD debugger", - "type": "shell", - "command": "openocd", - "presentation": { - "echo": false, - "reveal": "always", - "panel": "dedicated", - "focus": true, - "group": "debug" - }, - "problemMatcher": [] - }, - { - "label": "Open Terminal GDB", - "type": "shell", - "command": "arm-none-eabi-gdb ${workspaceFolder:Controls}/Objects/controls-leader.elf", - "presentation": { - "echo": false, - "reveal": "always", - "panel": "dedicated", - "focus": true, - "group": "debug" - }, - "problemMatcher": [] - }, - { - "label": "Start Renode Tools", - "dependsOn": [ - "Start Renode", - "Open UART2 Telnet" - ], - "dependsOrder": "sequence", - "problemMatcher": [] - }, - { - "label": "Start Renode Tools & Terminal GDB", - "dependsOn": [ - "Start Renode Tools", - "Open Terminal GDB" - ], - "dependsOrder": "sequence", - "problemMatcher": [] - }, - { - "label": "Start Hardware Tools", - "dependsOn": [ - "Start OpenOCD debugger", - "Open Terminal GDB" - ], - "dependsOrder": "sequence", - "problemMatcher": [] - }, - { - "label": "Build Controls & Start OpenOCD", - "dependsOn": [ - "Build Controls", - "Start OpenOCD debugger" - ], - "dependsOrder": "sequence", - "problemMatcher": [] - }, - { - "label": "Build Controls & Start Hardware Tools", - "dependsOn": [ - "Build Controls", - "Start Hardware Tools" - ], - "dependsOrder": "sequence", - "problemMatcher": [] - }, - { - "label": "Build Controls & Start Renode Tools", - "dependsOn": [ - "Build Controls", - "Start Renode Tools" - ], - "dependsOrder": "sequence", - "problemMatcher": [] - }, - { - "label": "Kill Processes", - "type": "process", - "command": [ - "${command:workbench.action.tasks.terminate}", - "${command:workbench.action.acceptSelectedQuickOpenItem}" - ], - "problemMatcher": [] - } - ], - "inputs": [ - { - "id": "target", - "type": "pickString", - "description": "Target to compile.", - "options": [ - "leader", - "flash", - "clean" - ] - }, - { - "id": "test", - "type": "promptString", - "description": "Test file to compile and run.", - "default": "" - }, - { - "id": "debug", - "type": "pickString", - "description": "Debug ", - "options": [ - "1", - "0" - ], - "default": "1" - } - ], - }, - "launch": { - "version": "2.0.0", - "configurations": [ - { - "name": "Renode Build & Debug Controls", - "type": "cppdbg", - "request": "launch", - "cwd": "${workspaceFolder:Controls}", - "program": "${workspaceFolder:Controls}/Objects/controls-leader.elf", - "preLaunchTask": "Build Controls & Start Renode Tools", - "postDebugTask": "Kill Processes", - - "stopAtEntry": true, - "stopAtConnect": true, - - "customLaunchSetupCommands": [ - {"text": "target extended-remote :3333", "ignoreFailures": false}, - {"text": "file Objects/controls-leader.elf"} - ], - - "MIMode": "gdb", - "miDebuggerPath": "arm-none-eabi-gdb", - "miDebuggerServerAddress": "localhost:3333", - "miDebuggerArgs": "--cd=${workspaceFolder:Controls}", - "hardwareBreakpoints": {"require": true}, - - "targetArchitecture": "arm64", - "logging": { - "engineLogging": false, - "traceResponse": false - } - }, - { - "name": "Hardware Build & Debug Controls", - "type": "cppdbg", - "request": "launch", - "cwd": "${workspaceFolder:Controls}", - "program": "${workspaceFolder:Controls}/Objects/controls-leader.elf", - "preLaunchTask": "Build Controls & Start OpenOCD", - "postDebugTask": "Kill Processes", - - "stopAtEntry": true, - "stopAtConnect": true, - - "customLaunchSetupCommands": [ - {"text": "target extended-remote :3333", "ignoreFailures": false}, - {"text": "file Objects/controls-leader.elf"} - ], - - "MIMode": "gdb", - "miDebuggerPath": "arm-none-eabi-gdb", - "miDebuggerServerAddress": "localhost:3333", - "miDebuggerArgs": "--cd=${workspaceFolder:Controls}", - "hardwareBreakpoints": {"require": true}, - - "targetArchitecture": "arm64", - "logging": { - "engineLogging": false, - "traceResponse": false - } - } - - ] - }, - "extensions": { - "recommendations": [ - "ms-vscode.cpptools-extension-pack", // For Controls C code - "GitHub.vscode-pull-request-github", // For reviewing pull requests directly from VSCode - "eamodio.gitlens", // For better github stuff - "jirkavrba.subway-surfers", // For fun - "ms-vscode-remote.remote-wsl", // For WSL - "waderyan.gitblame" // For tracking commit history and authors within code - ] - } - -} \ No newline at end of file From 3a02e625bbd5ece823f91f3c1409133d645d3513 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 2 Mar 2024 02:58:16 -0600 Subject: [PATCH 49/57] Renamed example unit tests. --- Tests/UnitTests/Tests/Test_Contactors.c | 12 ++++++------ .../Tests/{Test_Pedals.c => Test_Pedals_Example.c} | 0 .../{Test_ReadCarCan.c => Test_ReadCarCan_Example.c} | 0 3 files changed, 6 insertions(+), 6 deletions(-) rename Tests/UnitTests/Tests/{Test_Pedals.c => Test_Pedals_Example.c} (100%) rename Tests/UnitTests/Tests/{Test_ReadCarCan.c => Test_ReadCarCan_Example.c} (100%) diff --git a/Tests/UnitTests/Tests/Test_Contactors.c b/Tests/UnitTests/Tests/Test_Contactors.c index 1003f28c2..3e6d079fa 100644 --- a/Tests/UnitTests/Tests/Test_Contactors.c +++ b/Tests/UnitTests/Tests/Test_Contactors.c @@ -19,6 +19,12 @@ DEFINE_FFF_GLOBALS; // Special function required by Unity that will run before each test void setUp(void){ + // Left blank because we don't need it +} + + +// Another required function from Unity that will run after each test +void tearDown(void){ // Reset the fakes' call and argument history between tests // This is important if you'll be using this functions in multiple tests // In our case we don't need them since we don't use functions between tests, @@ -31,12 +37,6 @@ void setUp(void){ } -// Another required function from Unity that will run after each test -void tearDown(void){ - // Left blank because we don't need it -} - - // **** Helper functions **** // static uint32_t count_instances_int(int match, int* array, uint32_t numElems) { uint32_t num = 0; diff --git a/Tests/UnitTests/Tests/Test_Pedals.c b/Tests/UnitTests/Tests/Test_Pedals_Example.c similarity index 100% rename from Tests/UnitTests/Tests/Test_Pedals.c rename to Tests/UnitTests/Tests/Test_Pedals_Example.c diff --git a/Tests/UnitTests/Tests/Test_ReadCarCan.c b/Tests/UnitTests/Tests/Test_ReadCarCan_Example.c similarity index 100% rename from Tests/UnitTests/Tests/Test_ReadCarCan.c rename to Tests/UnitTests/Tests/Test_ReadCarCan_Example.c From 7f37ccb749e2f1d9117ab8d331b6c2befdcd09b1 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 2 Mar 2024 03:06:34 -0600 Subject: [PATCH 50/57] Changed build directory for the unit tests to be the same as the general Objects folder. --- Makefile | 1 - Tests/UnitTests/Makefile | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 319e99fec..c73e3915f 100644 --- a/Makefile +++ b/Makefile @@ -72,7 +72,6 @@ help: clean: - rm -fR Tests/UnitTests/Objects rm -fR Objects rm -f *.out rm -fr Docs/doxygen diff --git a/Tests/UnitTests/Makefile b/Tests/UnitTests/Makefile index 863b2333e..fa621bce5 100644 --- a/Tests/UnitTests/Makefile +++ b/Tests/UnitTests/Makefile @@ -11,7 +11,7 @@ YELLOW=\033[0;33m NC=\033[0m # No Color # Build path -BUILD_DIR = Objects +BUILD_DIR = ../../Objects ###################################### # source @@ -46,9 +46,6 @@ SF = st-flash ####################################### # C_INCLUDES ####################################### - -#-iquote: used to stop the compiler from searching the current directory first. Another effect: -Idirs before it are only searched for "" files -# Whatever I put after iquote doesn't seem to be found, but putting it in twice works. This will break #include-next, though C_INCLUDES := \ -I- \ -I../../Tests/Inc/ \ From 1b2611acec1eed10ee4c712f42ed51ae42f9af52 Mon Sep 17 00:00:00 2001 From: Madeleine Lee <74027612+KnockbackNemo@users.noreply.github.com> Date: Sat, 2 Mar 2024 11:54:54 -0600 Subject: [PATCH 51/57] Added call to lock scheduler in AssertOsError. (#421) * Added call to lock scheduler in AssertOsError. * Ran make check. --- Apps/Src/Tasks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Apps/Src/Tasks.c b/Apps/Src/Tasks.c index 383967958..a8b701986 100644 --- a/Apps/Src/Tasks.c +++ b/Apps/Src/Tasks.c @@ -56,7 +56,9 @@ extern const PinInfo * Error assertion-related functions */ void AssertOsError(volatile OS_ERR err) { + OS_ERR err2 = 0; if (err != OS_ERR_NONE) { + OSSchedLock(&err2); EmergencyContactorOpen(); // Turn off contactors and turn on the // brakelight to indicate an emergency DisplayFault(err); // Display the location and error code From 19f0726fc9753a14f7702c2167a795c7e1ad6c83 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 2 Mar 2024 14:15:45 -0600 Subject: [PATCH 52/57] Deleted unnecessary mocks that were only defining things. --- Tests/UnitTests/Mocks/RTOS/cpu.h | 391 -------- Tests/UnitTests/Mocks/RTOS/cpu_cfg.h | 219 ----- Tests/UnitTests/Mocks/RTOS/cpu_def.h | 224 ----- Tests/UnitTests/Mocks/RTOS/lib_def.h | 1348 -------------------------- Tests/UnitTests/Mocks/RTOS/os.h | 6 +- Tests/UnitTests/Mocks/RTOS/os_cfg.h | 121 --- Tests/UnitTests/Mocks/RTOS/os_type.h | 102 -- 7 files changed, 2 insertions(+), 2409 deletions(-) delete mode 100644 Tests/UnitTests/Mocks/RTOS/cpu.h delete mode 100644 Tests/UnitTests/Mocks/RTOS/cpu_cfg.h delete mode 100644 Tests/UnitTests/Mocks/RTOS/cpu_def.h delete mode 100644 Tests/UnitTests/Mocks/RTOS/lib_def.h delete mode 100644 Tests/UnitTests/Mocks/RTOS/os_cfg.h delete mode 100644 Tests/UnitTests/Mocks/RTOS/os_type.h diff --git a/Tests/UnitTests/Mocks/RTOS/cpu.h b/Tests/UnitTests/Mocks/RTOS/cpu.h deleted file mode 100644 index 9da751aa7..000000000 --- a/Tests/UnitTests/Mocks/RTOS/cpu.h +++ /dev/null @@ -1,391 +0,0 @@ -///////////////////////////////////////////// -////// MOCK ////// -///////////////////////////////////////////// - -/* -********************************************************************************************************* -* uC/CPU -* CPU CONFIGURATION & PORT LAYER -* -* (c) Copyright 2004-2015; Micrium, Inc.; Weston, FL -* -* All rights reserved. Protected by international copyright laws. -* -* uC/CPU is provided in source form to registered licensees ONLY. It is -* illegal to distribute this source code to any third party unless you receive -* written permission by an authorized Micrium representative. Knowledge of -* the source code may NOT be used to develop a similar product. -* -* Please help us continue to provide the Embedded community with the finest -* software available. Your honesty is greatly appreciated. -* -* You can find our product's user manual, API reference, release notes and -* more information at https://doc.micrium.com. -* You can contact us at www.micrium.com. -********************************************************************************************************* -*/ - -/* -********************************************************************************************************* -* -* CPU PORT FILE -* -* ARM-Cortex-M4 -* GNU C Compiler -* -* Filename : cpu.h -* Version : V1.30.02.00 -* Programmer(s) : JJL -* BAN -********************************************************************************************************* -*/ - - -/* -********************************************************************************************************* -* MODULE -* -* Note(s) : (1) This CPU header file is protected from multiple pre-processor inclusion through use of -* the CPU module present pre-processor macro definition. -********************************************************************************************************* -*/ - -#ifndef CPU_MODULE_PRESENT /* See Note #1. */ -#define CPU_MODULE_PRESENT - - -/* -********************************************************************************************************* -* CPU INCLUDE FILES -* -* Note(s) : (1) The following CPU files are located in the following directories : -* -* (a) \\cpu_cfg.h -* -* (b) (1) \\cpu_def.h -* (2) \\\\cpu*.* -* -* where -* directory path for Your Product's Application -* directory path for common CPU-compiler software -* directory name for specific CPU -* directory name for specific compiler -* -* (2) Compiler MUST be configured to include as additional include path directories : -* -* (a) '\\' directory See Note #1a -* -* (b) (1) '\\' directory See Note #1b1 -* (2) '\\\\' directory See Note #1b2 -* -* (3) Since NO custom library modules are included, 'cpu.h' may ONLY use configurations from -* CPU configuration file 'cpu_cfg.h' that do NOT reference any custom library definitions. -* -* In other words, 'cpu.h' may use 'cpu_cfg.h' configurations that are #define'd to numeric -* constants or to NULL (i.e. NULL-valued #define's); but may NOT use configurations to -* custom library #define's (e.g. DEF_DISABLED or DEF_ENABLED). -********************************************************************************************************* -*/ - -#include -//#include /* See Note #3. */ - -#ifdef __cplusplus -extern "C" { -#endif - - -/* -********************************************************************************************************* -* CONFIGURE STANDARD DATA TYPES -* -* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications. -* -* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer -* data type of a pointer to a function which returns void & has no arguments. -* -* (2) Example function pointer usage : -* -* CPU_FNCT_VOID FnctName; -* -* FnctName(); -* -* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer -* data type of a pointer to a function which returns void & has a single void -* pointer argument. -* -* (2) Example function pointer usage : -* -* CPU_FNCT_PTR FnctName; -* void *p_obj -* -* FnctName(p_obj); -********************************************************************************************************* -*/ - -typedef void CPU_VOID; -typedef char CPU_CHAR; /* 8-bit character */ -typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */ -typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */ -typedef signed char CPU_INT08S; /* 8-bit signed integer */ -typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */ -typedef signed short CPU_INT16S; /* 16-bit signed integer */ -typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */ -typedef signed int CPU_INT32S; /* 32-bit signed integer */ -typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */ -typedef signed long long CPU_INT64S; /* 64-bit signed integer */ - -typedef float CPU_FP32; /* 32-bit floating point */ -typedef double CPU_FP64; /* 64-bit floating point */ - - -typedef volatile CPU_INT08U CPU_REG08; /* 8-bit register */ -typedef volatile CPU_INT16U CPU_REG16; /* 16-bit register */ -typedef volatile CPU_INT32U CPU_REG32; /* 32-bit register */ -typedef volatile CPU_INT64U CPU_REG64; /* 64-bit register */ - - -typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */ -typedef void (*CPU_FNCT_PTR )(void *p_obj); /* See Note #2b. */ - - -/* -********************************************************************************************************* -* CPU WORD CONFIGURATION -* -* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE, CPU_CFG_DATA_SIZE, & CPU_CFG_DATA_SIZE_MAX with CPU's &/or -* compiler's word sizes : -* -* CPU_WORD_SIZE_08 8-bit word size -* CPU_WORD_SIZE_16 16-bit word size -* CPU_WORD_SIZE_32 32-bit word size -* CPU_WORD_SIZE_64 64-bit word size -* -* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order : -* -* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant -* octet @ lowest memory address) -* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant -* octet @ lowest memory address) -********************************************************************************************************* -*/ - - /* Define CPU word sizes (see Note #1) : */ -#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size (in octets). */ -#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size (in octets). */ -#define CPU_CFG_DATA_SIZE_MAX CPU_WORD_SIZE_64 /* Defines CPU maximum word size (in octets). */ - -#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order (see Note #2). */ - - -/* -********************************************************************************************************* -* CONFIGURE CPU ADDRESS & DATA TYPES -********************************************************************************************************* -*/ - - /* CPU address type based on address bus size. */ -#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32) -typedef CPU_INT32U CPU_ADDR; -#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16) -typedef CPU_INT16U CPU_ADDR; -#else -typedef CPU_INT08U CPU_ADDR; -#endif - - /* CPU data type based on data bus size. */ -#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32) -typedef CPU_INT32U CPU_DATA; -#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) -typedef CPU_INT16U CPU_DATA; -#else -typedef CPU_INT08U CPU_DATA; -#endif - - -typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */ -typedef CPU_ADDR CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */ - - -/* -********************************************************************************************************* -* CPU STACK CONFIGURATION -* -* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : -* -* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack -* memory address after data is pushed onto the stack -* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack -* memory address after data is pushed onto the stack -* -* (2) Configure CPU_CFG_STK_ALIGN_BYTES with the highest minimum alignement required for -* cpu stacks. -* -* (a) ARM Procedure Calls Standard requires an 8 bytes stack alignment. -********************************************************************************************************* -*/ - -#define CPU_CFG_STK_GROWTH CPU_STK_GROWTH_HI_TO_LO /* Defines CPU stack growth order (see Note #1). */ - -#define CPU_CFG_STK_ALIGN_BYTES (8u) /* Defines CPU stack alignment in bytes. (see Note #2). */ - -typedef CPU_INT32U CPU_STK; /* Defines CPU stack data type. */ -typedef CPU_ADDR CPU_STK_SIZE; /* Defines CPU stack size data type. */ - - -/* -********************************************************************************************************* -* CRITICAL SECTION CONFIGURATION -* -* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : -* -* Enter/Exit critical sections by ... -* -* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts -* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack -* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable -* -* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support -* multiple levels of interrupts. However, with some CPUs/compilers, this is the only -* available method. -* -* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple -* levels of interrupts. However, this method assumes that the compiler provides C-level -* &/or assembly-level functionality for the following : -* -* ENTER CRITICAL SECTION : -* (1) Push/save interrupt status onto a local stack -* (2) Disable interrupts -* -* EXIT CRITICAL SECTION : -* (3) Pop/restore interrupt status from a local stack -* -* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple -* levels of interrupts. However, this method assumes that the compiler provides C-level -* &/or assembly-level functionality for the following : -* -* ENTER CRITICAL SECTION : -* (1) Save interrupt status into a local variable -* (2) Disable interrupts -* -* EXIT CRITICAL SECTION : -* (3) Restore interrupt status from a local variable -* -* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT -* allow inline assembly in C source files, critical section macro's MUST call an assembly -* subroutine defined in a 'cpu_a.asm' file located in the following software directory : -* -* \\\\ -* -* where -* directory path for common CPU-compiler software -* directory name for specific CPU -* directory name for specific compiler -* -* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need -* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). -* -* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, if -* used, MUST be declared following ALL other local variables. -* -* Example : -* -* void Fnct (void) -* { -* CPU_INT08U val_08; -* CPU_INT16U val_16; -* CPU_INT32U val_32; -* CPU_SR_ALLOC(); MUST be declared after ALL other local variables -* : -* : -* } -* -* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to -* completely store the CPU's/compiler's status word. -********************************************************************************************************* -*/ - /* Configure CPU critical method (see Note #1) : */ -#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL - -typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3b). */ - - /* Allocates CPU status register word (see Note #3a). */ -#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) -#define CPU_SR_ALLOC() CPU_SR cpu_sr = (CPU_SR)0 -#else -#define CPU_SR_ALLOC() -#endif - - - -#define CPU_INT_DIS() do { cpu_sr = CPU_SR_Save(); } while (0) /* Save CPU status word & disable interrupts.*/ -#define CPU_INT_EN() do { CPU_SR_Restore(cpu_sr); } while (0) /* Restore CPU status word. */ - - -#ifdef CPU_CFG_INT_DIS_MEAS_EN - /* Disable interrupts, ... */ - /* & start interrupts disabled time measurement.*/ -#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); \ - CPU_IntDisMeasStart(); } while (0) - /* Stop & measure interrupts disabled time, */ - /* ... & re-enable interrupts. */ -#define CPU_CRITICAL_EXIT() do { CPU_IntDisMeasStop(); \ - CPU_INT_EN(); } while (0) - -#else - -#define CPU_CRITICAL_ENTER() do { CPU_INT_DIS(); } while (0) /* Disable interrupts. */ -#define CPU_CRITICAL_EXIT() do { CPU_INT_EN(); } while (0) /* Re-enable interrupts. */ - -#endif - - -/* -********************************************************************************************************* -* MEMORY BARRIERS CONFIGURATION -* -* Note(s) : (1) (a) Configure memory barriers if required by the architecture. -* -* CPU_MB Full memory barrier. -* CPU_RMB Read (Loads) memory barrier. -* CPU_WMB Write (Stores) memory barrier. -* -********************************************************************************************************* -*/ - -#define CPU_MB() __asm__ __volatile__ ("dsb" : : : "memory") -#define CPU_RMB() __asm__ __volatile__ ("dsb" : : : "memory") -#define CPU_WMB() __asm__ __volatile__ ("dsb" : : : "memory") - - -/* -********************************************************************************************************* -* CPU COUNT ZEROS CONFIGURATION -* -* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits -* function(s) in : -* -* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ -* 'cpu_cfg.h' to enable assembly-optimized function(s) -* -* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ -* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise -* -* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits -* function(s) in : -* -* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ -* 'cpu_cfg.h' to enable assembly-optimized function(s) -* -* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ -* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise -********************************************************************************************************* -*/ - - /* Configure CPU count leading zeros bits ... */ -#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ - - /* Configure CPU count trailing zeros bits ... */ -#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ - -#endif \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/RTOS/cpu_cfg.h b/Tests/UnitTests/Mocks/RTOS/cpu_cfg.h deleted file mode 100644 index 174d3bccf..000000000 --- a/Tests/UnitTests/Mocks/RTOS/cpu_cfg.h +++ /dev/null @@ -1,219 +0,0 @@ -///////////////////////////////////////////// -////// MOCK ////// -///////////////////////////////////////////// - -/* -********************************************************************************************************* -* uC/CPU -* CPU CONFIGURATION & PORT LAYER -* -* (c) Copyright 2004-2015; Micrium, Inc.; Weston, FL -* -* All rights reserved. Protected by international copyright laws. -* -* uC/CPU is provided in source form to registered licensees ONLY. It is -* illegal to distribute this source code to any third party unless you receive -* written permission by an authorized Micrium representative. Knowledge of -* the source code may NOT be used to develop a similar product. -* -* Please help us continue to provide the Embedded community with the finest -* software available. Your honesty is greatly appreciated. -* -* You can find our product's user manual, API reference, release notes and -* more information at https://doc.micrium.com. -* You can contact us at www.micrium.com. -********************************************************************************************************* -*/ - -/* -********************************************************************************************************* -* -* CPU CONFIGURATION FILE -* -* TEMPLATE -* -* Filename : cpu_cfg.h -* Version : V1.30.02 -* Programmer(s) : SR -* ITJ -* JBL -********************************************************************************************************* -*/ - - -/* -********************************************************************************************************* -* MODULE -********************************************************************************************************* -*/ - -#ifndef CPU_CFG_MODULE_PRESENT -#define CPU_CFG_MODULE_PRESENT - - -/* -********************************************************************************************************* -* CPU NAME CONFIGURATION -* -* Note(s) : (1) Configure CPU_CFG_NAME_EN to enable/disable CPU host name feature : -* -* (a) CPU host name storage -* (b) CPU host name API functions -* -* (2) Configure CPU_CFG_NAME_SIZE with the desired ASCII string size of the CPU host name, -* including the terminating NULL character. -* -* See also 'cpu_core.h GLOBAL VARIABLES Note #1'. -********************************************************************************************************* -*/ - - /* Configure CPU host name feature (see Note #1) : */ -#define CPU_CFG_NAME_EN DEF_ENABLED - /* DEF_DISABLED CPU host name DISABLED */ - /* DEF_ENABLED CPU host name ENABLED */ - - /* Configure CPU host name ASCII string size ... */ -#define CPU_CFG_NAME_SIZE 16 /* ... (see Note #2). */ - - -/* -********************************************************************************************************* -* CPU TIMESTAMP CONFIGURATION -* -* Note(s) : (1) Configure CPU_CFG_TS_xx_EN to enable/disable CPU timestamp features : -* -* (a) CPU_CFG_TS_32_EN enable/disable 32-bit CPU timestamp feature -* (b) CPU_CFG_TS_64_EN enable/disable 64-bit CPU timestamp feature -* -* (2) (a) Configure CPU_CFG_TS_TMR_SIZE with the CPU timestamp timer's word size : -* -* CPU_WORD_SIZE_08 8-bit word size -* CPU_WORD_SIZE_16 16-bit word size -* CPU_WORD_SIZE_32 32-bit word size -* CPU_WORD_SIZE_64 64-bit word size -* -* (b) If the size of the CPU timestamp timer is not a binary multiple of 8-bit octets -* (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple octet word -* size SHOULD be configured (e.g. to 16-bits). However, the minimum supported word -* size for CPU timestamp timers is 8-bits. -* -* See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2a'. -********************************************************************************************************* -*/ - - /* Configure CPU timestamp features (see Note #1) : */ -#define CPU_CFG_TS_32_EN DEF_ENABLED -#define CPU_CFG_TS_64_EN DEF_DISABLED - /* DEF_DISABLED CPU timestamps DISABLED */ - /* DEF_ENABLED CPU timestamps ENABLED */ - - /* Configure CPU timestamp timer word size ... */ - /* ... (see Note #2) : */ -#define CPU_CFG_TS_TMR_SIZE CPU_WORD_SIZE_32 - - -/* -********************************************************************************************************* -* CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION -* -* Note(s) : (1) (a) Configure CPU_CFG_INT_DIS_MEAS_EN to enable/disable measuring CPU's interrupts -* disabled time : -* -* (a) Enabled, if CPU_CFG_INT_DIS_MEAS_EN #define'd in 'cpu_cfg.h' -* -* (b) Disabled, if CPU_CFG_INT_DIS_MEAS_EN NOT #define'd in 'cpu_cfg.h' -* -* See also 'cpu_core.h FUNCTION PROTOTYPES Note #1'. -* -* (b) Configure CPU_CFG_INT_DIS_MEAS_OVRHD_NBR with the number of times to measure & -* average the interrupts disabled time measurements overhead. -* -* See also 'cpu_core.c CPU_IntDisMeasInit() Note #3a'. -********************************************************************************************************* -*/ - -#if 1 /* Configure CPU interrupts disabled time ... */ -#define CPU_CFG_INT_DIS_MEAS_EN /* ... measurements feature (see Note #1a). */ -#endif - - /* Configure number of interrupts disabled overhead ... */ -#define CPU_CFG_INT_DIS_MEAS_OVRHD_NBR 1u /* ... time measurements (see Note #1b). */ - - -/* -********************************************************************************************************* -* CPU COUNT ZEROS CONFIGURATION -* -* Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits -* function(s) in : -* -* (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ -* 'cpu_cfg.h' to enable assembly-optimized function(s) -* -* (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ -* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise -* -* (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits -* function(s) in : -* -* (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/ -* 'cpu_cfg.h' to enable assembly-optimized function(s) -* -* (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/ -* 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise -********************************************************************************************************* -*/ - -#if 1 /* Configure CPU count leading zeros bits ... */ -#define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */ -#endif - -#if 0 /* Configure CPU count trailing zeros bits ... */ -#define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */ -#endif - - -/* -********************************************************************************************************* -* CPU ENDIAN TYPE OVERRIDE -* -* Note(s) : (1) Configure CPU_CFG_ENDIAN_TYPE to override the default CPU endian type defined in cpu.h. -* -* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant -* octet @ lowest memory address) -* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant -* octet @ lowest memory address) -* -* (2) Defining CPU_CFG_ENDIAN_TYPE here is only valid for supported bi-endian architectures. -* See 'cpu.h CPU WORD CONFIGURATION Note #3' for details -********************************************************************************************************* -*/ - -#if 0 -#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_BIG /* Defines CPU data word-memory order (see Note #2). */ -#endif - - -/* -********************************************************************************************************* -* CACHE MANAGEMENT -* -* Note(s) : (1) Configure CPU_CFG_CACHE_MGMT_EN to enable the cache managment API. - -* -* (2) Defining CPU_CFG_CACHE_MGMT_EN to DEF_ENABLED only enable the cache management function. -* Cache are assumed to be configured and enabled by the time CPU_init() is called. -********************************************************************************************************* -*/ - -#define CPU_CFG_CACHE_MGMT_EN DEF_DISABLED /* Defines CPU data word-memory order (see Note #1). */ - - -/* -********************************************************************************************************* -* MODULE END -********************************************************************************************************* -*/ - -#endif /* End of CPU cfg module include. */ - diff --git a/Tests/UnitTests/Mocks/RTOS/cpu_def.h b/Tests/UnitTests/Mocks/RTOS/cpu_def.h deleted file mode 100644 index 59631196f..000000000 --- a/Tests/UnitTests/Mocks/RTOS/cpu_def.h +++ /dev/null @@ -1,224 +0,0 @@ -///////////////////////////////////////////// -////// MOCK ////// -///////////////////////////////////////////// - -/* -********************************************************************************************************* -* uC/CPU -* CPU CONFIGURATION & PORT LAYER -* -* (c) Copyright 2004-2015; Micrium, Inc.; Weston, FL -* -* All rights reserved. Protected by international copyright laws. -* -* uC/CPU is provided in source form to registered licensees ONLY. It is -* illegal to distribute this source code to any third party unless you receive -* written permission by an authorized Micrium representative. Knowledge of -* the source code may NOT be used to develop a similar product. -* -* Please help us continue to provide the Embedded community with the finest -* software available. Your honesty is greatly appreciated. -* -* You can find our product's user manual, API reference, release notes and -* more information at https://doc.micrium.com. -* You can contact us at www.micrium.com. -********************************************************************************************************* -*/ - -/* -********************************************************************************************************* -* -* CPU CONFIGURATION DEFINES -* -* Filename : cpu_def.h -* Version : V1.30.02 -* Programmer(s) : ITJ -********************************************************************************************************* -*/ - - -/* -********************************************************************************************************* -* MODULE -* -* Note(s) : (1) This CPU definition header file is protected from multiple pre-processor inclusion -* through use of the CPU definition module present pre-processor macro definition. -********************************************************************************************************* -*/ - -#ifndef CPU_DEF_MODULE_PRESENT -#define CPU_DEF_MODULE_PRESENT - - -/* -********************************************************************************************************* -* CORE CPU MODULE VERSION NUMBER -* -* Note(s) : (1) (a) The core CPU module software version is denoted as follows : -* -* Vx.yy.zz -* -* where -* V denotes 'Version' label -* x denotes major software version revision number -* yy denotes minor software version revision number -* zz denotes sub-minor software version revision number -* -* (b) The software version label #define is formatted as follows : -* -* ver = x.yyzz * 100 * 100 -* -* where -* ver denotes software version number scaled as an integer value -* x.yyzz denotes software version number, where the unscaled integer -* portion denotes the major version number & the unscaled -* fractional portion denotes the (concatenated) minor -* version numbers -********************************************************************************************************* -*/ - -#define CPU_CORE_VERSION 13002u /* See Note #1. */ - - -/* -********************************************************************************************************* -* CPU WORD CONFIGURATION -* -* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE & CPU_CFG_DATA_SIZE in 'cpu.h' with CPU's word sizes : -* -* CPU_WORD_SIZE_08 8-bit word size -* CPU_WORD_SIZE_16 16-bit word size -* CPU_WORD_SIZE_32 32-bit word size -* CPU_WORD_SIZE_64 64-bit word size -* -* (2) Configure CPU_CFG_ENDIAN_TYPE in 'cpu.h' with CPU's data-word-memory order : -* -* (a) CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant -* octet @ lowest memory address) -* (b) CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant -* octet @ lowest memory address) -********************************************************************************************************* -*/ - - /* ---------------------- CPU WORD SIZE ----------------------- */ -#define CPU_WORD_SIZE_08 1u /* 8-bit word size (in octets). */ -#define CPU_WORD_SIZE_16 2u /* 16-bit word size (in octets). */ -#define CPU_WORD_SIZE_32 4u /* 32-bit word size (in octets). */ -#define CPU_WORD_SIZE_64 8u /* 64-bit word size (in octets). */ - - - /* ------------------ CPU WORD-ENDIAN ORDER ------------------- */ -#define CPU_ENDIAN_TYPE_NONE 0u -#define CPU_ENDIAN_TYPE_BIG 1u /* Big- endian word order (see Note #1a). */ -#define CPU_ENDIAN_TYPE_LITTLE 2u /* Little-endian word order (see Note #1b). */ - - -/* -********************************************************************************************************* -* CPU STACK CONFIGURATION -* -* Note(s) : (1) Configure CPU_CFG_STK_GROWTH in 'cpu.h' with CPU's stack growth order : -* -* (a) CPU_STK_GROWTH_LO_TO_HI CPU stack pointer increments to the next higher stack -* memory address after data is pushed onto the stack -* (b) CPU_STK_GROWTH_HI_TO_LO CPU stack pointer decrements to the next lower stack -* memory address after data is pushed onto the stack -********************************************************************************************************* -*/ - - /* ------------------ CPU STACK GROWTH ORDER ------------------ */ -#define CPU_STK_GROWTH_NONE 0u -#define CPU_STK_GROWTH_LO_TO_HI 1u /* CPU stk incs towards higher mem addrs (see Note #1a). */ -#define CPU_STK_GROWTH_HI_TO_LO 2u /* CPU stk decs towards lower mem addrs (see Note #1b). */ - - -/* -********************************************************************************************************* -* CRITICAL SECTION CONFIGURATION -* -* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method : -* -* Enter/Exit critical sections by ... -* -* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts -* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack -* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable -* -* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support -* multiple levels of interrupts. However, with some CPUs/compilers, this is the only -* available method. -* -* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it supports multiple -* levels of interrupts. However, this method assumes that the compiler provides C-level -* &/or assembly-level functionality for the following : -* -* ENTER CRITICAL SECTION : -* (1) Push/save interrupt status onto a local stack -* (2) Disable interrupts -* -* EXIT CRITICAL SECTION : -* (3) Pop/restore interrupt status from a local stack -* -* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it supports multiple -* levels of interrupts. However, this method assumes that the compiler provides C-level -* &/or assembly-level functionality for the following : -* -* ENTER CRITICAL SECTION : -* (1) Save interrupt status into a local variable -* (2) Disable interrupts -* -* EXIT CRITICAL SECTION : -* (3) Restore interrupt status from a local variable -* -* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT -* allow inline assembly in C source files, critical section macro's MUST call an assembly -* subroutine defined in a 'cpu_a.asm' file located in the following software directory : -* -* \\\\ -* -* where -* directory path for common CPU-compiler software -* directory name for specific CPU -* directory name for specific compiler -* -* (3) (a) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need -* to be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). -* -* (1) 'cpu_sr' local variable SHOULD be declared via the CPU_SR_ALLOC() macro which, -* if used, MUST be declared following ALL other local variables (see any 'cpu.h -* CRITICAL SECTION CONFIGURATION Note #3a1'). -* -* Example : -* -* void Fnct (void) -* { -* CPU_INT08U val_08; -* CPU_INT16U val_16; -* CPU_INT32U val_32; -* CPU_SR_ALLOC(); MUST be declared after ALL other local variables -* : -* : -* } -* -* (b) Configure 'CPU_SR' data type with the appropriate-sized CPU data type large enough to -* completely store the CPU's/compiler's status word. -********************************************************************************************************* -*/ - - /* --------------- CPU CRITICAL SECTION METHODS --------------- */ -#define CPU_CRITICAL_METHOD_NONE 0u /* */ -#define CPU_CRITICAL_METHOD_INT_DIS_EN 1u /* DIS/EN ints (see Note #1a). */ -#define CPU_CRITICAL_METHOD_STATUS_STK 2u /* Push/Pop int status onto stk (see Note #1b). */ -#define CPU_CRITICAL_METHOD_STATUS_LOCAL 3u /* Save/Restore int status to local var (see Note #1c). */ - - -/* -********************************************************************************************************* -* MODULE END -* -* Note(s) : (1) See 'cpu_def.h MODULE'. -********************************************************************************************************* -*/ - -#endif /* End of CPU def module include. */ - diff --git a/Tests/UnitTests/Mocks/RTOS/lib_def.h b/Tests/UnitTests/Mocks/RTOS/lib_def.h deleted file mode 100644 index 0fea0ce12..000000000 --- a/Tests/UnitTests/Mocks/RTOS/lib_def.h +++ /dev/null @@ -1,1348 +0,0 @@ -///////////////////////////////////////////// -////// MOCK ////// -///////////////////////////////////////////// - -/* -********************************************************************************************************* -* uC/LIB -* CUSTOM LIBRARY MODULES -* -* (c) Copyright 2004-2014; Micrium, Inc.; Weston, FL -* -* All rights reserved. Protected by international copyright laws. -* -* uC/LIB is provided in source form to registered licensees ONLY. It is -* illegal to distribute this source code to any third party unless you receive -* written permission by an authorized Micrium representative. Knowledge of -* the source code may NOT be used to develop a similar product. -* -* Please help us continue to provide the Embedded community with the finest -* software available. Your honesty is greatly appreciated. -* -* You can find our product's user manual, API reference, release notes and -* more information at: https://doc.micrium.com -* -* You can contact us at: http://www.micrium.com -********************************************************************************************************* -*/ - -/* -********************************************************************************************************* -* -* CORE CUSTOM LIBRARY MODULE -* -* Filename : lib_def.h -* Version : V1.38.01 -* Programmer(s) : ITJ -* FBJ -* JFD -********************************************************************************************************* -* Note(s) : (1) Assumes the following versions (or more recent) of software modules are included in -* the project build : -* -* (a) uC/CPU V1.29.00 -* -* -* (2) NO compiler-supplied standard library functions are used in library or product software. -* -* (a) ALL standard library functions are implemented in the custom library modules : -* -* (1) \\lib_*.* -* -* (2) \\Ports\\\lib*_a.* -* -* where -* directory path for custom library software -* directory name for specific processor (CPU) -* directory name for specific compiler -* -* (b) Product-specific library functions are implemented in individual products. -********************************************************************************************************* -*/ - - -/* -********************************************************************************************************* -* MODULE -* -* Note(s) : (1) This library definition header file is protected from multiple pre-processor inclusion -* through use of the library definition module present pre-processor macro definition. -********************************************************************************************************* -*/ - -#ifndef LIB_DEF_MODULE_PRESENT -#define LIB_DEF_MODULE_PRESENT - - -/* -********************************************************************************************************* -* CUSTOM LIBRARY MODULE VERSION NUMBER -* -* Note(s) : (1) (a) The custom library module software version is denoted as follows : -* -* Vx.yy.zz -* -* where -* V denotes 'Version' label -* x denotes major software version revision number -* yy denotes minor software version revision number -* zz denotes sub-minor software version revision number -* -* (b) The software version label #define is formatted as follows : -* -* ver = x.yyzz * 100 * 100 -* -* where -* ver denotes software version number scaled as an integer value -* x.yyzz denotes software version number, where the unscaled integer -* portion denotes the major version number & the unscaled -* fractional portion denotes the (concatenated) minor -* version numbers -********************************************************************************************************* -*/ - -#define LIB_VERSION 13801u /* See Note #1. */ - - -/* -********************************************************************************************************* -* INCLUDE FILES -* -* Note(s) : (1) The custom library software files are located in the following directories : -* -* (a) \\lib_*.* -* -* where -* directory path for custom library software -* -* (2) CPU-configuration software files are located in the following directories : -* -* (a) \\cpu_*.* -* (b) \\\\cpu*.* -* -* where -* directory path for common CPU-compiler software -* directory name for specific processor (CPU) -* directory name for specific compiler -* -* (3) Compiler MUST be configured to include as additional include path directories : -* -* (a) '\\' directory See Note #1a -* -* (b) (1) '\\' directory See Note #2a -* (2) '\\\\' directory See Note #2b -********************************************************************************************************* -*/ - -//#include -#include - - -/* -********************************************************************************************************* -* STANDARD DEFINES -********************************************************************************************************* -*/ - -#define DEF_NULL 0 - - - /* ----------------- BOOLEAN DEFINES ------------------ */ -#define DEF_FALSE 0u -#define DEF_TRUE 1u - -#define DEF_NO 0u -#define DEF_YES 1u - -#define DEF_DISABLED 0u -#define DEF_ENABLED 1u - -#define DEF_INACTIVE 0u -#define DEF_ACTIVE 1u - -#define DEF_INVALID 0u -#define DEF_VALID 1u - -#define DEF_OFF 0u -#define DEF_ON 1u - -#define DEF_CLR 0u -#define DEF_SET 1u - -#define DEF_FAIL 0u -#define DEF_OK 1u - - - /* ------------------- BIT DEFINES -------------------- */ -#define DEF_BIT_NONE 0x00u - -#define DEF_BIT_00 0x01u -#define DEF_BIT_01 0x02u -#define DEF_BIT_02 0x04u -#define DEF_BIT_03 0x08u -#define DEF_BIT_04 0x10u -#define DEF_BIT_05 0x20u -#define DEF_BIT_06 0x40u -#define DEF_BIT_07 0x80u - -#define DEF_BIT_08 0x0100u -#define DEF_BIT_09 0x0200u -#define DEF_BIT_10 0x0400u -#define DEF_BIT_11 0x0800u -#define DEF_BIT_12 0x1000u -#define DEF_BIT_13 0x2000u -#define DEF_BIT_14 0x4000u -#define DEF_BIT_15 0x8000u - -#define DEF_BIT_16 0x00010000u -#define DEF_BIT_17 0x00020000u -#define DEF_BIT_18 0x00040000u -#define DEF_BIT_19 0x00080000u -#define DEF_BIT_20 0x00100000u -#define DEF_BIT_21 0x00200000u -#define DEF_BIT_22 0x00400000u -#define DEF_BIT_23 0x00800000u - -#define DEF_BIT_24 0x01000000u -#define DEF_BIT_25 0x02000000u -#define DEF_BIT_26 0x04000000u -#define DEF_BIT_27 0x08000000u -#define DEF_BIT_28 0x10000000u -#define DEF_BIT_29 0x20000000u -#define DEF_BIT_30 0x40000000u -#define DEF_BIT_31 0x80000000u -#define DEF_BIT_32 0x0000000100000000u -#define DEF_BIT_33 0x0000000200000000u -#define DEF_BIT_34 0x0000000400000000u -#define DEF_BIT_35 0x0000000800000000u -#define DEF_BIT_36 0x0000001000000000u -#define DEF_BIT_37 0x0000002000000000u -#define DEF_BIT_38 0x0000004000000000u -#define DEF_BIT_39 0x0000008000000000u - -#define DEF_BIT_40 0x0000010000000000u -#define DEF_BIT_41 0x0000020000000000u -#define DEF_BIT_42 0x0000040000000000u -#define DEF_BIT_43 0x0000080000000000u -#define DEF_BIT_44 0x0000100000000000u -#define DEF_BIT_45 0x0000200000000000u -#define DEF_BIT_46 0x0000400000000000u -#define DEF_BIT_47 0x0000800000000000u - -#define DEF_BIT_48 0x0001000000000000u -#define DEF_BIT_49 0x0002000000000000u -#define DEF_BIT_50 0x0004000000000000u -#define DEF_BIT_51 0x0008000000000000u -#define DEF_BIT_52 0x0010000000000000u -#define DEF_BIT_53 0x0020000000000000u -#define DEF_BIT_54 0x0040000000000000u -#define DEF_BIT_55 0x0080000000000000u - -#define DEF_BIT_56 0x0100000000000000u -#define DEF_BIT_57 0x0200000000000000u -#define DEF_BIT_58 0x0400000000000000u -#define DEF_BIT_59 0x0800000000000000u -#define DEF_BIT_60 0x1000000000000000u -#define DEF_BIT_61 0x2000000000000000u -#define DEF_BIT_62 0x4000000000000000u -#define DEF_BIT_63 0x8000000000000000u - - - /* ------------------ ALIGN DEFINES ------------------- */ -#define DEF_ALIGN_MAX_NBR_OCTETS 4096u - - - /* ------------------ OCTET DEFINES ------------------- */ -#define DEF_OCTET_NBR_BITS 8u -#define DEF_OCTET_MASK 0xFFu - -#define DEF_OCTET_TO_BIT_NBR_BITS 3u -#define DEF_OCTET_TO_BIT_SHIFT DEF_OCTET_TO_BIT_NBR_BITS -#define DEF_OCTET_TO_BIT_MASK 0x07u - - -#define DEF_NIBBLE_NBR_BITS 4u -#define DEF_NIBBLE_MASK 0x0Fu - - - /* --------------- NUMBER BASE DEFINES ---------------- */ -#define DEF_NBR_BASE_BIN 2u -#define DEF_NBR_BASE_OCT 8u -#define DEF_NBR_BASE_DEC 10u -#define DEF_NBR_BASE_HEX 16u - - - /* ----------------- INTEGER DEFINES ------------------ */ -#define DEF_INT_08_NBR_BITS 8u -#define DEF_INT_08_MASK 0xFFu - -#define DEF_INT_08U_MIN_VAL 0u -#define DEF_INT_08U_MAX_VAL 255u - -#define DEF_INT_08S_MIN_VAL_ONES_CPL (-127) -#define DEF_INT_08S_MAX_VAL_ONES_CPL 127 - -#define DEF_INT_08S_MIN_VAL (DEF_INT_08S_MIN_VAL_ONES_CPL - 1) -#define DEF_INT_08S_MAX_VAL DEF_INT_08S_MAX_VAL_ONES_CPL - -#define DEF_INT_08U_NBR_DIG_MIN 1u -#define DEF_INT_08U_NBR_DIG_MAX 3u - -#define DEF_INT_08S_NBR_DIG_MIN 3u -#define DEF_INT_08S_NBR_DIG_MAX 3u - - - -#define DEF_INT_16_NBR_BITS 16u -#define DEF_INT_16_MASK 0xFFFFu - -#define DEF_INT_16U_MIN_VAL 0u -#define DEF_INT_16U_MAX_VAL 65535u - -#define DEF_INT_16S_MIN_VAL_ONES_CPL (-32767) -#define DEF_INT_16S_MAX_VAL_ONES_CPL 32767 - -#define DEF_INT_16S_MIN_VAL (DEF_INT_16S_MIN_VAL_ONES_CPL - 1) -#define DEF_INT_16S_MAX_VAL DEF_INT_16S_MAX_VAL_ONES_CPL - -#define DEF_INT_16U_NBR_DIG_MIN 1u -#define DEF_INT_16U_NBR_DIG_MAX 5u - -#define DEF_INT_16S_NBR_DIG_MIN 5u -#define DEF_INT_16S_NBR_DIG_MAX 5u - - - -#define DEF_INT_32_NBR_BITS 32u -#define DEF_INT_32_MASK 0xFFFFFFFFu - -#define DEF_INT_32U_MIN_VAL 0u -#define DEF_INT_32U_MAX_VAL 4294967295u - -#define DEF_INT_32S_MIN_VAL_ONES_CPL (-2147483647) -#define DEF_INT_32S_MAX_VAL_ONES_CPL 2147483647 - -#define DEF_INT_32S_MIN_VAL (DEF_INT_32S_MIN_VAL_ONES_CPL - 1) -#define DEF_INT_32S_MAX_VAL DEF_INT_32S_MAX_VAL_ONES_CPL - -#define DEF_INT_32U_NBR_DIG_MIN 1u -#define DEF_INT_32U_NBR_DIG_MAX 10u - -#define DEF_INT_32S_NBR_DIG_MIN 10u -#define DEF_INT_32S_NBR_DIG_MAX 10u - - - -#define DEF_INT_64_NBR_BITS 64u -#define DEF_INT_64_MASK 0xFFFFFFFFFFFFFFFFu - -#define DEF_INT_64U_MIN_VAL 0u -#define DEF_INT_64U_MAX_VAL 18446744073709551615u - -#define DEF_INT_64S_MIN_VAL_ONES_CPL (-9223372036854775807) -#define DEF_INT_64S_MAX_VAL_ONES_CPL 9223372036854775807 - -#define DEF_INT_64S_MIN_VAL (DEF_INT_64S_MIN_VAL_ONES_CPL - 1) -#define DEF_INT_64S_MAX_VAL DEF_INT_64S_MAX_VAL_ONES_CPL - -#define DEF_INT_64U_NBR_DIG_MIN 1u -#define DEF_INT_64U_NBR_DIG_MAX 20u - -#define DEF_INT_64S_NBR_DIG_MIN 19u -#define DEF_INT_64S_NBR_DIG_MAX 19u - - - /* --------------- CPU INTEGER DEFINES ---------------- */ -#define DEF_INT_CPU_NBR_BITS (CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS) -#define DEF_INT_CPU_NBR_BITS_MAX (CPU_CFG_DATA_SIZE_MAX * DEF_OCTET_NBR_BITS) - - - -#if (DEF_INT_CPU_NBR_BITS == DEF_INT_08_NBR_BITS) - - -#define DEF_INT_CPU_MASK DEF_INT_08_MASK - -#define DEF_INT_CPU_U_MIN_VAL DEF_INT_08U_MIN_VAL -#define DEF_INT_CPU_U_MAX_VAL DEF_INT_08U_MAX_VAL - -#define DEF_INT_CPU_S_MIN_VAL DEF_INT_08S_MIN_VAL -#define DEF_INT_CPU_S_MAX_VAL DEF_INT_08S_MAX_VAL - -#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_08S_MIN_VAL_ONES_CPL -#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_08S_MAX_VAL_ONES_CPL - - - -#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_16_NBR_BITS) - - -#define DEF_INT_CPU_MASK DEF_INT_16_MASK - -#define DEF_INT_CPU_U_MIN_VAL DEF_INT_16U_MIN_VAL -#define DEF_INT_CPU_U_MAX_VAL DEF_INT_16U_MAX_VAL - -#define DEF_INT_CPU_S_MIN_VAL DEF_INT_16S_MIN_VAL -#define DEF_INT_CPU_S_MAX_VAL DEF_INT_16S_MAX_VAL - -#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_16S_MIN_VAL_ONES_CPL -#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_16S_MAX_VAL_ONES_CPL - - - -#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_32_NBR_BITS) - - -#define DEF_INT_CPU_MASK DEF_INT_32_MASK - -#define DEF_INT_CPU_U_MIN_VAL DEF_INT_32U_MIN_VAL -#define DEF_INT_CPU_U_MAX_VAL DEF_INT_32U_MAX_VAL - -#define DEF_INT_CPU_S_MIN_VAL DEF_INT_32S_MIN_VAL -#define DEF_INT_CPU_S_MAX_VAL DEF_INT_32S_MAX_VAL - -#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_32S_MIN_VAL_ONES_CPL -#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_32S_MAX_VAL_ONES_CPL - - - -#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_64_NBR_BITS) - - -#define DEF_INT_CPU_MASK DEF_INT_64_MASK - -#define DEF_INT_CPU_U_MIN_VAL DEF_INT_64U_MIN_VAL -#define DEF_INT_CPU_U_MAX_VAL DEF_INT_64U_MAX_VAL - -#define DEF_INT_CPU_S_MIN_VAL DEF_INT_64S_MIN_VAL -#define DEF_INT_CPU_S_MAX_VAL DEF_INT_64S_MAX_VAL - -#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_64S_MIN_VAL_ONES_CPL -#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_64S_MAX_VAL_ONES_CPL - - - -#else - -// #error "CPU_CFG_DATA_SIZE illegally #defined in 'cpu.h' " -// #error " [See 'cpu.h CONFIGURATION ERRORS']" - -#endif - - - /* ------------------- TIME DEFINES ------------------- */ -#define DEF_TIME_NBR_DAY_PER_WK 7u -#define DEF_TIME_NBR_DAY_PER_YR 365u -#define DEF_TIME_NBR_DAY_PER_YR_LEAP 366u - -#define DEF_TIME_NBR_HR_PER_DAY 24u -#define DEF_TIME_NBR_HR_PER_WK (DEF_TIME_NBR_HR_PER_DAY * DEF_TIME_NBR_DAY_PER_WK ) -#define DEF_TIME_NBR_HR_PER_YR (DEF_TIME_NBR_HR_PER_DAY * DEF_TIME_NBR_DAY_PER_YR ) -#define DEF_TIME_NBR_HR_PER_YR_LEAP (DEF_TIME_NBR_HR_PER_DAY * DEF_TIME_NBR_DAY_PER_YR_LEAP) - -#define DEF_TIME_NBR_MIN_PER_HR 60u -#define DEF_TIME_NBR_MIN_PER_DAY (DEF_TIME_NBR_MIN_PER_HR * DEF_TIME_NBR_HR_PER_DAY ) -#define DEF_TIME_NBR_MIN_PER_WK (DEF_TIME_NBR_MIN_PER_DAY * DEF_TIME_NBR_DAY_PER_WK ) -#define DEF_TIME_NBR_MIN_PER_YR (DEF_TIME_NBR_MIN_PER_DAY * DEF_TIME_NBR_DAY_PER_YR ) -#define DEF_TIME_NBR_MIN_PER_YR_LEAP (DEF_TIME_NBR_MIN_PER_DAY * DEF_TIME_NBR_DAY_PER_YR_LEAP) - -#define DEF_TIME_NBR_SEC_PER_MIN 60u -#define DEF_TIME_NBR_SEC_PER_HR (DEF_TIME_NBR_SEC_PER_MIN * DEF_TIME_NBR_MIN_PER_HR ) -#define DEF_TIME_NBR_SEC_PER_DAY (DEF_TIME_NBR_SEC_PER_HR * DEF_TIME_NBR_HR_PER_DAY ) -#define DEF_TIME_NBR_SEC_PER_WK (DEF_TIME_NBR_SEC_PER_DAY * DEF_TIME_NBR_DAY_PER_WK ) -#define DEF_TIME_NBR_SEC_PER_YR (DEF_TIME_NBR_SEC_PER_DAY * DEF_TIME_NBR_DAY_PER_YR ) -#define DEF_TIME_NBR_SEC_PER_YR_LEAP (DEF_TIME_NBR_SEC_PER_DAY * DEF_TIME_NBR_DAY_PER_YR_LEAP) - -#define DEF_TIME_NBR_mS_PER_SEC 1000u -#define DEF_TIME_NBR_uS_PER_SEC 1000000u -#define DEF_TIME_NBR_nS_PER_SEC 1000000000u - - -/* -********************************************************************************************************* -* ERROR CODES -* -* Note(s) : (1) All library error codes are #define'd in 'lib_def.h'; -********************************************************************************************************* -*/ - -typedef enum lib_err { - - LIB_ERR_NONE = 0u, - - LIB_MEM_ERR_NONE = 10000u, - LIB_MEM_ERR_NULL_PTR = 10001u, /* Ptr arg(s) passed NULL ptr(s). */ - - LIB_MEM_ERR_INVALID_MEM_SIZE = 10100u, /* Invalid mem size. */ - LIB_MEM_ERR_INVALID_MEM_ALIGN = 10101u, /* Invalid mem align. */ - LIB_MEM_ERR_INVALID_SEG_SIZE = 10110u, /* Invalid mem seg size. */ - LIB_MEM_ERR_INVALID_SEG_OVERLAP = 10111u, /* Invalid mem seg overlaps other mem seg(s). */ - LIB_MEM_ERR_INVALID_SEG_EXISTS = 10112u, /* Invalid mem seg already exists. */ - LIB_MEM_ERR_INVALID_POOL = 10120u, /* Invalid mem pool. */ - LIB_MEM_ERR_INVALID_BLK_NBR = 10130u, /* Invalid mem pool blk nbr. */ - LIB_MEM_ERR_INVALID_BLK_SIZE = 10131u, /* Invalid mem pool blk size. */ - LIB_MEM_ERR_INVALID_BLK_ALIGN = 10132u, /* Invalid mem pool blk align. */ - LIB_MEM_ERR_INVALID_BLK_IX = 10133u, /* Invalid mem pool ix. */ - LIB_MEM_ERR_INVALID_BLK_ADDR = 10135u, /* Invalid mem pool blk addr. */ - LIB_MEM_ERR_INVALID_BLK_ADDR_IN_POOL = 10136u, /* Mem pool blk addr already in mem pool. */ - - LIB_MEM_ERR_SEG_EMPTY = 10200u, /* Mem seg empty; i.e. NO avail mem in seg. */ - LIB_MEM_ERR_SEG_OVF = 10201u, /* Mem seg ovf; i.e. req'd mem ovfs rem mem in seg. */ - LIB_MEM_ERR_POOL_FULL = 10205u, /* Mem pool full; i.e. all mem blks avail in mem pool. */ - LIB_MEM_ERR_POOL_EMPTY = 10206u, /* Mem pool empty; i.e. NO mem blks avail in mem pool. */ - LIB_MEM_ERR_POOL_UNLIMITED = 10207u, /* Mem pool is unlimited. */ - - LIB_MEM_ERR_HEAP_EMPTY = 10210u, /* Heap seg empty; i.e. NO avail mem in heap. */ - LIB_MEM_ERR_HEAP_OVF = 10211u, /* Heap seg ovf; i.e. req'd mem ovfs rem mem in heap. */ - LIB_MEM_ERR_HEAP_NOT_FOUND = 10215u /* Heap seg NOT found. */ - -} LIB_ERR; - - -/* -********************************************************************************************************* -* DATA TYPES -********************************************************************************************************* -*/ - - -/* -********************************************************************************************************* -* GLOBAL VARIABLES -********************************************************************************************************* -*/ - - -/* -********************************************************************************************************* -* TRACING -********************************************************************************************************* -*/ - - /* Trace level, default to TRACE_LEVEL_OFF. */ -#ifndef TRACE_LEVEL_OFF -#define TRACE_LEVEL_OFF 0u -#endif - -#ifndef TRACE_LEVEL_INFO -#define TRACE_LEVEL_INFO 1u -#endif - -#ifndef TRACE_LEVEL_DBG -#define TRACE_LEVEL_DBG 2u -#endif - -#ifndef TRACE_LEVEL_LOG -#define TRACE_LEVEL_LOG 3u -#endif - - -/* -********************************************************************************************************* -* BIT MACRO'S -********************************************************************************************************* -*/ - -/* -********************************************************************************************************* -* DEF_BIT() -* -* Description : Create bit mask with single, specified bit set. -* -* Argument(s) : bit Bit number of bit to set. -* -* Return(s) : Bit mask with single, specified bit set. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'bit' SHOULD be a non-negative integer. -* -* (2) (a) 'bit' values that overflow the target CPU &/or compiler environment (e.g. negative -* or greater-than-CPU-data-size values) MAY generate compiler warnings &/or errors. -********************************************************************************************************* -*/ - -#define DEF_BIT(bit) (1u << (bit)) - - -/* -********************************************************************************************************* -* DEF_BITxx() -* -* Description : Create bit mask of specified bit size with single, specified bit set. -* -* Argument(s) : bit Bit number of bit to set. -* -* Return(s) : Bit mask with single, specified bit set. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'bit' SHOULD be a non-negative integer. -* -* (2) (a) 'bit' values that overflow the target CPU &/or compiler environment (e.g. negative -* or greater-than-CPU-data-size values) MAY generate compiler warnings &/or errors. -* -* (b) To avoid overflowing any target CPU &/or compiler's integer data type, unsigned -* bit constant '1' is cast to specified integer data type size. -* -* (3) Ideally, DEF_BITxx() macro's should be named DEF_BIT_xx(); however, these names already -* previously-released for bit constant #define's (see 'STANDARD DEFINES BIT DEFINES'). -********************************************************************************************************* -*/ - -#define DEF_BIT08(bit) ((CPU_INT08U)((CPU_INT08U)1u << (bit))) - -#define DEF_BIT16(bit) ((CPU_INT16U)((CPU_INT16U)1u << (bit))) - -#define DEF_BIT32(bit) ((CPU_INT32U)((CPU_INT32U)1u << (bit))) - -#define DEF_BIT64(bit) ((CPU_INT64U)((CPU_INT64U)1u << (bit))) - - -/* -********************************************************************************************************* -* DEF_BIT_MASK() -* -* Description : Shift a bit mask. -* -* Argument(s) : bit_mask Bit mask to shift. -* -* bit_shift Number of bit positions to left-shift bit mask. -* -* Return(s) : Shifted bit mask. -* -* Caller(s) : Application. -* -* Note(s) : (1) (a) 'bit_mask' SHOULD be an unsigned integer. -* -* (b) 'bit_shift' SHOULD be a non-negative integer. -* -* (2) 'bit_shift' values that overflow the target CPU &/or compiler environment (e.g. negative -* or greater-than-CPU-data-size values) MAY generate compiler warnings &/or errors. -********************************************************************************************************* -*/ - -#define DEF_BIT_MASK(bit_mask, bit_shift) ((bit_mask) << (bit_shift)) - - -/* -********************************************************************************************************* -* DEF_BIT_MASK_xx() -* -* Description : Shift a bit mask of specified bit size. -* -* Argument(s) : bit_mask Bit mask to shift. -* -* bit_shift Number of bit positions to left-shift bit mask. -* -* Return(s) : Shifted bit mask. -* -* Caller(s) : Application. -* -* Note(s) : (1) (a) 'bit_mask' SHOULD be an unsigned integer. -* -* (b) 'bit_shift' SHOULD be a non-negative integer. -* -* (2) 'bit_shift' values that overflow the target CPU &/or compiler environment (e.g. negative -* or greater-than-CPU-data-size values) MAY generate compiler warnings &/or errors. -********************************************************************************************************* -*/ - -#define DEF_BIT_MASK_08(bit_mask, bit_shift) ((CPU_INT08U)((CPU_INT08U)(bit_mask) << (bit_shift))) - -#define DEF_BIT_MASK_16(bit_mask, bit_shift) ((CPU_INT16U)((CPU_INT16U)(bit_mask) << (bit_shift))) - -#define DEF_BIT_MASK_32(bit_mask, bit_shift) ((CPU_INT32U)((CPU_INT32U)(bit_mask) << (bit_shift))) - -#define DEF_BIT_MASK_64(bit_mask, bit_shift) ((CPU_INT64U)((CPU_INT64U)(bit_mask) << (bit_shift))) - - -/* -********************************************************************************************************* -* DEF_BIT_FIELD() -* -* Description : Create & shift a contiguous bit field. -* -* Argument(s) : bit_field Number of contiguous bits to set in the bit field. -* -* bit_shift Number of bit positions to left-shift bit field. -* -* Return(s) : Shifted bit field. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'bit_field' & 'bit_shift' SHOULD be non-negative integers. -* -* (2) (a) 'bit_field'/'bit_shift' values that overflow the target CPU &/or compiler -* environment (e.g. negative or greater-than-CPU-data-size values) MAY generate -* compiler warnings &/or errors. -* -* (b) To avoid overflowing any target CPU &/or compiler's integer data type, unsigned -* bit constant '1' is suffixed with 'L'ong integer modifier. -* -* This may still be insufficient for CPUs &/or compilers that support 'long long' -* integer data types, in which case 'LL' integer modifier should be suffixed. -* However, since almost all 16- & 32-bit CPUs & compilers support 'long' integer -* data types but many may NOT support 'long long' integer data types, only 'long' -* integer data types & modifiers are supported. -* -* See also 'DEF_BIT_FIELD_xx() Note #1b'. -********************************************************************************************************* -*/ - -#define DEF_BIT_FIELD(bit_field, bit_shift) ((((bit_field) >= DEF_INT_CPU_NBR_BITS) ? (DEF_INT_CPU_U_MAX_VAL) \ - : (DEF_BIT(bit_field) - 1uL)) \ - << (bit_shift)) - -/* -********************************************************************************************************* -* DEF_BIT_FIELD_xx() -* -* Description : Create & shift a contiguous bit field of specified bit size. -* -* Argument(s) : bit_field Number of contiguous bits to set in the bit field. -* -* bit_shift Number of bit positions to left-shift bit field. -* -* Return(s) : Shifted bit field. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'bit_field' & 'bit_shift' SHOULD be non-negative integers. -* -* (2) (a) 'bit_field'/'bit_shift' values that overflow the target CPU &/or compiler -* environment (e.g. negative or greater-than-CPU-data-size values) MAY generate -* compiler warnings &/or errors. -* -* (b) To avoid overflowing any target CPU &/or compiler's integer data type, unsigned -* bit constant '1' is cast to specified integer data type size. -********************************************************************************************************* -*/ - -#define DEF_BIT_FIELD_08(bit_field, bit_shift) ((CPU_INT08U)((((CPU_INT08U)(bit_field) >= (CPU_INT08U)DEF_INT_08_NBR_BITS) ? (CPU_INT08U)(DEF_INT_08U_MAX_VAL) \ - : (CPU_INT08U)(DEF_BIT08(bit_field) - (CPU_INT08U)1u)) \ - << (bit_shift))) - -#define DEF_BIT_FIELD_16(bit_field, bit_shift) ((CPU_INT16U)((((CPU_INT16U)(bit_field) >= (CPU_INT16U)DEF_INT_16_NBR_BITS) ? (CPU_INT16U)(DEF_INT_16U_MAX_VAL) \ - : (CPU_INT16U)(DEF_BIT16(bit_field) - (CPU_INT16U)1u)) \ - << (bit_shift))) - -#define DEF_BIT_FIELD_32(bit_field, bit_shift) ((CPU_INT32U)((((CPU_INT32U)(bit_field) >= (CPU_INT32U)DEF_INT_32_NBR_BITS) ? (CPU_INT32U)(DEF_INT_32U_MAX_VAL) \ - : (CPU_INT32U)(DEF_BIT32(bit_field) - (CPU_INT32U)1u)) \ - << (bit_shift))) - -#define DEF_BIT_FIELD_64(bit_field, bit_shift) ((CPU_INT64U)((((CPU_INT64U)(bit_field) >= (CPU_INT64U)DEF_INT_64_NBR_BITS) ? (CPU_INT64U)(DEF_INT_64U_MAX_VAL) \ - : (CPU_INT64U)(DEF_BIT64(bit_field) - (CPU_INT64U)1u)) \ - << (bit_shift))) - - -/* -********************************************************************************************************* -* DEF_BIT_SET() -* -* Description : Set specified bit(s) in a value. -* -* Argument(s) : val Value to modify by setting specified bit(s). -* -* mask Mask of bits to set. -* -* Return(s) : Modified value with specified bit(s) set. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. -********************************************************************************************************* -*/ - -#define DEF_BIT_SET(val, mask) ((val) = ((val) | (mask))) - - -/* -********************************************************************************************************* -* DEF_BIT_SET_xx() -* -* Description : Set specified bit(s) in a value of specified bit size. -* -* Argument(s) : val Value to modify by setting specified bit(s). -* -* mask Mask of bits to set. -* -* Return(s) : Modified value with specified bit(s) set. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. -* -* (2) These macros are deprecated and should be replaced by the DEF_BIT_SET macro. -********************************************************************************************************* -*/ - -#define DEF_BIT_SET_08(val, mask) DEF_BIT_SET((val), (mask)) - -#define DEF_BIT_SET_16(val, mask) DEF_BIT_SET((val), (mask)) - -#define DEF_BIT_SET_32(val, mask) DEF_BIT_SET((val), (mask)) - -#define DEF_BIT_SET_64(val, mask) DEF_BIT_SET((val), (mask)) - - -/* -********************************************************************************************************* -* DEF_BIT_CLR() -* -* Description : Clear specified bit(s) in a value. -* -* Argument(s) : val Value to modify by clearing specified bit(s). -* -* mask Mask of bits to clear. -* -* Return(s) : Modified value with specified bit(s) clear. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. -********************************************************************************************************* -*/ - -#define DEF_BIT_CLR(val, mask) ((val) = ((val) & ~(mask))) - - -/* -********************************************************************************************************* -* DEF_BIT_CLR_xx() -* -* Description : Clear specified bit(s) in a value of specified bit size. -* -* Argument(s) : val Value to modify by clearing specified bit(s). -* -* mask Mask of bits to clear. -* -* Return(s) : Modified value with specified bit(s) clear. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. -* -* (2) These macros are deprecated and should be replaced by the DEF_BIT_CLR macro. -********************************************************************************************************* -*/ - -#define DEF_BIT_CLR_08(val, mask) DEF_BIT_CLR((val), (mask)) - -#define DEF_BIT_CLR_16(val, mask) DEF_BIT_CLR((val), (mask)) - -#define DEF_BIT_CLR_32(val, mask) DEF_BIT_CLR((val), (mask)) - -#define DEF_BIT_CLR_64(val, mask) DEF_BIT_CLR((val), (mask)) - - -/* -********************************************************************************************************* -* DEF_BIT_TOGGLE() -* -* Description : Toggles specified bit(s) in a value. -* -* Argument(s) : val Value to modify by toggling specified bit(s). -* -* mask Mask of bits to toggle. -* -* Return(s) : Modified value with specified bit(s) toggled. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. -********************************************************************************************************* -*/ - -#define DEF_BIT_TOGGLE(val, mask) ((val) ^= (mask)) - - -/* -********************************************************************************************************* -* DEF_BIT_FIELD_RD() -* -* Description : Reads a 'val' field, masked and shifted, given by mask 'field_mask'. -* -* Argument(s) : val Value to read from. -* -* field_mask Mask of field to read. See note #1, #2 and #3. -* -* Return(s) : Field value, masked and right-shifted to bit position 0. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'field_mask' argument must NOT be 0. -* -* (2) 'field_mask' argument must contain a mask with contiguous set bits. -* -* (3) 'val' & 'field_mask' SHOULD be unsigned integers. -********************************************************************************************************* -*/ - -#define DEF_BIT_FIELD_RD(val, field_mask) (((val) & (field_mask)) / ((field_mask) & ~((field_mask) << 1u))) - - -/* -********************************************************************************************************* -* DEF_BIT_FIELD_ENC() -* -* Description : Encodes given 'field_val' at position given by mask 'field_mask'. -* -* Argument(s) : field_val Value to encode. -* -* field_mask Mask of field to read. See note #1 and #2. -* -* Return(s) : Field value, masked and left-shifted to field position. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'field_mask' argument must contain a mask with contiguous set bits. -* -* (2) 'field_val' & 'field_mask' SHOULD be unsigned integers. -********************************************************************************************************* -*/ - -#define DEF_BIT_FIELD_ENC(field_val, field_mask) (((field_val) * ((field_mask) & ~((field_mask) << 1u))) & (field_mask)) - - -/* -********************************************************************************************************* -* DEF_BIT_FIELD_WR() -* -* Description : Writes 'field_val' field at position given by mask 'field_mask' in variable 'var'. -* -* Argument(s) : var Variable to write field to. See note #2. -* -* field_val Desired value for field. See note #2. -* -* field_mask Mask of field to write to. See note #1 and #2. -* -* Return(s) : None. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'field_mask' argument must contain a mask with contiguous set bits. -* -* (2) 'var', 'field_val' & 'field_mask' SHOULD be unsigned integers. -********************************************************************************************************* -*/ - -#define DEF_BIT_FIELD_WR(var, field_val, field_mask) (var) = (((var) & ~(field_mask)) | DEF_BIT_FIELD_ENC((field_val), (field_mask))) - - -/* -********************************************************************************************************* -* DEF_BIT_IS_SET() -* -* Description : Determine if specified bit(s) in a value are set. -* -* Argument(s) : val Value to check for specified bit(s) set. -* -* mask Mask of bits to check if set (see Note #2). -* -* Return(s) : DEF_YES, if ALL specified bit(s) are set in value. -* -* DEF_NO, if ALL specified bit(s) are NOT set in value. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. -* -* (2) NULL 'mask' allowed; returns 'DEF_NO' since NO mask bits specified. -********************************************************************************************************* -*/ - -#define DEF_BIT_IS_SET(val, mask) (((((val) & (mask)) == (mask)) && \ - ((mask) != 0u)) ? (DEF_YES) : (DEF_NO)) - - -/* -********************************************************************************************************* -* DEF_BIT_IS_CLR() -* -* Description : Determine if specified bit(s) in a value are clear. -* -* Argument(s) : val Value to check for specified bit(s) clear. -* -* mask Mask of bits to check if clear (see Note #2). -* -* Return(s) : DEF_YES, if ALL specified bit(s) are clear in value. -* -* DEF_NO, if ALL specified bit(s) are NOT clear in value. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. -* -* (2) NULL 'mask' allowed; returns 'DEF_NO' since NO mask bits specified. -********************************************************************************************************* -*/ - -#define DEF_BIT_IS_CLR(val, mask) (((((val) & (mask)) == 0u) && \ - ((mask) != 0u)) ? (DEF_YES) : (DEF_NO)) - - -/* -********************************************************************************************************* -* DEF_BIT_IS_SET_ANY() -* -* Description : Determine if any specified bit(s) in a value are set. -* -* Argument(s) : val Value to check for specified bit(s) set. -* -* mask Mask of bits to check if set (see Note #2). -* -* Return(s) : DEF_YES, if ANY specified bit(s) are set in value. -* -* DEF_NO, if ALL specified bit(s) are NOT set in value. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. -* -* (2) NULL 'mask' allowed; returns 'DEF_NO' since NO mask bits specified. -********************************************************************************************************* -*/ - -#define DEF_BIT_IS_SET_ANY(val, mask) ((((val) & (mask)) == 0u) ? (DEF_NO ) : (DEF_YES)) - - -/* -********************************************************************************************************* -* DEF_BIT_IS_CLR_ANY() -* -* Description : Determine if any specified bit(s) in a value are clear. -* -* Argument(s) : val Value to check for specified bit(s) clear. -* -* mask Mask of bits to check if clear (see Note #2). -* -* Return(s) : DEF_YES, if ANY specified bit(s) are clear in value. -* -* DEF_NO, if ALL specified bit(s) are NOT clear in value. -* -* Note(s) : (1) 'val' & 'mask' SHOULD be unsigned integers. -* -* (2) NULL 'mask' allowed; returns 'DEF_NO' since NO mask bits specified. -********************************************************************************************************* -*/ - -#define DEF_BIT_IS_CLR_ANY(val, mask) ((((val) & (mask)) == (mask)) ? (DEF_NO ) : (DEF_YES)) - - -/* -********************************************************************************************************* -* VALUE MACRO'S -********************************************************************************************************* -*/ - -/* -********************************************************************************************************* -* DEF_CHK_VAL_MIN() -* -* Description : Validate a value as greater than or equal to a specified minimum value. -* -* Argument(s) : val Value to validate. -* -* val_min Minimum value to test. -* -* Return(s) : DEF_OK, Value is greater than or equal to minimum value. -* -* DEF_FAIL, otherwise. -* -* Caller(s) : Application. -* -* Note(s) : (1) DEF_CHK_VAL_MIN() avoids directly comparing any two values if only one of the values -* is negative since the negative value might be incorrectly promoted to an arbitrary -* unsigned value if the other value to compare is unsigned. -* -* (2) Validation of values is limited to the range supported by the compiler &/or target -* environment. All other values that underflow/overflow the supported range will -* modulo/wrap into the supported range as arbitrary signed or unsigned values. -* -* Therefore, any values that underflow the most negative signed value or overflow -* the most positive unsigned value supported by the compiler &/or target environment -* cannot be validated : -* -* ( N-1 N ] -* ( -(2 ) , 2 - 1 ] -* ( ] -* -* where -* N Number of data word bits supported by the compiler -* &/or target environment -* -* (a) Note that the most negative value, -2^(N-1), is NOT included in the supported -* range since many compilers do NOT always correctly handle this value. -* -* (3) 'val' and 'val_min' are compared to 1 instead of 0 to avoid warning generated for -* unsigned numbers. -********************************************************************************************************* -*/ - -#define DEF_CHK_VAL_MIN(val, val_min) (((!(((val) >= 1) && ((val_min) < 1))) && \ - ((((val_min) >= 1) && ((val) < 1)) || \ - ((val) < (val_min)))) ? DEF_FAIL : DEF_OK) - - -/* -********************************************************************************************************* -* DEF_CHK_VAL_MAX() -* -* Description : Validate a value as less than or equal to a specified maximum value. -* -* Argument(s) : val Value to validate. -* -* val_max Maximum value to test. -* -* Return(s) : DEF_OK, Value is less than or equal to maximum value. -* -* DEF_FAIL, otherwise. -* -* Caller(s) : Application. -* -* Note(s) : (1) DEF_CHK_VAL_MAX() avoids directly comparing any two values if only one of the values -* is negative since the negative value might be incorrectly promoted to an arbitrary -* unsigned value if the other value to compare is unsigned. -* -* (2) Validation of values is limited to the range supported by the compiler &/or target -* environment. All other values that underflow/overflow the supported range will -* modulo/wrap into the supported range as arbitrary signed or unsigned values. -* -* Therefore, any values that underflow the most negative signed value or overflow -* the most positive unsigned value supported by the compiler &/or target environment -* cannot be validated : -* -* ( N-1 N ] -* ( -(2 ) , 2 - 1 ] -* ( ] -* -* where -* N Number of data word bits supported by the compiler -* &/or target environment -* -* (a) Note that the most negative value, -2^(N-1), is NOT included in the supported -* range since many compilers do NOT always correctly handle this value. -* -* (3) 'val' and 'val_max' are compared to 1 instead of 0 to avoid warning generated for -* unsigned numbers. -********************************************************************************************************* -*/ - -#define DEF_CHK_VAL_MAX(val, val_max) (((!(((val_max) >= 1) && ((val) < 1))) && \ - ((((val) >= 1) && ((val_max) < 1)) || \ - ((val) > (val_max)))) ? DEF_FAIL : DEF_OK) - - -/* -********************************************************************************************************* -* DEF_CHK_VAL() -* -* Description : Validate a value as greater than or equal to a specified minimum value & less than or -* equal to a specified maximum value. -* -* Argument(s) : val Value to validate. -* -* val_min Minimum value to test. -* -* val_max Maximum value to test. -* -* Return(s) : DEF_OK, Value is greater than or equal to minimum value AND -* less than or equal to maximum value. -* -* DEF_FAIL, otherwise. -* -* Caller(s) : Application. -* -* Note(s) : (1) DEF_CHK_VAL() avoids directly comparing any two values if only one of the values -* is negative since the negative value might be incorrectly promoted to an arbitrary -* unsigned value if the other value to compare is unsigned. -* -* (2) Validation of values is limited to the range supported by the compiler &/or target -* environment. All other values that underflow/overflow the supported range will -* modulo/wrap into the supported range as arbitrary signed or unsigned values. -* -* Therefore, any values that underflow the most negative signed value or overflow -* the most positive unsigned value supported by the compiler &/or target environment -* cannot be validated : -* -* ( N-1 N ] -* ( -(2 ) , 2 - 1 ] -* ( ] -* -* where -* N Number of data word bits supported by the compiler -* &/or target environment -* -* (a) Note that the most negative value, -2^(N-1), is NOT included in the supported -* range since many compilers do NOT always correctly handle this value. -* -* (3) DEF_CHK_VAL() does NOT validate that the maximum value ('val_max') is greater than -* or equal to the minimum value ('val_min'). -********************************************************************************************************* -*/ - -#define DEF_CHK_VAL(val, val_min, val_max) (((DEF_CHK_VAL_MIN((val), (val_min)) == DEF_FAIL) || \ - (DEF_CHK_VAL_MAX((val), (val_max)) == DEF_FAIL)) ? DEF_FAIL : DEF_OK) - - -/* -********************************************************************************************************* -* DEF_GET_U_MAX_VAL() -* -* Description : Get the maximum unsigned value that can be represented in an unsigned integer variable -* of the same data type size as an object. -* -* Argument(s) : obj Object or data type to return maximum unsigned value (see Note #1). -* -* Return(s) : Maximum unsigned integer value that can be represented by the object, if NO error(s). -* -* 0, otherwise. -* -* Caller(s) : Application. -* -* Note(s) : (1) 'obj' SHOULD be an integer object or data type but COULD also be a character or -* pointer object or data type. -********************************************************************************************************* -*/ - -#if (CPU_CFG_DATA_SIZE_MAX == CPU_WORD_SIZE_08) - -#define DEF_GET_U_MAX_VAL(obj) ((sizeof(obj) == CPU_WORD_SIZE_08) ? DEF_INT_08U_MAX_VAL : 0) - - -#elif (CPU_CFG_DATA_SIZE_MAX == CPU_WORD_SIZE_16) - -#define DEF_GET_U_MAX_VAL(obj) ((sizeof(obj) == CPU_WORD_SIZE_08) ? DEF_INT_08U_MAX_VAL : \ - ((sizeof(obj) == CPU_WORD_SIZE_16) ? DEF_INT_16U_MAX_VAL : 0)) - - -#elif (CPU_CFG_DATA_SIZE_MAX == CPU_WORD_SIZE_32) - -#define DEF_GET_U_MAX_VAL(obj) ((sizeof(obj) == CPU_WORD_SIZE_08) ? DEF_INT_08U_MAX_VAL : \ - ((sizeof(obj) == CPU_WORD_SIZE_16) ? DEF_INT_16U_MAX_VAL : \ - ((sizeof(obj) == CPU_WORD_SIZE_32) ? DEF_INT_32U_MAX_VAL : 0))) - - -#elif (CPU_CFG_DATA_SIZE_MAX == CPU_WORD_SIZE_64) - -#define DEF_GET_U_MAX_VAL(obj) ((sizeof(obj) == CPU_WORD_SIZE_08) ? DEF_INT_08U_MAX_VAL : \ - ((sizeof(obj) == CPU_WORD_SIZE_16) ? DEF_INT_16U_MAX_VAL : \ - ((sizeof(obj) == CPU_WORD_SIZE_32) ? DEF_INT_32U_MAX_VAL : \ - ((sizeof(obj) == CPU_WORD_SIZE_64) ? DEF_INT_64U_MAX_VAL : 0)))) - -#else - -#error "CPU_CFG_DATA_SIZE_MAX illegally #defined in 'cpu.h' " -#error " [See 'cpu.h CONFIGURATION ERRORS']" - -#endif - - -/* -********************************************************************************************************* -* MATH MACRO'S -* -* Note(s) : (1) Ideally, ALL mathematical macro's & functions SHOULD be defined in the custom mathematics -* library ('lib_math.*'). #### However, to maintain backwards compatibility with previously- -* released modules, mathematical macro & function definitions should only be moved to the -* custom mathematics library once all previously-released modules are updated to include the -* custom mathematics library. -********************************************************************************************************* -*/ - -/* -********************************************************************************************************* -* DEF_MIN() -* -* Description : Determine the minimum of two values. -* -* Argument(s) : a First value. -* -* b Second value. -* -* Return(s) : Minimum of the two values. -* -* Caller(s) : Application. -* -* Note(s) : none. -********************************************************************************************************* -*/ - -#define DEF_MIN(a, b) (((a) < (b)) ? (a) : (b)) - - -/* -********************************************************************************************************* -* DEF_MAX() -* -* Description : Determine the maximum of two values. -* -* Argument(s) : a First value. -* -* b Second value. -* -* Return(s) : Maximum of the two values. -* -* Note(s) : none. -********************************************************************************************************* -*/ - -#define DEF_MAX(a, b) (((a) > (b)) ? (a) : (b)) - - -/* -********************************************************************************************************* -* DEF_ABS() -* -* Description : Determine the absolute value of a value. -* -* Argument(s) : a Value to calculate absolute value. -* -* Return(s) : Absolute value of the value. -* -* Caller(s) : Application. -* -* Note(s) : none. -********************************************************************************************************* -*/ - -#define DEF_ABS(a) (((a) < 0) ? (-(a)) : (a)) - - -/* -********************************************************************************************************* -* FUNCTION PROTOTYPES -********************************************************************************************************* -*/ - - -/* -********************************************************************************************************* -* CONFIGURATION ERRORS -********************************************************************************************************* -*/ - - -/* -********************************************************************************************************* -* LIBRARY CONFIGURATION ERRORS -********************************************************************************************************* -*/ - - /* See 'lib_def.h Note #1a'. */ -#if (CPU_CORE_VERSION < 12900u) -// #error "CPU_CORE_VERSION [SHOULD be >= V1.29.00]" -#endif - - -/* -********************************************************************************************************* -* MODULE END -* -* Note(s) : (1) See 'lib_def.h MODULE'. -********************************************************************************************************* -*/ - -#endif /* End of lib def module include. */ - diff --git a/Tests/UnitTests/Mocks/RTOS/os.h b/Tests/UnitTests/Mocks/RTOS/os.h index 18ee5d389..1bbb018d8 100644 --- a/Tests/UnitTests/Mocks/RTOS/os.h +++ b/Tests/UnitTests/Mocks/RTOS/os.h @@ -4,7 +4,6 @@ #ifndef OS_H #define OS_H -#include "os_type.h" /* @@ -24,13 +23,12 @@ */ #include "fff.h" #include -//#include #include #include #include "os_type.h" -//#include +#include #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN == DEF_ENABLED)) -//#include +#include #endif diff --git a/Tests/UnitTests/Mocks/RTOS/os_cfg.h b/Tests/UnitTests/Mocks/RTOS/os_cfg.h deleted file mode 100644 index 16ced5b23..000000000 --- a/Tests/UnitTests/Mocks/RTOS/os_cfg.h +++ /dev/null @@ -1,121 +0,0 @@ -///////////////////////////////////////////// -////// MOCK ////// -///////////////////////////////////////////// - -/* -************************************************************************************************************************ -* uC/OS-III -* The Real-Time Kernel -* -* (c) Copyright 2009-2015; Micrium, Inc.; Weston, FL -* All rights reserved. Protected by international copyright laws. -* -* CONFIGURATION FILE -* -* File : OS_CFG.H -* By : JJL -* Version : V3.04.05 -* -* LICENSING TERMS: -* --------------- -* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or -* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/ -* product then, you need to contact Micrium to properly license uC/OS-III for its use in your -* application/product. We provide ALL the source code for your convenience and to help you -* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use -* it commercially without paying a licensing fee. -* -* Knowledge of the source code may NOT be used to develop a similar product. -* -* Please help us continue to provide the embedded community with the finest software available. -* Your honesty is greatly appreciated. -* -* You can find our product's user manual, API reference, release notes and -* more information at https://doc.micrium.com. -* You can contact us at www.micrium.com. -************************************************************************************************************************ -*/ - -#ifndef OS_CFG_H -#define OS_CFG_H - - /* ---------------------------- MISCELLANEOUS -------------------------- */ -#define OS_CFG_APP_HOOKS_EN 1u /* Enable (1) or Disable (0) application specific hooks */ -#define OS_CFG_ARG_CHK_EN 0u /* Enable (1) or Disable (0) argument checking */ -#define OS_CFG_CALLED_FROM_ISR_CHK_EN 0u /* Enable (1) or Disable (0) check for called from ISR */ -#define OS_CFG_DBG_EN 1u /* Enable (1) debug code/variables */ -#define OS_CFG_ISR_POST_DEFERRED_EN 0u /* Enable (1) or Disable (0) Deferred ISR posts */ -#define OS_CFG_OBJ_TYPE_CHK_EN 1u /* Enable (1) or Disable (0) object type checking */ -#define OS_CFG_TS_EN 1u /* Enable (1) or Disable (0) time stamping */ - -#define OS_CFG_PEND_MULTI_EN 1u /* Enable (1) or Disable (0) code generation for multi-pend feature */ - -#define OS_CFG_PRIO_MAX 32u /* Defines the maximum number of task priorities (see OS_PRIO data type) */ - -#define OS_CFG_SCHED_LOCK_TIME_MEAS_EN 0u /* Include code to measure scheduler lock time */ -#define OS_CFG_SCHED_ROUND_ROBIN_EN 0u /* Include code for Round-Robin scheduling */ -#define OS_CFG_STK_SIZE_MIN 64u /* Minimum allowable task stack size */ - - - /* ----------------------------- EVENT FLAGS --------------------------- */ -#define OS_CFG_FLAG_EN 1u /* Enable (1) or Disable (0) code generation for EVENT FLAGS */ -#define OS_CFG_FLAG_DEL_EN 0u /* Include code for OSFlagDel() */ -#define OS_CFG_FLAG_MODE_CLR_EN 0u /* Include code for Wait on Clear EVENT FLAGS */ -#define OS_CFG_FLAG_PEND_ABORT_EN 0u /* Include code for OSFlagPendAbort() */ - - - /* -------------------------- MEMORY MANAGEMENT ------------------------ */ -#define OS_CFG_MEM_EN 1u /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */ - - - /* --------------------- MUTUAL EXCLUSION SEMAPHORES ------------------- */ -#define OS_CFG_MUTEX_EN 1u /* Enable (1) or Disable (0) code generation for MUTEX */ -#define OS_CFG_MUTEX_DEL_EN 0u /* Include code for OSMutexDel() */ -#define OS_CFG_MUTEX_PEND_ABORT_EN 0u /* Include code for OSMutexPendAbort() */ - - - /* --------------------------- MESSAGE QUEUES -------------------------- */ -#define OS_CFG_Q_EN 1u /* Enable (1) or Disable (0) code generation for QUEUES */ -#define OS_CFG_Q_DEL_EN 0u /* Include code for OSQDel() */ -#define OS_CFG_Q_FLUSH_EN 0u /* Include code for OSQFlush() */ -#define OS_CFG_Q_PEND_ABORT_EN 1u /* Include code for OSQPendAbort() */ - - - /* ----------------------------- SEMAPHORES ---------------------------- */ -#define OS_CFG_SEM_EN 1u /* Enable (1) or Disable (0) code generation for SEMAPHORES */ -#define OS_CFG_SEM_DEL_EN 1u /* Include code for OSSemDel() */ -#define OS_CFG_SEM_PEND_ABORT_EN 1u /* Include code for OSSemPendAbort() */ -#define OS_CFG_SEM_SET_EN 1u /* Include code for OSSemSet() */ - - - /* -------------------------- TASK MANAGEMENT -------------------------- */ -#define OS_CFG_STAT_TASK_EN 1u /* Enable (1) or Disable(0) the statistics task */ -#define OS_CFG_STAT_TASK_STK_CHK_EN 1u /* Check task stacks from statistic task */ - -#define OS_CFG_TASK_CHANGE_PRIO_EN 1u /* Include code for OSTaskChangePrio() */ -#define OS_CFG_TASK_DEL_EN 1u /* Include code for OSTaskDel() */ -#define OS_CFG_TASK_Q_EN 1u /* Include code for OSTaskQXXXX() */ -#define OS_CFG_TASK_Q_PEND_ABORT_EN 0u /* Include code for OSTaskQPendAbort() */ -#define OS_CFG_TASK_PROFILE_EN 1u /* Include variables in OS_TCB for profiling */ -#define OS_CFG_TASK_REG_TBL_SIZE 1u /* Number of task specific registers */ -#define OS_CFG_TASK_SEM_PEND_ABORT_EN 1u /* Include code for OSTaskSemPendAbort() */ -#define OS_CFG_TASK_SUSPEND_EN 1u /* Include code for OSTaskSuspend() and OSTaskResume() */ - - - /* -------------------------- TIME MANAGEMENT -------------------------- */ -#define OS_CFG_TIME_DLY_HMSM_EN 1u /* Include code for OSTimeDlyHMSM() */ -#define OS_CFG_TIME_DLY_RESUME_EN 0u /* Include code for OSTimeDlyResume() */ - - - /* ------------------- TASK LOCAL STORAGE MANAGEMENT ------------------- */ -#define OS_CFG_TLS_TBL_SIZE 0u /* Include code for Task Local Storage (TLS) registers */ - - - /* ------------------------- TIMER MANAGEMENT -------------------------- */ -#define OS_CFG_TMR_EN 1u /* Enable (1) or Disable (0) code generation for TIMERS */ -#define OS_CFG_TMR_DEL_EN 0u /* Enable (1) or Disable (0) code generation for OSTmrDel() */ - - /* ------------------------------ uC/TRACE ----------------------------- */ -#define TRACE_CFG_EN 0u /* Enable (1) or Disable (0) uC/Trace instrumentation */ - -#endif diff --git a/Tests/UnitTests/Mocks/RTOS/os_type.h b/Tests/UnitTests/Mocks/RTOS/os_type.h deleted file mode 100644 index 214aeffc9..000000000 --- a/Tests/UnitTests/Mocks/RTOS/os_type.h +++ /dev/null @@ -1,102 +0,0 @@ -///////////////////////////////////////////// -////// MOCK ////// -///////////////////////////////////////////// - -/* -************************************************************************************************************************ -* uC/OS-III -* The Real-Time Kernel -* -* (c) Copyright 2009-2015; Micrium, Inc.; Weston, FL -* All rights reserved. Protected by international copyright laws. -* -* File : OS_TYPE.H -* By : JJL -* Version : V3.05.01 -* -* LICENSING TERMS: -* --------------- -* uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or -* for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/ -* product then, you need to contact Micrium to properly license uC/OS-III for its use in your -* application/product. We provide ALL the source code for your convenience and to help you -* experience uC/OS-III. The fact that the source is provided does NOT mean that you can use -* it commercially without paying a licensing fee. -* -* Knowledge of the source code may NOT be used to develop a similar product. -* -* Please help us continue to provide the embedded community with the finest software available. -* Your honesty is greatly appreciated. -* -* You can find our product's user manual, API reference, release notes and -* more information at https://doc.micrium.com. -* You can contact us at www.micrium.com. -************************************************************************************************************************ -*/ - -#ifndef OS_TYPE_H -#define OS_TYPE_H -#include "cpu.h" -#ifdef VSC_INCLUDE_H_FILE_NAMES -const CPU_CHAR *os_type__h = "$Id: $"; -#endif - -/* -************************************************************************************************************************ -* INCLUDE HEADER FILES -************************************************************************************************************************ -*/ - - /* Description # Bits */ - /* */ - /* ----------------------------------------------------------- */ - -typedef CPU_INT16U OS_CPU_USAGE; /* CPU Usage 0..10000 <16>/32 */ - -typedef CPU_INT32U OS_CTR; /* Counter, 32 */ - -typedef CPU_INT32U OS_CTX_SW_CTR; /* Counter of context switches, 32 */ - -typedef CPU_INT32U OS_CYCLES; /* CPU clock cycles, <32>/64 */ - -typedef CPU_INT32U OS_FLAGS; /* Event flags, 8/16/<32> */ - -typedef CPU_INT32U OS_IDLE_CTR; /* Holds the number of times the idle task runs, <32>/64 */ - -typedef CPU_INT16U OS_MEM_QTY; /* Number of memory blocks, <16>/32 */ -typedef CPU_INT16U OS_MEM_SIZE; /* Size in bytes of a memory block, <16>/32 */ - -typedef CPU_INT16U OS_MSG_QTY; /* Number of OS_MSGs in the msg pool, <16>/32 */ -typedef CPU_INT16U OS_MSG_SIZE; /* Size of messages in number of bytes, <16>/32 */ - -typedef CPU_INT08U OS_NESTING_CTR; /* Interrupt and scheduler nesting, <8>/16/32 */ - -typedef CPU_INT16U OS_OBJ_QTY; /* Number of kernel objects counter, <16>/32 */ -typedef CPU_INT32U OS_OBJ_TYPE; /* Special flag to determine object type, 32 */ - -typedef CPU_INT16U OS_OPT; /* Holds function options, <16>/32 */ - -typedef CPU_INT32U OS_MON_RES; /* Monitor result flags, */ - -typedef CPU_INT08U OS_PRIO; /* Priority of a task, <8>/16/32 */ - -typedef CPU_INT16U OS_QTY; /* Quantity <16>/32 */ - -typedef CPU_INT32U OS_RATE_HZ; /* Rate in Hertz 32 */ - -#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_64) /* Task register 8/16/<32/64> */ -typedef CPU_INT64U OS_REG; -#else -typedef CPU_INT32U OS_REG; -#endif -typedef CPU_INT08U OS_REG_ID; /* Index to task register <8>/16/32 */ - -typedef CPU_INT32U OS_SEM_CTR; /* Semaphore value 16/<32> */ - -typedef CPU_INT08U OS_STATE; /* State variable <8>/16/32 */ - -typedef CPU_INT08U OS_STATUS; /* Status <8>/16/32 */ - -typedef CPU_INT32U OS_TICK; /* Clock tick counter <32>/64 */ - -#endif From 18baf1c021628336e25d6c20313a9279e79e8f14 Mon Sep 17 00:00:00 2001 From: Madeleine Lee Date: Sat, 2 Mar 2024 14:24:10 -0600 Subject: [PATCH 53/57] Removed defines from mock os.h and used original os.h instead. --- Tests/UnitTests/Mocks/RTOS/os.h | 1343 +------------------------------ 1 file changed, 1 insertion(+), 1342 deletions(-) diff --git a/Tests/UnitTests/Mocks/RTOS/os.h b/Tests/UnitTests/Mocks/RTOS/os.h index 1bbb018d8..9f1def980 100644 --- a/Tests/UnitTests/Mocks/RTOS/os.h +++ b/Tests/UnitTests/Mocks/RTOS/os.h @@ -2,10 +2,6 @@ ////// MOCK ////// ///////////////////////////////////////////// -#ifndef OS_H -#define OS_H - - /* ************************************************************************************************************************ * uC/OS-III VERSION NUMBER @@ -22,6 +18,7 @@ ************************************************************************************************************************ */ #include "fff.h" +#include_next "os.h" #include #include #include @@ -31,1341 +28,6 @@ #include #endif - -/* -************************************************************************************************************************ -* CRITICAL SECTION HANDLING -************************************************************************************************************************ -*/ - - -#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u && defined(CPU_CFG_INT_DIS_MEAS_EN) -#define OS_SCHED_LOCK_TIME_MEAS_START() OS_SchedLockTimeMeasStart() -#else -#define OS_SCHED_LOCK_TIME_MEAS_START() -#endif - - -#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u && defined(CPU_CFG_INT_DIS_MEAS_EN) -#define OS_SCHED_LOCK_TIME_MEAS_STOP() OS_SchedLockTimeMeasStop() -#else -#define OS_SCHED_LOCK_TIME_MEAS_STOP() -#endif - -#if OS_CFG_ISR_POST_DEFERRED_EN > 0u /* Deferred ISR Posts ------------------------------ */ - /* Lock the scheduler */ -#define OS_CRITICAL_ENTER() \ - do { \ - CPU_CRITICAL_ENTER(); \ - OSSchedLockNestingCtr++; \ - if (OSSchedLockNestingCtr == 1u) { \ - OS_SCHED_LOCK_TIME_MEAS_START(); \ - } \ - CPU_CRITICAL_EXIT(); \ - } while (0) - /* Lock the scheduler but re-enable interrupts */ -#define OS_CRITICAL_ENTER_CPU_EXIT() \ - do { \ - OSSchedLockNestingCtr++; \ - \ - if (OSSchedLockNestingCtr == 1u) { \ - OS_SCHED_LOCK_TIME_MEAS_START(); \ - } \ - CPU_CRITICAL_EXIT(); \ - } while (0) - - /* Scheduling occurs only if an interrupt occurs */ -#define OS_CRITICAL_EXIT() \ - do { \ - CPU_CRITICAL_ENTER(); \ - OSSchedLockNestingCtr--; \ - if (OSSchedLockNestingCtr == (OS_NESTING_CTR)0) { \ - OS_SCHED_LOCK_TIME_MEAS_STOP(); \ - if (OSIntQNbrEntries > (OS_OBJ_QTY)0) { \ - CPU_CRITICAL_EXIT(); \ - OS_Sched0(); \ - } else { \ - CPU_CRITICAL_EXIT(); \ - } \ - } else { \ - CPU_CRITICAL_EXIT(); \ - } \ - } while (0) - -#define OS_CRITICAL_EXIT_NO_SCHED() \ - do { \ - CPU_CRITICAL_ENTER(); \ - OSSchedLockNestingCtr--; \ - if (OSSchedLockNestingCtr == (OS_NESTING_CTR)0) { \ - OS_SCHED_LOCK_TIME_MEAS_STOP(); \ - } \ - CPU_CRITICAL_EXIT(); \ - } while (0) - - -#else /* Direct ISR Posts -------------------------------- */ - - -#define OS_CRITICAL_ENTER() CPU_CRITICAL_ENTER() - -#define OS_CRITICAL_ENTER_CPU_EXIT() - -#define OS_CRITICAL_EXIT() CPU_CRITICAL_EXIT() - -#define OS_CRITICAL_EXIT_NO_SCHED() CPU_CRITICAL_EXIT() - -#endif - -/* -************************************************************************************************************************ -* MISCELLANEOUS -************************************************************************************************************************ -*/ - -#ifdef OS_GLOBALS -#define OS_EXT -#else -#define OS_EXT extern -#endif - - -#define OS_PRIO_TBL_SIZE ((OS_CFG_PRIO_MAX - 1u) / (DEF_INT_CPU_NBR_BITS) + 1u) - -#define OS_MSG_EN (((OS_CFG_TASK_Q_EN > 0u) || (OS_CFG_Q_EN > 0u)) ? 1u : 0u) - -#define OS_OBJ_TYPE_REQ (((OS_CFG_DBG_EN > 0u) || (OS_CFG_OBJ_TYPE_CHK_EN > 0u) || (OS_CFG_PEND_MULTI_EN > 0u) \ - || (OS_CFG_ISR_POST_DEFERRED_EN > 0u)) ? 1u : 0u) - - -/* -************************************************************************************************************************ -************************************************************************************************************************ -* # D E F I N E S -************************************************************************************************************************ -************************************************************************************************************************ -*/ - -/* -======================================================================================================================== -* TASK STATUS -======================================================================================================================== -*/ - -#define OS_STATE_OS_STOPPED (OS_STATE)(0u) -#define OS_STATE_OS_RUNNING (OS_STATE)(1u) - -#define OS_STATE_NOT_RDY (CPU_BOOLEAN)(0u) -#define OS_STATE_RDY (CPU_BOOLEAN)(1u) - - - /* ------------------- TASK STATES ------------------ */ -#define OS_TASK_STATE_BIT_DLY (OS_STATE)(0x01u) /* /-------- SUSPENDED bit */ - /* | */ -#define OS_TASK_STATE_BIT_PEND (OS_STATE)(0x02u) /* | /----- PEND bit */ - /* | | */ -#define OS_TASK_STATE_BIT_SUSPENDED (OS_STATE)(0x04u) /* | | /--- Delayed/Timeout bit */ - /* | | | */ - /* V V V */ - -#define OS_TASK_STATE_RDY (OS_STATE)( 0u) /* 0 0 0 Ready */ -#define OS_TASK_STATE_DLY (OS_STATE)( 1u) /* 0 0 1 Delayed or Timeout */ -#define OS_TASK_STATE_PEND (OS_STATE)( 2u) /* 0 1 0 Pend */ -#define OS_TASK_STATE_PEND_TIMEOUT (OS_STATE)( 3u) /* 0 1 1 Pend + Timeout */ -#define OS_TASK_STATE_SUSPENDED (OS_STATE)( 4u) /* 1 0 0 Suspended */ -#define OS_TASK_STATE_DLY_SUSPENDED (OS_STATE)( 5u) /* 1 0 1 Suspended + Delayed or Timeout */ -#define OS_TASK_STATE_PEND_SUSPENDED (OS_STATE)( 6u) /* 1 1 0 Suspended + Pend */ -#define OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED (OS_STATE)( 7u) /* 1 1 1 Suspended + Pend + Timeout */ -#define OS_TASK_STATE_DEL (OS_STATE)(255u) - - /* ----------------- PENDING ON ... ----------------- */ -#define OS_TASK_PEND_ON_NOTHING (OS_STATE)( 0u) /* Pending on nothing */ -#define OS_TASK_PEND_ON_FLAG (OS_STATE)( 1u) /* Pending on event flag group */ -#define OS_TASK_PEND_ON_TASK_Q (OS_STATE)( 2u) /* Pending on message to be sent to task */ -#define OS_TASK_PEND_ON_MULTI (OS_STATE)( 3u) /* Pending on multiple semaphores and/or queues */ -#define OS_TASK_PEND_ON_MUTEX (OS_STATE)( 4u) /* Pending on mutual exclusion semaphore */ -#define OS_TASK_PEND_ON_Q (OS_STATE)( 5u) /* Pending on queue */ -#define OS_TASK_PEND_ON_SEM (OS_STATE)( 6u) /* Pending on semaphore */ -#define OS_TASK_PEND_ON_TASK_SEM (OS_STATE)( 7u) /* Pending on signal to be sent to task */ - -/* ------------------------------------------------------------------------------------------------------------------------- -* TASK PEND STATUS -* (Status codes for OS_TCBs field .PendStatus) ------------------------------------------------------------------------------------------------------------------------- -*/ - -#define OS_STATUS_PEND_OK (OS_STATUS)( 0u) /* Pending status OK, !pending, or pending complete */ -#define OS_STATUS_PEND_ABORT (OS_STATUS)( 1u) /* Pending aborted */ -#define OS_STATUS_PEND_DEL (OS_STATUS)( 2u) /* Pending object deleted */ -#define OS_STATUS_PEND_TIMEOUT (OS_STATUS)( 3u) /* Pending timed out */ - -/* -======================================================================================================================== -* OS OBJECT TYPES -* -* Note(s) : (1) OS_OBJ_TYPE_&&& #define values specifically chosen as ASCII representations of the kernel -* object types. Memory displays of kernel objects will display the kernel object TYPEs with -* their chosen ASCII names. -======================================================================================================================== -*/ - -#define OS_OBJ_TYPE_NONE (OS_OBJ_TYPE)CPU_TYPE_CREATE('N', 'O', 'N', 'E') -#define OS_OBJ_TYPE_FLAG (OS_OBJ_TYPE)CPU_TYPE_CREATE('F', 'L', 'A', 'G') -#define OS_OBJ_TYPE_MEM (OS_OBJ_TYPE)CPU_TYPE_CREATE('M', 'E', 'M', ' ') -#define OS_OBJ_TYPE_MUTEX (OS_OBJ_TYPE)CPU_TYPE_CREATE('M', 'U', 'T', 'X') -#define OS_OBJ_TYPE_Q (OS_OBJ_TYPE)CPU_TYPE_CREATE('Q', 'U', 'E', 'U') -#define OS_OBJ_TYPE_SEM (OS_OBJ_TYPE)CPU_TYPE_CREATE('S', 'E', 'M', 'A') -#define OS_OBJ_TYPE_TASK_MSG (OS_OBJ_TYPE)CPU_TYPE_CREATE('T', 'M', 'S', 'G') -#define OS_OBJ_TYPE_TASK_RESUME (OS_OBJ_TYPE)CPU_TYPE_CREATE('T', 'R', 'E', 'S') -#define OS_OBJ_TYPE_TASK_SIGNAL (OS_OBJ_TYPE)CPU_TYPE_CREATE('T', 'S', 'I', 'G') -#define OS_OBJ_TYPE_TASK_SUSPEND (OS_OBJ_TYPE)CPU_TYPE_CREATE('T', 'S', 'U', 'S') -#define OS_OBJ_TYPE_TICK (OS_OBJ_TYPE)CPU_TYPE_CREATE('T', 'I', 'C', 'K') -#define OS_OBJ_TYPE_TMR (OS_OBJ_TYPE)CPU_TYPE_CREATE('T', 'M', 'R', ' ') - -/* -======================================================================================================================== -* Possible values for 'opt' argument -======================================================================================================================== -*/ - -#define OS_OPT_NONE (OS_OPT)(0x0000u) - -/* ------------------------------------------------------------------------------------------------------------------------- -* DELETE OPTIONS ------------------------------------------------------------------------------------------------------------------------- -*/ - -#define OS_OPT_DEL_NO_PEND (OS_OPT)(0x0000u) -#define OS_OPT_DEL_ALWAYS (OS_OPT)(0x0001u) - -/* ------------------------------------------------------------------------------------------------------------------------- -* PEND OPTIONS ------------------------------------------------------------------------------------------------------------------------- -*/ - -#define OS_OPT_PEND_FLAG_MASK (OS_OPT)(0x000Fu) -#define OS_OPT_PEND_FLAG_CLR_ALL (OS_OPT)(0x0001u) /* Wait for ALL the bits specified to be CLR */ -#define OS_OPT_PEND_FLAG_CLR_AND (OS_OPT)(0x0001u) - -#define OS_OPT_PEND_FLAG_CLR_ANY (OS_OPT)(0x0002u) /* Wait for ANY of the bits specified to be CLR */ -#define OS_OPT_PEND_FLAG_CLR_OR (OS_OPT)(0x0002u) - -#define OS_OPT_PEND_FLAG_SET_ALL (OS_OPT)(0x0004u) /* Wait for ALL the bits specified to be SET */ -#define OS_OPT_PEND_FLAG_SET_AND (OS_OPT)(0x0004u) - -#define OS_OPT_PEND_FLAG_SET_ANY (OS_OPT)(0x0008u) /* Wait for ANY of the bits specified to be SET */ -#define OS_OPT_PEND_FLAG_SET_OR (OS_OPT)(0x0008u) - -#define OS_OPT_PEND_FLAG_CONSUME (OS_OPT)(0x0100u) /* Consume the flags if condition(s) satisfied */ - - -#define OS_OPT_PEND_BLOCKING (OS_OPT)(0x0000u) -#define OS_OPT_PEND_NON_BLOCKING (OS_OPT)(0x8000u) - -/* ------------------------------------------------------------------------------------------------------------------------- -* PEND ABORT OPTIONS ------------------------------------------------------------------------------------------------------------------------- -*/ - -#define OS_OPT_PEND_ABORT_1 (OS_OPT)(0x0000u) /* Pend abort a single waiting task */ -#define OS_OPT_PEND_ABORT_ALL (OS_OPT)(0x0100u) /* Pend abort ALL tasks waiting */ - -/* ------------------------------------------------------------------------------------------------------------------------- -* POST OPTIONS ------------------------------------------------------------------------------------------------------------------------- -*/ - - -#define OS_OPT_POST_NONE (OS_OPT)(0x0000u) - -#define OS_OPT_POST_FLAG_SET (OS_OPT)(0x0000u) -#define OS_OPT_POST_FLAG_CLR (OS_OPT)(0x0001u) - -#define OS_OPT_POST_FIFO (OS_OPT)(0x0000u) /* Default is to post FIFO */ -#define OS_OPT_POST_LIFO (OS_OPT)(0x0010u) /* Post to highest priority task waiting */ -#define OS_OPT_POST_1 (OS_OPT)(0x0000u) /* Post message to highest priority task waiting */ -#define OS_OPT_POST_ALL (OS_OPT)(0x0200u) /* Broadcast message to ALL tasks waiting */ - -#define OS_OPT_POST_NO_SCHED (OS_OPT)(0x8000u) /* Do not call the scheduler if this is selected */ - -/* ------------------------------------------------------------------------------------------------------------------------- -* PEND ABORT OPTIONS ------------------------------------------------------------------------------------------------------------------------- -*/ - -#define OS_OPT_PEND_ABORT_1 (OS_OPT)(0x0000u) /* Pend abort a single waiting task */ -#define OS_OPT_PEND_ABORT_ALL (OS_OPT)(0x0100u) /* Pend abort ALL tasks waiting */ - -/* ------------------------------------------------------------------------------------------------------------------------- -* POST OPTIONS ------------------------------------------------------------------------------------------------------------------------- -*/ - - -#define OS_OPT_POST_NONE (OS_OPT)(0x0000u) - -#define OS_OPT_POST_FLAG_SET (OS_OPT)(0x0000u) -#define OS_OPT_POST_FLAG_CLR (OS_OPT)(0x0001u) - -#define OS_OPT_POST_FIFO (OS_OPT)(0x0000u) /* Default is to post FIFO */ -#define OS_OPT_POST_LIFO (OS_OPT)(0x0010u) /* Post to highest priority task waiting */ -#define OS_OPT_POST_1 (OS_OPT)(0x0000u) /* Post message to highest priority task waiting */ -#define OS_OPT_POST_ALL (OS_OPT)(0x0200u) /* Broadcast message to ALL tasks waiting */ - -#define OS_OPT_POST_NO_SCHED (OS_OPT)(0x8000u) /* Do not call the scheduler if this is selected */ - -/* ------------------------------------------------------------------------------------------------------------------------- -* TIMER OPTIONS ------------------------------------------------------------------------------------------------------------------------- -*/ - -#define OS_OPT_TMR_NONE (OS_OPT)(0u) /* No option selected */ - -#define OS_OPT_TMR_ONE_SHOT (OS_OPT)(1u) /* Timer will not auto restart when it expires */ -#define OS_OPT_TMR_PERIODIC (OS_OPT)(2u) /* Timer will auto restart when it expires */ - -#define OS_OPT_TMR_CALLBACK (OS_OPT)(3u) /* OSTmrStop() option to call 'callback' w/ timer arg */ -#define OS_OPT_TMR_CALLBACK_ARG (OS_OPT)(4u) /* OSTmrStop() option to call 'callback' w/ new arg */ - -/* ------------------------------------------------------------------------------------------------------------------------- -* TIMER STATES ------------------------------------------------------------------------------------------------------------------------- -*/ - -#define OS_TMR_STATE_UNUSED (OS_STATE)(0u) -#define OS_TMR_STATE_STOPPED (OS_STATE)(1u) -#define OS_TMR_STATE_RUNNING (OS_STATE)(2u) -#define OS_TMR_STATE_COMPLETED (OS_STATE)(3u) - -/* ------------------------------------------------------------------------------------------------------------------------- -* PRIORITY ------------------------------------------------------------------------------------------------------------------------- -*/ - /* Dflt prio to init task TCB */ -#define OS_PRIO_INIT (OS_PRIO)(OS_CFG_PRIO_MAX) - -/* ------------------------------------------------------------------------------------------------------------------------- -* TIMER TICK THRESHOLDS ------------------------------------------------------------------------------------------------------------------------- -*/ - /* Threshold to init previous tick time */ -#define OS_TICK_TH_INIT (OS_TICK)(DEF_BIT ((sizeof(OS_TICK) * DEF_OCTET_NBR_BITS) - 1u)) - - /* Threshold to check if tick time already ready */ -#define OS_TICK_TH_RDY (OS_TICK)(DEF_BIT_FIELD(((sizeof(OS_TICK) * DEF_OCTET_NBR_BITS) / 2u), \ - ((sizeof(OS_TICK) * DEF_OCTET_NBR_BITS) / 2u))) - - -/* -************************************************************************************************************************ -************************************************************************************************************************ -* E N U M E R A T I O N S -************************************************************************************************************************ -************************************************************************************************************************ -*/ - -/* ------------------------------------------------------------------------------------------------------------------------- -* ERROR CODES ------------------------------------------------------------------------------------------------------------------------- -*/ - -typedef enum os_err { - OS_ERR_NONE = 0u, - - OS_ERR_A = 10000u, - OS_ERR_ACCEPT_ISR = 10001u, - - OS_ERR_B = 11000u, - - OS_ERR_C = 12000u, - OS_ERR_CREATE_ISR = 12001u, - - OS_ERR_D = 13000u, - OS_ERR_DEL_ISR = 13001u, - - OS_ERR_E = 14000u, - - OS_ERR_F = 15000u, - OS_ERR_FATAL_RETURN = 15001u, - - OS_ERR_FLAG_GRP_DEPLETED = 15101u, - OS_ERR_FLAG_NOT_RDY = 15102u, - OS_ERR_FLAG_PEND_OPT = 15103u, - OS_ERR_FLUSH_ISR = 15104u, - - OS_ERR_G = 16000u, - - OS_ERR_H = 17000u, - - OS_ERR_I = 18000u, - OS_ERR_ILLEGAL_CREATE_RUN_TIME = 18001u, - OS_ERR_INT_Q = 18002u, - OS_ERR_INT_Q_FULL = 18003u, - OS_ERR_INT_Q_SIZE = 18004u, - OS_ERR_INT_Q_STK_INVALID = 18005u, - OS_ERR_INT_Q_STK_SIZE_INVALID = 18006u, - - OS_ERR_J = 19000u, - - OS_ERR_K = 20000u, - - OS_ERR_L = 21000u, - OS_ERR_LOCK_NESTING_OVF = 21001u, - - OS_ERR_M = 22000u, - - OS_ERR_MEM_CREATE_ISR = 22201u, - OS_ERR_MEM_FULL = 22202u, - OS_ERR_MEM_INVALID_P_ADDR = 22203u, - OS_ERR_MEM_INVALID_BLKS = 22204u, - OS_ERR_MEM_INVALID_PART = 22205u, - OS_ERR_MEM_INVALID_P_BLK = 22206u, - OS_ERR_MEM_INVALID_P_MEM = 22207u, - OS_ERR_MEM_INVALID_P_DATA = 22208u, - OS_ERR_MEM_INVALID_SIZE = 22209u, - OS_ERR_MEM_NO_FREE_BLKS = 22210u, - - OS_ERR_MSG_POOL_EMPTY = 22301u, - OS_ERR_MSG_POOL_NULL_PTR = 22302u, - - OS_ERR_MUTEX_NOT_OWNER = 22401u, - OS_ERR_MUTEX_OWNER = 22402u, - OS_ERR_MUTEX_NESTING = 22403u, - OS_ERR_MUTEX_OVF = 22404u, - - OS_ERR_N = 23000u, - OS_ERR_NAME = 23001u, - OS_ERR_NO_MORE_ID_AVAIL = 23002u, - - OS_ERR_O = 24000u, - OS_ERR_OBJ_CREATED = 24001u, - OS_ERR_OBJ_DEL = 24002u, - OS_ERR_OBJ_PTR_NULL = 24003u, - OS_ERR_OBJ_TYPE = 24004u, - - OS_ERR_OPT_INVALID = 24101u, - - OS_ERR_OS_NOT_RUNNING = 24201u, - OS_ERR_OS_RUNNING = 24202u, - - OS_ERR_P = 25000u, - OS_ERR_PEND_ABORT = 25001u, - OS_ERR_PEND_ABORT_ISR = 25002u, - OS_ERR_PEND_ABORT_NONE = 25003u, - OS_ERR_PEND_ABORT_SELF = 25004u, - OS_ERR_PEND_DEL = 25005u, - OS_ERR_PEND_ISR = 25006u, - OS_ERR_PEND_LOCKED = 25007u, - OS_ERR_PEND_WOULD_BLOCK = 25008u, - - OS_ERR_POST_NULL_PTR = 25101u, - OS_ERR_POST_ISR = 25102u, - - OS_ERR_PRIO_EXIST = 25201u, - OS_ERR_PRIO = 25202u, - OS_ERR_PRIO_INVALID = 25203u, - - OS_ERR_PTR_INVALID = 25301u, - - OS_ERR_Q = 26000u, - OS_ERR_Q_FULL = 26001u, - OS_ERR_Q_EMPTY = 26002u, - OS_ERR_Q_MAX = 26003u, - OS_ERR_Q_SIZE = 26004u, - - OS_ERR_R = 27000u, - OS_ERR_REG_ID_INVALID = 27001u, - OS_ERR_ROUND_ROBIN_1 = 27002u, - OS_ERR_ROUND_ROBIN_DISABLED = 27003u, - - OS_ERR_S = 28000u, - OS_ERR_SCHED_INVALID_TIME_SLICE = 28001u, - OS_ERR_SCHED_LOCK_ISR = 28002u, - OS_ERR_SCHED_LOCKED = 28003u, - OS_ERR_SCHED_NOT_LOCKED = 28004u, - OS_ERR_SCHED_UNLOCK_ISR = 28005u, - - OS_ERR_SEM_OVF = 28101u, - OS_ERR_SET_ISR = 28102u, - - OS_ERR_STAT_RESET_ISR = 28201u, - OS_ERR_STAT_PRIO_INVALID = 28202u, - OS_ERR_STAT_STK_INVALID = 28203u, - OS_ERR_STAT_STK_SIZE_INVALID = 28204u, - OS_ERR_STATE_INVALID = 28205u, - OS_ERR_STATUS_INVALID = 28206u, - OS_ERR_STK_INVALID = 28207u, - OS_ERR_STK_SIZE_INVALID = 28208u, - OS_ERR_STK_LIMIT_INVALID = 28209u, - - OS_ERR_T = 29000u, - OS_ERR_TASK_CHANGE_PRIO_ISR = 29001u, - OS_ERR_TASK_CREATE_ISR = 29002u, - OS_ERR_TASK_DEL = 29003u, - OS_ERR_TASK_DEL_IDLE = 29004u, - OS_ERR_TASK_DEL_INVALID = 29005u, - OS_ERR_TASK_DEL_ISR = 29006u, - OS_ERR_TASK_INVALID = 29007u, - OS_ERR_TASK_NO_MORE_TCB = 29008u, - OS_ERR_TASK_NOT_DLY = 29009u, - OS_ERR_TASK_NOT_EXIST = 29010u, - OS_ERR_TASK_NOT_SUSPENDED = 29011u, - OS_ERR_TASK_OPT = 29012u, - OS_ERR_TASK_RESUME_ISR = 29013u, - OS_ERR_TASK_RESUME_PRIO = 29014u, - OS_ERR_TASK_RESUME_SELF = 29015u, - OS_ERR_TASK_RUNNING = 29016u, - OS_ERR_TASK_STK_CHK_ISR = 29017u, - OS_ERR_TASK_SUSPENDED = 29018u, - OS_ERR_TASK_SUSPEND_IDLE = 29019u, - OS_ERR_TASK_SUSPEND_INT_HANDLER = 29020u, - OS_ERR_TASK_SUSPEND_ISR = 29021u, - OS_ERR_TASK_SUSPEND_PRIO = 29022u, - OS_ERR_TASK_WAITING = 29023u, - - OS_ERR_TCB_INVALID = 29101u, - - OS_ERR_TLS_ID_INVALID = 29120u, - OS_ERR_TLS_ISR = 29121u, - OS_ERR_TLS_NO_MORE_AVAIL = 29122u, - OS_ERR_TLS_NOT_EN = 29123u, - OS_ERR_TLS_DESTRUCT_ASSIGNED = 29124u, - - OS_ERR_TICK_PRIO_INVALID = 29201u, - OS_ERR_TICK_STK_INVALID = 29202u, - OS_ERR_TICK_STK_SIZE_INVALID = 29203u, - OS_ERR_TICK_WHEEL_SIZE = 29204u, - - OS_ERR_TIME_DLY_ISR = 29301u, - OS_ERR_TIME_DLY_RESUME_ISR = 29302u, - OS_ERR_TIME_GET_ISR = 29303u, - OS_ERR_TIME_INVALID_HOURS = 29304u, - OS_ERR_TIME_INVALID_MINUTES = 29305u, - OS_ERR_TIME_INVALID_SECONDS = 29306u, - OS_ERR_TIME_INVALID_MILLISECONDS = 29307u, - OS_ERR_TIME_NOT_DLY = 29308u, - OS_ERR_TIME_SET_ISR = 29309u, - OS_ERR_TIME_ZERO_DLY = 29310u, - - OS_ERR_TIMEOUT = 29401u, - - OS_ERR_TMR_INACTIVE = 29501u, - OS_ERR_TMR_INVALID_DEST = 29502u, - OS_ERR_TMR_INVALID_DLY = 29503u, - OS_ERR_TMR_INVALID_PERIOD = 29504u, - OS_ERR_TMR_INVALID_STATE = 29505u, - OS_ERR_TMR_INVALID = 29506u, - OS_ERR_TMR_ISR = 29507u, - OS_ERR_TMR_NO_CALLBACK = 29508u, - OS_ERR_TMR_NON_AVAIL = 29509u, - OS_ERR_TMR_PRIO_INVALID = 29510u, - OS_ERR_TMR_STK_INVALID = 29511u, - OS_ERR_TMR_STK_SIZE_INVALID = 29512u, - OS_ERR_TMR_STOPPED = 29513u, - - OS_ERR_U = 30000u, - - OS_ERR_V = 31000u, - - OS_ERR_W = 32000u, - - OS_ERR_X = 33000u, - - OS_ERR_Y = 34000u, - OS_ERR_YIELD_ISR = 34001u, - - OS_ERR_Z = 35000u -} OS_ERR; - - - -/* -************************************************************************************************************************ -************************************************************************************************************************ -* D A T A T Y P E S -************************************************************************************************************************ -************************************************************************************************************************ -*/ - -typedef struct os_flag_grp OS_FLAG_GRP; - -typedef struct os_mem OS_MEM; - -typedef struct os_msg OS_MSG; -typedef struct os_msg_pool OS_MSG_POOL; -typedef struct os_msg_q OS_MSG_Q; - -typedef struct os_mutex OS_MUTEX; - -typedef struct os_int_q OS_INT_Q; - -typedef struct os_q OS_Q; - -typedef struct os_sem OS_SEM; - -typedef void (*OS_TASK_PTR)(void *p_arg); - -typedef struct os_tcb OS_TCB; - -#if defined(OS_CFG_TLS_TBL_SIZE) && (OS_CFG_TLS_TBL_SIZE > 0u) -typedef void *OS_TLS; - -typedef CPU_DATA OS_TLS_ID; - -typedef void (*OS_TLS_DESTRUCT_PTR)(OS_TCB *p_tcb, - OS_TLS_ID id, - OS_TLS value); -#endif - -typedef struct os_rdy_list OS_RDY_LIST; - -typedef struct os_tick_list OS_TICK_LIST; - -typedef void (*OS_TMR_CALLBACK_PTR)(void *p_tmr, void *p_arg); -typedef struct os_tmr OS_TMR; - -typedef struct os_pend_data OS_PEND_DATA; -typedef struct os_pend_list OS_PEND_LIST; -typedef struct os_pend_obj OS_PEND_OBJ; - -#if OS_CFG_APP_HOOKS_EN > 0u -typedef void (*OS_APP_HOOK_VOID)(void); -typedef void (*OS_APP_HOOK_TCB)(OS_TCB *p_tcb); -#endif - - -/* -************************************************************************************************************************ -************************************************************************************************************************ -* D A T A S T R U C T U R E S -************************************************************************************************************************ -************************************************************************************************************************ -*/ - -/* ------------------------------------------------------------------------------------------------------------------------- -* ISR POST DATA ------------------------------------------------------------------------------------------------------------------------- -*/ - -#if OS_CFG_ISR_POST_DEFERRED_EN > 0u -struct os_int_q { - OS_OBJ_TYPE Type; /* Type of object placed in the circular list */ - OS_INT_Q *NextPtr; /* Pointer to next OS_INT_Q in circular list */ - void *ObjPtr; /* Pointer to object placed in the queue */ - void *MsgPtr; /* Pointer to message if posting to a message queue */ - OS_MSG_SIZE MsgSize; /* Message Size if posting to a message queue */ - OS_FLAGS Flags; /* Value of flags if posting to an event flag group */ - OS_OPT Opt; /* Post Options */ - CPU_TS TS; /* Timestamp */ -}; -#endif - -/* ------------------------------------------------------------------------------------------------------------------------- -* READY LIST ------------------------------------------------------------------------------------------------------------------------- -*/ - -struct os_rdy_list { - OS_TCB *HeadPtr; /* Pointer to task that will run at selected priority */ - OS_TCB *TailPtr; /* Pointer to last task at selected priority */ - OS_OBJ_QTY NbrEntries; /* Number of entries at selected priority */ -}; - - -/* ------------------------------------------------------------------------------------------------------------------------- -* PEND DATA and PEND LIST ------------------------------------------------------------------------------------------------------------------------- -*/ - -struct os_pend_data { - OS_PEND_DATA *PrevPtr; - OS_PEND_DATA *NextPtr; - OS_TCB *TCBPtr; - OS_PEND_OBJ *PendObjPtr; - OS_PEND_OBJ *RdyObjPtr; - void *RdyMsgPtr; - OS_MSG_SIZE RdyMsgSize; - CPU_TS RdyTS; -}; - - -struct os_pend_list { - OS_PEND_DATA *HeadPtr; - OS_PEND_DATA *TailPtr; - OS_OBJ_QTY NbrEntries; -}; - - -/* ------------------------------------------------------------------------------------------------------------------------- -* PEND OBJ -* -* Note(s) : (1) The 'os_pend_obj' structure data type is a template/subset for specific kernel objects' data types: -* 'os_flag_grp', 'os_mutex', 'os_q', and 'os_sem'. Each specific kernel object data type MUST define -* ALL generic OS pend object parameters, synchronized in both the sequential order & data type of each -* parameter. -* -* Thus, ANY modification to the sequential order or data types of OS pend object parameters MUST be -* appropriately synchronized between the generic OS pend object data type & ALL specific kernel objects' -* data types. ------------------------------------------------------------------------------------------------------------------------- -*/ - -struct os_pend_obj { -#if OS_OBJ_TYPE_REQ > 0u - OS_OBJ_TYPE Type; -#endif -#if OS_CFG_DBG_EN > 0u - CPU_CHAR *NamePtr; -#endif - OS_PEND_LIST PendList; /* List of tasks pending on object */ -#if OS_CFG_DBG_EN > 0u - void *DbgPrevPtr; - void *DbgNextPtr; - CPU_CHAR *DbgNamePtr; -#endif -}; - - -/* ------------------------------------------------------------------------------------------------------------------------- -* EVENT FLAGS -* -* Note(s) : See PEND OBJ Note #1'. ------------------------------------------------------------------------------------------------------------------------- -*/ - - -struct os_flag_grp { /* Event Flag Group */ - /* ------------------ GENERIC MEMBERS ------------------ */ -#if OS_OBJ_TYPE_REQ > 0u - OS_OBJ_TYPE Type; /* Should be set to OS_OBJ_TYPE_FLAG */ -#endif -#if OS_CFG_DBG_EN > 0u - CPU_CHAR *NamePtr; /* Pointer to Event Flag Name (NUL terminated ASCII) */ -#endif - OS_PEND_LIST PendList; /* List of tasks waiting on event flag group */ -#if OS_CFG_DBG_EN > 0u - OS_FLAG_GRP *DbgPrevPtr; - OS_FLAG_GRP *DbgNextPtr; - CPU_CHAR *DbgNamePtr; -#endif - /* ------------------ SPECIFIC MEMBERS ------------------ */ - OS_FLAGS Flags; /* 8, 16 or 32 bit flags */ - CPU_TS TS; /* Timestamp of when last post occurred */ -#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) - CPU_INT32U FlagID; /* Unique ID for third-party debuggers and tracers. */ -#endif -}; - - -/* ------------------------------------------------------------------------------------------------------------------------- -* MEMORY PARTITIONS ------------------------------------------------------------------------------------------------------------------------- -*/ - - -struct os_mem { /* MEMORY CONTROL BLOCK */ -#if OS_OBJ_TYPE_REQ > 0u - OS_OBJ_TYPE Type; /* Should be set to OS_OBJ_TYPE_MEM */ -#endif - void *AddrPtr; /* Pointer to beginning of memory partition */ -#if OS_CFG_DBG_EN > 0u - CPU_CHAR *NamePtr; -#endif - void *FreeListPtr; /* Pointer to list of free memory blocks */ - OS_MEM_SIZE BlkSize; /* Size (in bytes) of each block of memory */ - OS_MEM_QTY NbrMax; /* Total number of blocks in this partition */ - OS_MEM_QTY NbrFree; /* Number of memory blocks remaining in this partition */ -#if OS_CFG_DBG_EN > 0u - OS_MEM *DbgPrevPtr; - OS_MEM *DbgNextPtr; -#endif -#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) - CPU_INT32U MemID; /* Unique ID for third-party debuggers and tracers. */ -#endif -}; - - -/* ------------------------------------------------------------------------------------------------------------------------- -* MESSAGES ------------------------------------------------------------------------------------------------------------------------- -*/ - -struct os_msg { /* MESSAGE CONTROL BLOCK */ - OS_MSG *NextPtr; /* Pointer to next message */ - void *MsgPtr; /* Actual message */ - OS_MSG_SIZE MsgSize; /* Size of the message (in # bytes) */ - CPU_TS MsgTS; /* Time stamp of when message was sent */ -}; - - - - -struct os_msg_pool { /* OS_MSG POOL */ - OS_MSG *NextPtr; /* Pointer to next message */ - OS_MSG_QTY NbrFree; /* Number of messages available from this pool */ - OS_MSG_QTY NbrUsed; /* Current number of messages used */ -#if OS_CFG_DBG_EN > 0u - OS_MSG_QTY NbrUsedMax; /* Peak number of messages used */ -#endif -}; - - - -struct os_msg_q { /* OS_MSG_Q */ - OS_MSG *InPtr; /* Pointer to next OS_MSG to be inserted in the queue */ - OS_MSG *OutPtr; /* Pointer to next OS_MSG to be extracted from the queue */ - OS_MSG_QTY NbrEntriesSize; /* Maximum allowable number of entries in the queue */ - OS_MSG_QTY NbrEntries; /* Current number of entries in the queue */ -#if OS_CFG_DBG_EN > 0u - OS_MSG_QTY NbrEntriesMax; /* Peak number of entries in the queue */ -#endif -#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) - CPU_INT32U MsgQID; /* Unique ID for third-party debuggers and tracers. */ -#endif -}; - - -/* ------------------------------------------------------------------------------------------------------------------------- -* MUTUAL EXCLUSION SEMAPHORES -* -* Note(s) : See PEND OBJ Note #1'. ------------------------------------------------------------------------------------------------------------------------- -*/ - -struct os_mutex { /* Mutual Exclusion Semaphore */ - /* ------------------ GENERIC MEMBERS ------------------ */ -#if OS_OBJ_TYPE_REQ > 0u - OS_OBJ_TYPE Type; /* Should be set to OS_OBJ_TYPE_MUTEX */ -#endif -#if OS_CFG_DBG_EN > 0u - CPU_CHAR *NamePtr; /* Pointer to Mutex Name (NUL terminated ASCII) */ -#endif - OS_PEND_LIST PendList; /* List of tasks waiting on mutex */ -#if OS_CFG_DBG_EN > 0u - OS_MUTEX *DbgPrevPtr; - OS_MUTEX *DbgNextPtr; - CPU_CHAR *DbgNamePtr; -#endif - /* ------------------ SPECIFIC MEMBERS ------------------ */ - OS_MUTEX *MutexGrpNextPtr; - OS_TCB *OwnerTCBPtr; - OS_NESTING_CTR OwnerNestingCtr; /* Mutex is available when the counter is 0 */ - CPU_TS TS; -#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) - CPU_INT08U MutexID; /* Unique ID for third-party debuggers and tracers. */ -#endif -}; - - -/* ------------------------------------------------------------------------------------------------------------------------- -* MESSAGE QUEUES -* -* Note(s) : See PEND OBJ Note #1'. ------------------------------------------------------------------------------------------------------------------------- -*/ - -struct os_q { /* Message Queue */ - /* ------------------ GENERIC MEMBERS ------------------ */ -#if OS_OBJ_TYPE_REQ > 0u - OS_OBJ_TYPE Type; /* Should be set to OS_OBJ_TYPE_Q */ -#endif -#if OS_CFG_DBG_EN > 0u - CPU_CHAR *NamePtr; /* Pointer to Message Queue Name (NUL terminated ASCII) */ -#endif - OS_PEND_LIST PendList; /* List of tasks waiting on message queue */ -#if OS_CFG_DBG_EN > 0u - OS_Q *DbgPrevPtr; - OS_Q *DbgNextPtr; - CPU_CHAR *DbgNamePtr; -#endif - /* ------------------ SPECIFIC MEMBERS ------------------ */ - OS_MSG_Q MsgQ; /* List of messages */ -#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) - CPU_INT08U MsgQID; /* Unique ID for third-party debuggers and tracers. */ -#endif -}; - - -/* ------------------------------------------------------------------------------------------------------------------------- -* SEMAPHORES -* -* Note(s) : See PEND OBJ Note #1'. ------------------------------------------------------------------------------------------------------------------------- -*/ - -struct os_sem { /* Semaphore */ - /* ------------------ GENERIC MEMBERS ------------------ */ -#if OS_OBJ_TYPE_REQ > 0u - OS_OBJ_TYPE Type; /* Should be set to OS_OBJ_TYPE_SEM */ -#endif -#if OS_CFG_DBG_EN > 0u - CPU_CHAR *NamePtr; /* Pointer to Semaphore Name (NUL terminated ASCII) */ -#endif - OS_PEND_LIST PendList; /* List of tasks waiting on semaphore */ -#if OS_CFG_DBG_EN > 0u - OS_SEM *DbgPrevPtr; - OS_SEM *DbgNextPtr; - CPU_CHAR *DbgNamePtr; -#endif - /* ------------------ SPECIFIC MEMBERS ------------------ */ - OS_SEM_CTR Ctr; - CPU_TS TS; -#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) - CPU_INT08U SemID; /* Unique ID for third-party debuggers and tracers. */ -#endif -}; - - -/* ------------------------------------------------------------------------------------------------------------------------- -* TASK CONTROL BLOCK ------------------------------------------------------------------------------------------------------------------------- -*/ - -struct os_tcb { - CPU_STK *StkPtr; /* Pointer to current top of stack */ - - void *ExtPtr; /* Pointer to user definable data for TCB extension */ - -#if ((OS_CFG_DBG_EN > 0u) || (OS_CFG_STAT_TASK_STK_CHK_EN > 0u)) - CPU_STK *StkLimitPtr; /* Pointer used to set stack 'watermark' limit */ -#endif - - OS_TCB *NextPtr; /* Pointer to next TCB in the TCB list */ - OS_TCB *PrevPtr; /* Pointer to previous TCB in the TCB list */ - - OS_TCB *TickNextPtr; - OS_TCB *TickPrevPtr; - - OS_TICK_LIST *TickListPtr; /* Pointer to tick list if task is in a tick list */ - -#if OS_CFG_DBG_EN > 0u - CPU_CHAR *NamePtr; /* Pointer to task name */ -#endif - -#if ((OS_CFG_DBG_EN > 0u) || (OS_CFG_STAT_TASK_STK_CHK_EN > 0u)) - CPU_STK *StkBasePtr; /* Pointer to base address of stack */ -#endif - -#if defined(OS_CFG_TLS_TBL_SIZE) && (OS_CFG_TLS_TBL_SIZE > 0u) - OS_TLS TLS_Tbl[OS_CFG_TLS_TBL_SIZE]; -#endif - -#if OS_CFG_DBG_EN > 0u - OS_TASK_PTR TaskEntryAddr; /* Pointer to task entry point address */ - void *TaskEntryArg; /* Argument passed to task when it was created */ -#endif - - OS_PEND_DATA *PendDataTblPtr; /* Pointer to list containing objects pended on */ - OS_STATE PendOn; /* Indicates what task is pending on */ - OS_STATUS PendStatus; /* Pend status */ - - OS_STATE TaskState; /* See OS_TASK_STATE_xxx */ - OS_PRIO Prio; /* Task priority (0 == highest) */ -#if OS_CFG_MUTEX_EN > 0u - OS_PRIO BasePrio; /* Base priority (Not inherited) */ - OS_MUTEX *MutexGrpHeadPtr; /* Owned mutex group head pointer */ -#endif - -#if ((OS_CFG_DBG_EN > 0u) || (OS_CFG_STAT_TASK_STK_CHK_EN > 0u)) - CPU_STK_SIZE StkSize; /* Size of task stack (in number of stack elements) */ -#endif - OS_OPT Opt; /* Task options as passed by OSTaskCreate() */ - - OS_OBJ_QTY PendDataTblEntries; /* Size of array of objects to pend on */ - - CPU_TS TS; /* Timestamp */ -#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) - CPU_INT08U SemID; /* Unique ID for third-party debuggers and tracers. */ -#endif - OS_SEM_CTR SemCtr; /* Task specific semaphore counter */ - - /* DELAY / TIMEOUT */ - OS_TICK TickRemain; /* Number of ticks remaining (updated at by OS_TickTask() */ - OS_TICK TickCtrPrev; /* Used by OSTimeDlyXX() in PERIODIC mode */ - -#if OS_CFG_SCHED_ROUND_ROBIN_EN > 0u - OS_TICK TimeQuanta; - OS_TICK TimeQuantaCtr; -#endif - -#if OS_MSG_EN > 0u - void *MsgPtr; /* Message received */ - OS_MSG_SIZE MsgSize; -#endif - -#if OS_CFG_TASK_Q_EN > 0u - OS_MSG_Q MsgQ; /* Message queue associated with task */ -#if OS_CFG_TASK_PROFILE_EN > 0u - CPU_TS MsgQPendTime; /* Time it took for signal to be received */ - CPU_TS MsgQPendTimeMax; /* Max amount of time it took for signal to be received */ -#endif -#endif - -#if OS_CFG_TASK_REG_TBL_SIZE > 0u - OS_REG RegTbl[OS_CFG_TASK_REG_TBL_SIZE]; /* Task specific registers */ -#endif - -#if OS_CFG_FLAG_EN > 0u - OS_FLAGS FlagsPend; /* Event flag(s) to wait on */ - OS_FLAGS FlagsRdy; /* Event flags that made task ready to run */ - OS_OPT FlagsOpt; /* Options (See OS_OPT_FLAG_xxx) */ -#endif - -#if OS_CFG_TASK_SUSPEND_EN > 0u - OS_NESTING_CTR SuspendCtr; /* Nesting counter for OSTaskSuspend() */ -#endif - -#if OS_CFG_TASK_PROFILE_EN > 0u - OS_CPU_USAGE CPUUsage; /* CPU Usage of task (0.00-100.00%) */ - OS_CPU_USAGE CPUUsageMax; /* CPU Usage of task (0.00-100.00%) - Peak */ - OS_CTX_SW_CTR CtxSwCtr; /* Number of time the task was switched in */ - CPU_TS CyclesDelta; /* value of OS_TS_GET() - .CyclesStart */ - CPU_TS CyclesStart; /* Snapshot of cycle counter at start of task resumption */ - OS_CYCLES CyclesTotal; /* Total number of # of cycles the task has been running */ - OS_CYCLES CyclesTotalPrev; /* Snapshot of previous # of cycles */ - - CPU_TS SemPendTime; /* Time it took for signal to be received */ - CPU_TS SemPendTimeMax; /* Max amount of time it took for signal to be received */ -#endif - -#if OS_CFG_STAT_TASK_STK_CHK_EN > 0u - CPU_STK_SIZE StkUsed; /* Number of stack elements used from the stack */ - CPU_STK_SIZE StkFree; /* Number of stack elements free on the stack */ -#endif - -#ifdef CPU_CFG_INT_DIS_MEAS_EN - CPU_TS IntDisTimeMax; /* Maximum interrupt disable time */ -#endif -#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u - CPU_TS SchedLockTimeMax; /* Maximum scheduler lock time */ -#endif - -#if OS_CFG_DBG_EN > 0u - OS_TCB *DbgPrevPtr; - OS_TCB *DbgNextPtr; - CPU_CHAR *DbgNamePtr; -#endif -#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) - CPU_INT08U TaskID; /* Unique ID for third-party debuggers and tracers. */ -#endif -}; - - -/* ------------------------------------------------------------------------------------------------------------------------- -* TICK DATA TYPE ------------------------------------------------------------------------------------------------------------------------- -*/ - -struct os_tick_list { - OS_TCB *TCB_Ptr; /* Pointer to list of tasks in tick list */ -#if OS_CFG_DBG_EN > 0u - OS_OBJ_QTY NbrEntries; /* Current number of entries in the tick list */ - OS_OBJ_QTY NbrUpdated; /* Number of entries updated */ -#endif -}; - - -/* ------------------------------------------------------------------------------------------------------------------------- -* TIMER DATA TYPES ------------------------------------------------------------------------------------------------------------------------- -*/ - -struct os_tmr { -#if OS_OBJ_TYPE_REQ > 0u - OS_OBJ_TYPE Type; -#endif -#if OS_CFG_DBG_EN > 0u - CPU_CHAR *NamePtr; /* Name to give the timer */ -#endif - OS_TMR_CALLBACK_PTR CallbackPtr; /* Function to call when timer expires */ - void *CallbackPtrArg; /* Argument to pass to function when timer expires */ - OS_TMR *NextPtr; /* Double link list pointers */ - OS_TMR *PrevPtr; - OS_TICK Remain; /* Amount of time remaining before timer expires */ - OS_TICK Dly; /* Delay before start of repeat */ - OS_TICK Period; /* Period to repeat timer */ - OS_OPT Opt; /* Options (see OS_OPT_TMR_xxx) */ - OS_STATE State; -#if OS_CFG_DBG_EN > 0u - OS_TMR *DbgPrevPtr; - OS_TMR *DbgNextPtr; -#endif -}; - - -/* -************************************************************************************************************************ -************************************************************************************************************************ -* G L O B A L V A R I A B L E S -************************************************************************************************************************ -************************************************************************************************************************ -*/ - -#if OS_CFG_APP_HOOKS_EN > 0u -OS_EXT OS_APP_HOOK_TCB OS_AppTaskCreateHookPtr; /* Application hooks */ -OS_EXT OS_APP_HOOK_TCB OS_AppTaskDelHookPtr; -OS_EXT OS_APP_HOOK_TCB OS_AppTaskReturnHookPtr; - -OS_EXT OS_APP_HOOK_VOID OS_AppIdleTaskHookPtr; -OS_EXT OS_APP_HOOK_VOID OS_AppStatTaskHookPtr; -OS_EXT OS_APP_HOOK_VOID OS_AppTaskSwHookPtr; -OS_EXT OS_APP_HOOK_VOID OS_AppTimeTickHookPtr; -#endif - - /* IDLE TASK -------------------------------- */ -OS_EXT OS_IDLE_CTR OSIdleTaskCtr; -OS_EXT OS_TCB OSIdleTaskTCB; - - /* MISCELLANEOUS ---------------------------- */ -OS_EXT OS_NESTING_CTR OSIntNestingCtr; /* Interrupt nesting level */ -#ifdef CPU_CFG_INT_DIS_MEAS_EN -OS_EXT CPU_TS OSIntDisTimeMax; /* Overall interrupt disable time */ -#endif - -OS_EXT OS_STATE OSRunning; /* Flag indicating that kernel is running */ - - - /* ISR HANDLER TASK ------------------------- */ -#if OS_CFG_ISR_POST_DEFERRED_EN > 0u -OS_EXT OS_INT_Q *OSIntQInPtr; -OS_EXT OS_INT_Q *OSIntQOutPtr; -OS_EXT OS_OBJ_QTY OSIntQNbrEntries; -OS_EXT OS_OBJ_QTY OSIntQNbrEntriesMax; -OS_EXT OS_OBJ_QTY OSIntQOvfCtr; -OS_EXT OS_TCB OSIntQTaskTCB; -OS_EXT CPU_TS OSIntQTaskTimeMax; -#endif - - /* FLAGS ------------------------------------ */ -#if OS_CFG_FLAG_EN > 0u -#if OS_CFG_DBG_EN > 0u -OS_EXT OS_FLAG_GRP *OSFlagDbgListPtr; -#endif -OS_EXT OS_OBJ_QTY OSFlagQty; -#endif - - /* MEMORY MANAGEMENT ------------------------ */ -#if OS_CFG_MEM_EN > 0u -#if OS_CFG_DBG_EN > 0u -OS_EXT OS_MEM *OSMemDbgListPtr; -#endif -OS_EXT OS_OBJ_QTY OSMemQty; /* Number of memory partitions created */ -#endif - - /* OS_MSG POOL ------------------------------ */ -#if OS_MSG_EN > 0u -OS_EXT OS_MSG_POOL OSMsgPool; /* Pool of OS_MSG */ -#endif - - /* MUTEX MANAGEMENT ------------------------- */ -#if OS_CFG_MUTEX_EN > 0u -#if OS_CFG_DBG_EN > 0u -OS_EXT OS_MUTEX *OSMutexDbgListPtr; -#endif -OS_EXT OS_OBJ_QTY OSMutexQty; /* Number of mutexes created */ -#endif - - /* PRIORITIES ------------------------------- */ -OS_EXT OS_PRIO OSPrioCur; /* Priority of current task */ -OS_EXT OS_PRIO OSPrioHighRdy; /* Priority of highest priority task */ -OS_EXT OS_PRIO OSPrioSaved; /* Saved priority level when Post Deferred */ -extern CPU_DATA OSPrioTbl[OS_PRIO_TBL_SIZE]; - - /* QUEUES ----------------------------------- */ -#if OS_CFG_Q_EN > 0u -#if OS_CFG_DBG_EN > 0u -OS_EXT OS_Q *OSQDbgListPtr; -#endif -OS_EXT OS_OBJ_QTY OSQQty; /* Number of message queues created */ -#endif - - - - /* READY LIST ------------------------------- */ -OS_EXT OS_RDY_LIST OSRdyList[OS_CFG_PRIO_MAX]; /* Table of tasks ready to run */ - - -#ifdef OS_SAFETY_CRITICAL_IEC61508 -OS_EXT CPU_BOOLEAN OSSafetyCriticalStartFlag; /* Flag indicating that all init. done */ -#endif - /* SCHEDULER -------------------------------- */ -#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u -OS_EXT CPU_TS_TMR OSSchedLockTimeBegin; /* Scheduler lock time measurement */ -OS_EXT CPU_TS_TMR OSSchedLockTimeMax; -OS_EXT CPU_TS_TMR OSSchedLockTimeMaxCur; -#endif - -OS_EXT OS_NESTING_CTR OSSchedLockNestingCtr; /* Lock nesting level */ -#if OS_CFG_SCHED_ROUND_ROBIN_EN > 0u -OS_EXT OS_TICK OSSchedRoundRobinDfltTimeQuanta; -OS_EXT CPU_BOOLEAN OSSchedRoundRobinEn; /* Enable/Disable round-robin scheduling */ -#endif - /* SEMAPHORES ------------------------------- */ -#if OS_CFG_SEM_EN > 0u -#if OS_CFG_DBG_EN > 0u -OS_EXT OS_SEM *OSSemDbgListPtr; -#endif -OS_EXT OS_OBJ_QTY OSSemQty; /* Number of semaphores created */ -#endif - - /* STATISTICS ------------------------------- */ -#if OS_CFG_STAT_TASK_EN > 0u -OS_EXT CPU_BOOLEAN OSStatResetFlag; /* Force the reset of the computed statistics */ -OS_EXT OS_CPU_USAGE OSStatTaskCPUUsage; /* CPU Usage in % */ -OS_EXT OS_CPU_USAGE OSStatTaskCPUUsageMax; /* CPU Usage in % (Peak) */ -OS_EXT OS_TICK OSStatTaskCtr; -OS_EXT OS_TICK OSStatTaskCtrMax; -OS_EXT OS_TICK OSStatTaskCtrRun; -OS_EXT CPU_BOOLEAN OSStatTaskRdy; -OS_EXT OS_TCB OSStatTaskTCB; -OS_EXT CPU_TS OSStatTaskTimeMax; -#endif - - /* TASKS ------------------------------------ */ -OS_EXT OS_CTX_SW_CTR OSTaskCtxSwCtr; /* Number of context switches */ -#if OS_CFG_DBG_EN > 0u -OS_EXT OS_TCB *OSTaskDbgListPtr; -#endif -OS_EXT OS_OBJ_QTY OSTaskQty; /* Number of tasks created */ - -#if OS_CFG_TASK_REG_TBL_SIZE > 0u -OS_EXT OS_REG_ID OSTaskRegNextAvailID; /* Next available Task Register ID */ -#endif - - /* TICK TASK -------------------------------- */ -OS_EXT OS_TICK OSTickCtr; /* Cnts the #ticks since startup or last set */ -OS_EXT OS_TCB OSTickTaskTCB; -OS_EXT CPU_TS OSTickTaskTimeMax; -OS_EXT OS_TICK_LIST OSTickListDly; -OS_EXT OS_TICK_LIST OSTickListTimeout; - - - -#if OS_CFG_TMR_EN > 0u /* TIMERS ----------------------------------- */ -#if OS_CFG_DBG_EN > 0u -OS_EXT OS_TMR *OSTmrDbgListPtr; -#endif -OS_EXT OS_OBJ_QTY OSTmrListEntries; /* Doubly-linked list of timers */ -OS_EXT OS_TMR *OSTmrListPtr; -#if OS_CFG_MUTEX_EN > 0u /* Use a Mutex (if available) to protect tmrs */ -OS_EXT OS_MUTEX OSTmrMutex; -#endif -OS_EXT OS_OBJ_QTY OSTmrQty; /* Number of timers created */ -OS_EXT OS_TCB OSTmrTaskTCB; /* TCB of timer task */ -OS_EXT CPU_TS OSTmrTaskTimeMax; -OS_EXT OS_TICK OSTmrTickCtr; /* Current time for the timers */ -OS_EXT OS_CTR OSTmrUpdateCnt; /* Counter for updating timers */ -OS_EXT OS_CTR OSTmrUpdateCtr; -#endif - - - - - /* TCBs ------------------------------------- */ -OS_EXT OS_TCB *OSTCBCurPtr; /* Pointer to currently running TCB */ -OS_EXT OS_TCB *OSTCBHighRdyPtr; /* Pointer to highest priority TCB */ - - -/* -************************************************************************************************************************ -************************************************************************************************************************ -* E X T E R N A L S -************************************************************************************************************************ -************************************************************************************************************************ -*/ - -extern CPU_STK * const OSCfg_IdleTaskStkBasePtr; -extern CPU_STK_SIZE const OSCfg_IdleTaskStkLimit; -extern CPU_STK_SIZE const OSCfg_IdleTaskStkSize; -extern CPU_INT32U const OSCfg_IdleTaskStkSizeRAM; - -extern OS_INT_Q * const OSCfg_IntQBasePtr; -extern OS_OBJ_QTY const OSCfg_IntQSize; -extern CPU_INT32U const OSCfg_IntQSizeRAM; -extern CPU_STK * const OSCfg_IntQTaskStkBasePtr; -extern CPU_STK_SIZE const OSCfg_IntQTaskStkLimit; -extern CPU_STK_SIZE const OSCfg_IntQTaskStkSize; -extern CPU_INT32U const OSCfg_IntQTaskStkSizeRAM; - -extern CPU_STK * const OSCfg_ISRStkBasePtr; -extern CPU_STK_SIZE const OSCfg_ISRStkSize; -extern CPU_INT32U const OSCfg_ISRStkSizeRAM; - -extern OS_MSG_SIZE const OSCfg_MsgPoolSize; -extern CPU_INT32U const OSCfg_MsgPoolSizeRAM; -extern OS_MSG * const OSCfg_MsgPoolBasePtr; - -extern OS_PRIO const OSCfg_StatTaskPrio; -extern OS_RATE_HZ const OSCfg_StatTaskRate_Hz; -extern CPU_STK * const OSCfg_StatTaskStkBasePtr; -extern CPU_STK_SIZE const OSCfg_StatTaskStkLimit; -extern CPU_STK_SIZE const OSCfg_StatTaskStkSize; -extern CPU_INT32U const OSCfg_StatTaskStkSizeRAM; - -extern CPU_STK_SIZE const OSCfg_StkSizeMin; - -extern OS_RATE_HZ const OSCfg_TickRate_Hz; -extern OS_PRIO const OSCfg_TickTaskPrio; -extern CPU_STK * const OSCfg_TickTaskStkBasePtr; -extern CPU_STK_SIZE const OSCfg_TickTaskStkLimit; -extern CPU_STK_SIZE const OSCfg_TickTaskStkSize; -extern CPU_INT32U const OSCfg_TickTaskStkSizeRAM; - -extern OS_PRIO const OSCfg_TmrTaskPrio; -extern OS_RATE_HZ const OSCfg_TmrTaskRate_Hz; -extern CPU_STK * const OSCfg_TmrTaskStkBasePtr; -extern CPU_STK_SIZE const OSCfg_TmrTaskStkLimit; -extern CPU_STK_SIZE const OSCfg_TmrTaskStkSize; -extern CPU_INT32U const OSCfg_TmrTaskStkSizeRAM; - - -extern CPU_STK OSCfg_IdleTaskStk[]; - -#if (OS_CFG_ISR_POST_DEFERRED_EN > 0u) -extern CPU_STK OSCfg_IntQTaskStk[]; -extern OS_INT_Q OSCfg_IntQ[]; -#endif - -extern CPU_STK OSCfg_ISRStk[]; - -#if (OS_MSG_EN > 0u) -extern OS_MSG OSCfg_MsgPool[]; -#endif - -#if (OS_CFG_STAT_TASK_EN > 0u) -extern CPU_STK OSCfg_StatTaskStk[]; -#endif - -extern CPU_STK OSCfg_TickTaskStk[]; - -#if (OS_CFG_TMR_EN > 0u) -extern CPU_STK OSCfg_TmrTaskStk[]; -#endif - /****** EVENT FLAGS *******/ DECLARE_FAKE_VOID_FUNC(OSFlagCreate, OS_FLAG_GRP*, CPU_CHAR*, OS_FLAGS, OS_ERR*); @@ -1549,6 +211,3 @@ DECLARE_FAKE_VALUE_FUNC(CPU_STK*, OSTaskStkInit, OS_TASK_PTR, void*, CPU_STK*, C DECLARE_FAKE_VOID_FUNC(OSTaskSwHook); DECLARE_FAKE_VOID_FUNC(OSTimeTickHook); - -#endif -// #endif \ No newline at end of file From 0257ebcec98a150c6a2b4d555c60add1462e0cf8 Mon Sep 17 00:00:00 2001 From: diyarajon Date: Sat, 2 Mar 2024 15:07:28 -0600 Subject: [PATCH 54/57] Created cpu core function mocks and deleted defines by using them from original file --- Tests/UnitTests/Mocks/RTOS/cpu_core.c | 8 + Tests/UnitTests/Mocks/RTOS/cpu_core.h | 492 +------------------------- Tests/UnitTests/Mocks/RTOS/os.h | 2 + 3 files changed, 14 insertions(+), 488 deletions(-) create mode 100644 Tests/UnitTests/Mocks/RTOS/cpu_core.c diff --git a/Tests/UnitTests/Mocks/RTOS/cpu_core.c b/Tests/UnitTests/Mocks/RTOS/cpu_core.c new file mode 100644 index 000000000..31845f3ee --- /dev/null +++ b/Tests/UnitTests/Mocks/RTOS/cpu_core.c @@ -0,0 +1,8 @@ +///////////////////////////////////////////// +////// MOCK ////// +///////////////////////////////////////////// + +#include "cpu_core.h" +#include "fff.h" + +DEFINE_FAKE_VOID_FUNC(CPU_Init); \ No newline at end of file diff --git a/Tests/UnitTests/Mocks/RTOS/cpu_core.h b/Tests/UnitTests/Mocks/RTOS/cpu_core.h index 2ca3efb74..f2904b17d 100644 --- a/Tests/UnitTests/Mocks/RTOS/cpu_core.h +++ b/Tests/UnitTests/Mocks/RTOS/cpu_core.h @@ -1,495 +1,11 @@ ///////////////////////////////////////////// ////// MOCK ////// ///////////////////////////////////////////// - -/* -********************************************************************************************************* -* uC/CPU -* CPU CONFIGURATION & PORT LAYER -* -* (c) Copyright 2004-2015; Micrium, Inc.; Weston, FL -* -* All rights reserved. Protected by international copyright laws. -* -* uC/CPU is provided in source form to registered licensees ONLY. It is -* illegal to distribute this source code to any third party unless you receive -* written permission by an authorized Micrium representative. Knowledge of -* the source code may NOT be used to develop a similar product. -* -* Please help us continue to provide the Embedded community with the finest -* software available. Your honesty is greatly appreciated. -* -* You can find our product's user manual, API reference, release notes and -* more information at https://doc.micrium.com. -* You can contact us at www.micrium.com. -********************************************************************************************************* -*/ - -/* -********************************************************************************************************* -* -* CORE CPU MODULE -* -* Filename : cpu_core.h -* Version : V1.30.02 -* Programmer(s) : SR -* ITJ -********************************************************************************************************* -* Note(s) : (1) Assumes the following versions (or more recent) of software modules are included in -* the project build : -* -* (a) uC/LIB V1.35.00 -********************************************************************************************************* -*/ - - -/* -********************************************************************************************************* -* MODULE -* -* Note(s) : (1) This core CPU header file is protected from multiple pre-processor inclusion through use of -* the core CPU module present pre-processor macro definition. -********************************************************************************************************* -*/ - -#ifndef CPU_CORE_MODULE_PRESENT /* See Note #1. */ -#define CPU_CORE_MODULE_PRESENT - - -/* -********************************************************************************************************* -* EXTERNS -********************************************************************************************************* -*/ - -#ifdef CPU_CORE_MODULE -#define CPU_CORE_EXT -#else -#define CPU_CORE_EXT extern -#endif - - -/* -********************************************************************************************************* -* INCLUDE FILES -* -* Note(s) : (1) CPU-configuration software files are located in the following directories : -* -* (a) \\cpu_cfg.h -* -* (b) (1) \\cpu_*.* -* (2) \\\\cpu*.* -* -* where -* directory path for Your Product's Application -* directory path for common CPU-compiler software -* directory name for specific processor (CPU) -* directory name for specific compiler -* -* (2) NO compiler-supplied standard library functions SHOULD be used. -* -* (a) Standard library functions are implemented in the custom library module(s) : -* -* \\lib_*.* -* -* where -* directory path for custom library software -* -* (3) Compiler MUST be configured to include as additional include path directories : -* -* (a) '\\' directory See Note #1a -* -* (b) (1) '\\' directory See Note #1b1 -* (2) '\\\\' directory See Note #1b2 -* -* (c) '\\' directory See Note #2a -********************************************************************************************************* -*/ - +#pragma once +#include_next "cpu_core.h" #include -//#include #include -#if (CPU_CFG_NAME_EN == DEF_ENABLED) -// #include -// #include -#endif - - -/* -********************************************************************************************************* -* CPU CONFIGURATION -* -* Note(s) : (1) The following pre-processor directives correctly configure CPU parameters. DO NOT MODIFY. -* -* (2) CPU timestamp timer feature is required for : -* -* (a) CPU timestamps -* (b) CPU interrupts disabled time measurement -* -* See also 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #1' -* & 'cpu_cfg.h CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION Note #1'. -********************************************************************************************************* -*/ - -#ifdef CPU_CFG_TS_EN -#undef CPU_CFG_TS_EN -#endif - - -#if ((CPU_CFG_TS_32_EN == DEF_ENABLED) || \ - (CPU_CFG_TS_64_EN == DEF_ENABLED)) -#define CPU_CFG_TS_EN DEF_ENABLED -#else -#define CPU_CFG_TS_EN DEF_DISABLED -#endif - -#if ((CPU_CFG_TS_EN == DEF_ENABLED) || \ -(defined(CPU_CFG_INT_DIS_MEAS_EN))) -#define CPU_CFG_TS_TMR_EN DEF_ENABLED -#else -#define CPU_CFG_TS_TMR_EN DEF_DISABLED -#endif - -/* -********************************************************************************************************* -* CACHE CONFIGURATION -* -* Note(s) : (1) The following pre-processor directives correctly configure CACHE parameters. DO NOT MODIFY. -* -********************************************************************************************************** -*/ - -#ifndef CPU_CFG_CACHE_MGMT_EN -#define CPU_CFG_CACHE_MGMT_EN DEF_DISABLED -#endif - - -/* -********************************************************************************************************* -* DEFINES -********************************************************************************************************* -*/ - -#define CPU_TIME_MEAS_NBR_MIN 1u -#define CPU_TIME_MEAS_NBR_MAX 128u - - -/* -********************************************************************************************************* -* DATA TYPES -********************************************************************************************************* -*/ - - -/* -********************************************************************************************************* -* CPU ERROR CODES -********************************************************************************************************* -*/ - -typedef enum cpu_err { - - CPU_ERR_NONE = 0u, - CPU_ERR_NULL_PTR = 10u, - - CPU_ERR_NAME_SIZE = 1000u, - - CPU_ERR_TS_FREQ_INVALID = 2000u - -} CPU_ERR; - - -/* -********************************************************************************************************* -* CPU TIMESTAMP DATA TYPES -* -* Note(s) : (1) CPU timestamp timer data type defined to the binary-multiple of 8-bit octets as configured -* by 'CPU_CFG_TS_TMR_SIZE' (see 'cpu_cfg.h CPU TIMESTAMP CONFIGURATION Note #2'). -********************************************************************************************************* -*/ - -typedef CPU_INT32U CPU_TS32; -typedef CPU_INT64U CPU_TS64; - -typedef CPU_TS32 CPU_TS; /* Req'd for backwards-compatibility. */ - - -#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) /* CPU ts tmr defined to cfg'd word size (see Note #1). */ -#if (CPU_CFG_TS_TMR_SIZE == CPU_WORD_SIZE_08) -typedef CPU_INT08U CPU_TS_TMR; -#elif (CPU_CFG_TS_TMR_SIZE == CPU_WORD_SIZE_16) -typedef CPU_INT16U CPU_TS_TMR; -#elif (CPU_CFG_TS_TMR_SIZE == CPU_WORD_SIZE_64) -typedef CPU_INT64U CPU_TS_TMR; -#else /* CPU ts tmr dflt size = 32-bits. */ -typedef CPU_INT32U CPU_TS_TMR; -#endif -#endif - - -/* -********************************************************************************************************* -* CPU TIMESTAMP TIMER FREQUENCY DATA TYPE -********************************************************************************************************* -*/ - -typedef CPU_INT32U CPU_TS_TMR_FREQ; - - -/* -********************************************************************************************************* -* GLOBAL VARIABLES -********************************************************************************************************* -*/ - -#if (CPU_CFG_NAME_EN == DEF_ENABLED) -CPU_CORE_EXT CPU_CHAR CPU_Name[CPU_CFG_NAME_SIZE]; /* CPU host name. */ -#endif - - -#if ((CPU_CFG_TS_32_EN == DEF_ENABLED) && \ - (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_32)) -CPU_CORE_EXT CPU_TS32 CPU_TS_32_Accum; /* 32-bit accum'd ts (in ts tmr cnts). */ -CPU_CORE_EXT CPU_TS_TMR CPU_TS_32_TmrPrev; /* 32-bit ts prev tmr (in ts tmr cnts). */ -#endif - -#if ((CPU_CFG_TS_64_EN == DEF_ENABLED) && \ - (CPU_CFG_TS_TMR_SIZE < CPU_WORD_SIZE_64)) -CPU_CORE_EXT CPU_TS64 CPU_TS_64_Accum; /* 64-bit accum'd ts (in ts tmr cnts). */ -CPU_CORE_EXT CPU_TS_TMR CPU_TS_64_TmrPrev; /* 64-bit ts prev tmr (in ts tmr cnts). */ -#endif - -#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED) -CPU_CORE_EXT CPU_TS_TMR_FREQ CPU_TS_TmrFreq_Hz; /* CPU ts tmr freq (in Hz). */ -#endif - - -#ifdef CPU_CFG_INT_DIS_MEAS_EN -CPU_CORE_EXT CPU_INT16U CPU_IntDisMeasCtr; /* Nbr tot ints dis'd ctr. */ -CPU_CORE_EXT CPU_INT16U CPU_IntDisNestCtr; /* Nbr nested ints dis'd ctr. */ - /* Ints dis'd time (in ts tmr cnts) : ... */ -CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasStart_cnts; /* ... start time. */ -CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasStop_cnts; /* ... stop time. */ -CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasOvrhd_cnts; /* ... time meas ovrhd. */ -CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasMaxCur_cnts; /* ... resetable max time dis'd. */ -CPU_CORE_EXT CPU_TS_TMR CPU_IntDisMeasMax_cnts; /* ... non-resetable max time dis'd. */ -#endif - - -/* -********************************************************************************************************* -* MACRO'S -********************************************************************************************************* -*/ - -/* -********************************************************************************************************* -* CPU_SW_EXCEPTION() -* -* Description : Trap unrecoverable software exception. -* -* Argument(s) : err_rtn_val Error type &/or value of the calling function to return (see Note #2b). -* -* Return(s) : none. -* -* Caller(s) : various. -* -* Note(s) : (1) CPU_SW_EXCEPTION() deadlocks the current code execution -- whether multi-tasked/ -* -processed/-threaded or single-threaded -- when the current code execution cannot -* gracefully recover or report a fault or exception condition. -* -* Example CPU_SW_EXCEPTION() call : -* -* void Fnct (CPU_ERR *p_err) -* { -* : -* -* if (p_err == (CPU_ERR *)0) { If 'p_err' NULL, cannot return error ... -* CPU_SW_EXCEPTION(;); ... so trap invalid argument exception. -* } -* -* : -* } -* -* See also 'cpu_core.c CPU_SW_Exception() Note #1'. -* -* (2) (a) CPU_SW_EXCEPTION() MAY be developer-implemented to output &/or handle any error or -* exception conditions; but since CPU_SW_EXCEPTION() is intended to trap unrecoverable -* software conditions, it is recommended that developer-implemented versions prevent -* execution of any code following calls to CPU_SW_EXCEPTION() by deadlocking the code -* (see Note #1). -* -* Example CPU_SW_EXCEPTION() : -* -* #define CPU_SW_EXCEPTION(err_rtn_val) do { \ -* Log(__FILE__, __LINE__); \ -* CPU_SW_Exception(); \ -* } while (0) -* -* (b) (1) However, if execution of code following calls to CPU_SW_EXCEPTION() is required -* (e.g. for automated testing); it is recommended that the last statement in -* developer-implemented versions be to return from the current function to prevent -* possible software exception(s) in the current function from triggering CPU &/or -* hardware exception(s). -* -* Example CPU_SW_EXCEPTION() : -* -* #define CPU_SW_EXCEPTION(err_rtn_val) do { \ -* Log(__FILE__, __LINE__); \ -* return err_rtn_val; \ -* } while (0) -* -* (A) Note that 'err_rtn_val' in the return statement MUST NOT be enclosed in -* parentheses. This allows CPU_SW_EXCEPTION() to return from functions that -* return 'void', i.e. NO return type or value (see also Note #2b2A). -* -* (2) In order for CPU_SW_EXCEPTION() to return from functions with various return -* types/values, each caller function MUST pass an appropriate error return type -* & value to CPU_SW_EXCEPTION(). -* -* (A) Note that CPU_SW_EXCEPTION() MUST NOT be passed any return type or value -* for functions that return 'void', i.e. NO return type or value; but SHOULD -* instead be passed a single semicolon. This prevents possible compiler -* warnings that CPU_SW_EXCEPTION() is passed too few arguments. However, -* the compiler may warn that CPU_SW_EXCEPTION() does NOT prevent creating -* null statements on lines with NO other code statements. -* -* Example CPU_SW_EXCEPTION() calls : -* -* void Fnct (CPU_ERR *p_err) -* { -* : -* -* if (p_err == (CPU_ERR *)0) { -* CPU_SW_EXCEPTION(;); Exception macro returns NO value -* } (see Note #2b2A) -* -* : -* } -* -* CPU_BOOLEAN Fnct (CPU_ERR *p_err) -* { -* : -* -* if (p_err == (CPU_ERR *)0) { -* CPU_SW_EXCEPTION(DEF_FAIL); Exception macro returns 'DEF_FAIL' -* } -* -* : -* } -* -* OBJ *Fnct (CPU_ERR *p_err) -* { -* : -* -* if (p_err == (CPU_ERR *)0) { -* CPU_SW_EXCEPTION((OBJ *)0); Exception macro returns NULL 'OBJ *' -* } -* -* : -* } -* -********************************************************************************************************* -*/ - -#ifndef CPU_SW_EXCEPTION /* See Note #2. */ -#define CPU_SW_EXCEPTION(err_rtn_val) do { \ - CPU_SW_Exception(); \ - } while (0) -#endif - - -/* -********************************************************************************************************* -* CPU_VAL_UNUSED() -* -* Description : -* -* Argument(s) : none. -* -* Return(s) : none. -* -* Caller(s) : #### various. -* -* Note(s) : none. -********************************************************************************************************* -*/ - - -#define CPU_VAL_UNUSED(val) ((void)&(val)); - - -#define CPU_VAL_IGNORED(val) CPU_VAL_UNUSED(val) - - -/* -********************************************************************************************************* -* CPU_TYPE_CREATE() -* -* Description : Creates a generic type value. -* -* Argument(s) : char_1 1st ASCII character to create generic type value. -* -* char_2 2nd ASCII character to create generic type value. -* -* char_3 3rd ASCII character to create generic type value. -* -* char_4 4th ASCII character to create generic type value. -* -* Return(s) : 32-bit generic type value. -* -* Caller(s) : various. -* -* Note(s) : (1) (a) Generic type values should be #define'd with large, non-trivial values to trap -* & discard invalid/corrupted objects based on type value. -* -* In other words, by assigning large, non-trivial values to valid objects' type -* fields; the likelihood that an object with an unassigned &/or corrupted type -* field will contain a value is highly improbable & therefore the object itself -* will be trapped as invalid. -* -* (b) (1) CPU_TYPE_CREATE() creates a 32-bit type value from four values. -* -* (2) Ideally, generic type values SHOULD be created from 'CPU_CHAR' characters to -* represent ASCII string abbreviations of the specific object types. Memory -* displays of object type values will display the specific object types with -* their chosen ASCII names. -* -* Examples : -* -* #define FILE_TYPE CPU_TYPE_CREATE('F', 'I', 'L', 'E') -* #define BUF_TYPE CPU_TYPE_CREATE('B', 'U', 'F', ' ') -********************************************************************************************************* -*/ - -#if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG) -#define CPU_TYPE_CREATE(char_1, char_2, char_3, char_4) (((CPU_INT32U)((CPU_INT08U)(char_1)) << (3u * DEF_OCTET_NBR_BITS)) | \ - ((CPU_INT32U)((CPU_INT08U)(char_2)) << (2u * DEF_OCTET_NBR_BITS)) | \ - ((CPU_INT32U)((CPU_INT08U)(char_3)) << (1u * DEF_OCTET_NBR_BITS)) | \ - ((CPU_INT32U)((CPU_INT08U)(char_4)))) - -#else - -#if ((CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_64) || \ - (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32)) -#define CPU_TYPE_CREATE(char_1, char_2, char_3, char_4) (((CPU_INT32U)((CPU_INT08U)(char_1))) | \ - ((CPU_INT32U)((CPU_INT08U)(char_2)) << (1u * DEF_OCTET_NBR_BITS)) | \ - ((CPU_INT32U)((CPU_INT08U)(char_3)) << (2u * DEF_OCTET_NBR_BITS)) | \ - ((CPU_INT32U)((CPU_INT08U)(char_4)) << (3u * DEF_OCTET_NBR_BITS))) - - -#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16) -#define CPU_TYPE_CREATE(char_1, char_2, char_3, char_4) (((CPU_INT32U)((CPU_INT08U)(char_1)) << (2u * DEF_OCTET_NBR_BITS)) | \ - ((CPU_INT32U)((CPU_INT08U)(char_2)) << (3u * DEF_OCTET_NBR_BITS)) | \ - ((CPU_INT32U)((CPU_INT08U)(char_3))) | \ - ((CPU_INT32U)((CPU_INT08U)(char_4)) << (1u * DEF_OCTET_NBR_BITS))) +#include "fff.h" -#else /* Dflt CPU_WORD_SIZE_08. */ -#define CPU_TYPE_CREATE(char_1, char_2, char_3, char_4) (((CPU_INT32U)((CPU_INT08U)(char_1)) << (3u * DEF_OCTET_NBR_BITS)) | \ - ((CPU_INT32U)((CPU_INT08U)(char_2)) << (2u * DEF_OCTET_NBR_BITS)) | \ - ((CPU_INT32U)((CPU_INT08U)(char_3)) << (1u * DEF_OCTET_NBR_BITS)) | \ - ((CPU_INT32U)((CPU_INT08U)(char_4)))) -#endif -#endif -#endif \ No newline at end of file +DECLARE_FAKE_VOID_FUNC(CPU_Init); diff --git a/Tests/UnitTests/Mocks/RTOS/os.h b/Tests/UnitTests/Mocks/RTOS/os.h index 9f1def980..1b7906aef 100644 --- a/Tests/UnitTests/Mocks/RTOS/os.h +++ b/Tests/UnitTests/Mocks/RTOS/os.h @@ -2,6 +2,8 @@ ////// MOCK ////// ///////////////////////////////////////////// +#pragma once + /* ************************************************************************************************************************ * uC/OS-III VERSION NUMBER From e967b8da299c03a6658970a75ef9edd11eb81b2b Mon Sep 17 00:00:00 2001 From: diyarajon Date: Sat, 2 Mar 2024 15:19:27 -0600 Subject: [PATCH 55/57] re-add workspace --- .vscode/LHR.code-workspace | 296 +++++++++++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 .vscode/LHR.code-workspace diff --git a/.vscode/LHR.code-workspace b/.vscode/LHR.code-workspace new file mode 100644 index 000000000..9e5310e01 --- /dev/null +++ b/.vscode/LHR.code-workspace @@ -0,0 +1,296 @@ +{ + "folders": [ + { + "path": "../" + }, + { + "path": "../../BPS" + } + ], + "settings": { + "liveServer.settings.multiRootWorkspaceName": "renode", + "terminal.integrated.defaultProfile.linux": "bash", + "terminal.integrated.profiles.linux": { + "bash": { + "path": "bash", + "icon": "terminal-bash", + "args": ["-i"] + }, + }, + }, + "tasks": { + "version": "2.0.0", + "tasks": [ + { + "label": "Build Controls", + "type": "process", + "command": "make", + "args": [ + "${input:target}", + "TEST=${input:test}", + "DEBUG=${input:debug}" + ], + "presentation": { + "echo": false, + "reveal": "always", + "panel": "dedicated", + "focus": true, + "clear": true, + "group": "build" + }, + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] + }, + { + "label": "Start Renode", + "type": "shell", + "command": "${workspaceFolder:Controls}/Scripts/start_renode.sh", + "presentation": { + "echo": false, + "reveal": "always", + "panel": "dedicated", + "focus": true, + "clear": true, + "group": "debug" + }, + "isBackground": true, + "problemMatcher": { + "owner": "custom", + "pattern": { + "regexp": ".", + "file": 1, + "location": 2, + "message": 3 + }, + "background": { + "activeOnStart": true, + "beginsPattern": "^.*", + "endsPattern": "^\"Renode Simulator is now active\".*" + } + } + }, + { + "label": "Open UART2 Telnet", + "type": "shell", + "command": "echo \"Controls Leaderboard UART2\"; while ! nc -z localhost ${RENODE_UART2_TELNET}; do sleep 2; echo .; done; echo Connected && nc localhost ${RENODE_UART2_TELNET}", + "presentation": { + "echo": false, + "reveal": "always", + "panel": "dedicated", + "focus": true, + "group": "debug" + }, + "isBackground": true, + "problemMatcher": { + "owner": "custom", + "pattern": { + "regexp": ".", + "file": 1, + "location": 2, + "message": 3 + }, + "background": { + "activeOnStart": true, + "beginsPattern": ".", + "endsPattern": "." + } + } + }, + { + "label": "Start OpenOCD debugger", + "type": "shell", + "command": "openocd", + "presentation": { + "echo": false, + "reveal": "always", + "panel": "dedicated", + "focus": true, + "group": "debug" + }, + "problemMatcher": [] + }, + { + "label": "Open Terminal GDB", + "type": "shell", + "command": "arm-none-eabi-gdb ${workspaceFolder:Controls}/Objects/controls-leader.elf", + "presentation": { + "echo": false, + "reveal": "always", + "panel": "dedicated", + "focus": true, + "group": "debug" + }, + "problemMatcher": [] + }, + { + "label": "Start Renode Tools", + "dependsOn": [ + "Start Renode", + "Open UART2 Telnet" + ], + "dependsOrder": "sequence", + "problemMatcher": [] + }, + { + "label": "Start Renode Tools & Terminal GDB", + "dependsOn": [ + "Start Renode Tools", + "Open Terminal GDB" + ], + "dependsOrder": "sequence", + "problemMatcher": [] + }, + { + "label": "Start Hardware Tools", + "dependsOn": [ + "Start OpenOCD debugger", + "Open Terminal GDB" + ], + "dependsOrder": "sequence", + "problemMatcher": [] + }, + { + "label": "Build Controls & Start OpenOCD", + "dependsOn": [ + "Build Controls", + "Start OpenOCD debugger" + ], + "dependsOrder": "sequence", + "problemMatcher": [] + }, + { + "label": "Build Controls & Start Hardware Tools", + "dependsOn": [ + "Build Controls", + "Start Hardware Tools" + ], + "dependsOrder": "sequence", + "problemMatcher": [] + }, + { + "label": "Build Controls & Start Renode Tools", + "dependsOn": [ + "Build Controls", + "Start Renode Tools" + ], + "dependsOrder": "sequence", + "problemMatcher": [] + }, + { + "label": "Kill Processes", + "type": "process", + "command": [ + "${command:workbench.action.tasks.terminate}", + "${command:workbench.action.acceptSelectedQuickOpenItem}" + ], + "problemMatcher": [] + } + ], + "inputs": [ + { + "id": "target", + "type": "pickString", + "description": "Target to compile.", + "options": [ + "leader", + "flash", + "clean" + ] + }, + { + "id": "test", + "type": "promptString", + "description": "Test file to compile and run.", + "default": "" + }, + { + "id": "debug", + "type": "pickString", + "description": "Debug ", + "options": [ + "1", + "0" + ], + "default": "1" + } + ], + }, + "launch": { + "version": "2.0.0", + "configurations": [ + { + "name": "Renode Build & Debug Controls", + "type": "cppdbg", + "request": "launch", + "cwd": "${workspaceFolder:Controls}", + "program": "${workspaceFolder:Controls}/Objects/controls-leader.elf", + "preLaunchTask": "Build Controls & Start Renode Tools", + "postDebugTask": "Kill Processes", + + "stopAtEntry": true, + "stopAtConnect": true, + + "customLaunchSetupCommands": [ + {"text": "target extended-remote :3333", "ignoreFailures": false}, + {"text": "file Objects/controls-leader.elf"} + ], + + "MIMode": "gdb", + "miDebuggerPath": "arm-none-eabi-gdb", + "miDebuggerServerAddress": "localhost:3333", + "miDebuggerArgs": "--cd=${workspaceFolder:Controls}", + "hardwareBreakpoints": {"require": true}, + + "targetArchitecture": "arm64", + "logging": { + "engineLogging": false, + "traceResponse": false + } + }, + { + "name": "Hardware Build & Debug Controls", + "type": "cppdbg", + "request": "launch", + "cwd": "${workspaceFolder:Controls}", + "program": "${workspaceFolder:Controls}/Objects/controls-leader.elf", + "preLaunchTask": "Build Controls & Start OpenOCD", + "postDebugTask": "Kill Processes", + + "stopAtEntry": true, + "stopAtConnect": true, + + "customLaunchSetupCommands": [ + {"text": "target extended-remote :3333", "ignoreFailures": false}, + {"text": "file Objects/controls-leader.elf"} + ], + + "MIMode": "gdb", + "miDebuggerPath": "arm-none-eabi-gdb", + "miDebuggerServerAddress": "localhost:3333", + "miDebuggerArgs": "--cd=${workspaceFolder:Controls}", + "hardwareBreakpoints": {"require": true}, + + "targetArchitecture": "arm64", + "logging": { + "engineLogging": false, + "traceResponse": false + } + } + + ] + }, + "extensions": { + "recommendations": [ + "ms-vscode.cpptools-extension-pack", // For Controls C code + "GitHub.vscode-pull-request-github", // For reviewing pull requests directly from VSCode + "eamodio.gitlens", // For better github stuff + "jirkavrba.subway-surfers", // For fun + "ms-vscode-remote.remote-wsl", // For WSL + "waderyan.gitblame" // For tracking commit history and authors within code + ] + } + +} \ No newline at end of file From 834eb416a3b232373aba282e2f5b3cf5d2afa6e3 Mon Sep 17 00:00:00 2001 From: diyarajon Date: Sat, 2 Mar 2024 15:59:03 -0600 Subject: [PATCH 56/57] Added debug macro to BSP makefile to use when testing, but not unit-testing --- BSP/STM32F413/Makefile | 3 +++ Makefile | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/BSP/STM32F413/Makefile b/BSP/STM32F413/Makefile index cf3073dd1..cc48c032e 100644 --- a/BSP/STM32F413/Makefile +++ b/BSP/STM32F413/Makefile @@ -125,6 +125,9 @@ ifeq ($(CAR_LOOPBACK), 1) C_DEFS += -DCAR_LOOPBACK endif +FILETOTEST = $(shell echo '$(FILE)' | tr '[:lower:]' '[:upper:]') Uses shell to make TEST file uppercase to define a macro +C_DEFS += -DDEBUG_$(FILETOTEST) #Defines a macro DEBUG_ + # compile gcc flags ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections diff --git a/Makefile b/Makefile index c73e3915f..9d7c685a1 100644 --- a/Makefile +++ b/Makefile @@ -20,9 +20,13 @@ export CAR_LOOPBACK # Check if test file exists for the leader. ifneq (,$(wildcard Tests/Test_$(TEST).c)) TEST_LEADER ?= Tests/Test_$(TEST).c + FILE = $(TEST) + else TEST_LEADER ?= Apps/Src/main.c + FILE = MAIN endif +export FILE #Check if unit test file exists (just to inform user if it isn't found) #UNITTEST is solely used for echoing purposes From a61bd8383c165220fe522bc6e8f5ccbfb006b81b Mon Sep 17 00:00:00 2001 From: diyarajon Date: Sat, 2 Mar 2024 16:26:55 -0600 Subject: [PATCH 57/57] Updated the ReadMe to include the DEBUG_TESTFILE and created an example of this in HelloWorld file --- BSP/STM32F413/Makefile | 2 +- README.md | 2 +- Tests/Test_HelloWorld.c | 10 ++++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/BSP/STM32F413/Makefile b/BSP/STM32F413/Makefile index cc48c032e..df7764d07 100644 --- a/BSP/STM32F413/Makefile +++ b/BSP/STM32F413/Makefile @@ -125,7 +125,7 @@ ifeq ($(CAR_LOOPBACK), 1) C_DEFS += -DCAR_LOOPBACK endif -FILETOTEST = $(shell echo '$(FILE)' | tr '[:lower:]' '[:upper:]') Uses shell to make TEST file uppercase to define a macro +FILETOTEST = $(shell echo '$(FILE)' | tr '[:lower:]' '[:upper:]') #Uses shell to make TEST file uppercase to define a macro C_DEFS += -DDEBUG_$(FILETOTEST) #Defines a macro DEBUG_ # compile gcc flags diff --git a/README.md b/README.md index 32a8cbaa7..c509a3776 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ Follow our [integration documentation](https://utexas.sharepoint.com/:w:/s/ENGR- WIP: A formal test framework has yet to be defined for the Controls system. -For now, ```make leader TEST=TestName``` should build the Controls system excluding **Apps/Src/main.c** and including **Tests/Test_TestName.c**. +For now, ```make leader TEST=TestName``` should build the Controls system excluding **Apps/Src/main.c** and including **Tests/Test_TestName.c**. A macro DEBUG_TESTNAME is also defined which can be used for debug dumps and more! An example of this can be found in Test_HelloWorld. ### Debugging OpenOCD is a debugger program that is open source and compatible with the STM32F413. GDB is a debugger program that can be used to step through a program as it is being run on the board. To use, you need two terminals open, as well as a USB connection to the ST-Link programmer (as if you were going to flash the program to the board). diff --git a/Tests/Test_HelloWorld.c b/Tests/Test_HelloWorld.c index 220bce2b3..24cbffc2c 100644 --- a/Tests/Test_HelloWorld.c +++ b/Tests/Test_HelloWorld.c @@ -3,8 +3,14 @@ #include int main(void){ - BSP_UART_Init(UART_2); - printf("Hello World\n"); + // This is an example of how to use DEBUG_ MACRO + + BspUartInit(kUart2); + #ifdef DEBUG_HELLOWORLD + printf("This print statement means that DEBUG_HELLOWORLD is defined\n"); + #else + printf("Hello World, your DEBUG_HELLOWORLD is not defined"); + #endif while(1){}