I am writing code for an MCXA153 dev kit and with my code I am writing ceedling tests.
In my header file for led.h
I have the snippet
#ifndef LED_H_
#define LED_H_
#include "MCXA153.h"
#include "fsl_gpio.h"
#include "fsl_port.h"
#include "fsl_reset.h"
#define LED_1_H_PIN 2U
#define LED_1_H_PORT PORT2
#define LED_1_H_GPIO GPIO2
#define LED_2_H_PIN 3U
#define LED_2_H_PORT PORT2
#define LED_2_H_GPIO GPIO2
#define LED_3_H_PIN 7U
#define LED_3_H_PORT PORT2
#define LED_3_H_GPIO GPIO2
#define LED_4_H_PIN 12U
#define LED_4_H_PORT PORT2
#define LED_4_H_GPIO GPIO2
#define LED_Debug_H_PIN 11U
#define LED_Debug_H_PORT PORT3
#define LED_Debug_H_GPIO GPIO3
#define LED_TASK_TIMES_TO_RUN 0U
#define LED_TASK_INITIAL_DELAY_MS 0U
#define LED_TASK_PERIOD_MS 5U
In led.c
all I do is include led.h
I have no further includes in my source code.
In my test code I mock all of my headers.
#ifdef CEEDLING_TESTS
#include "unity.h"
#include "mock_fsl_gpio.h"
#include "mock_fsl_port.h"
#include "mock_fsl_reset.h"
#include "led.h"
void setUp(void) {
memset(&leds, 0, sizeof(leds));
}
void tearDown(void) {
}
gpio_pin_config_t led_gpio_config = {
.pinDirection = kGPIO_DigitalOutput,
.outputLogic = LED_DEFAULT_STATE
};
const port_pin_config_t led_port_config = {
kPORT_PullDisable,
kPORT_LowPullResistor,
kPORT_FastSlewRate,
kPORT_PassiveFilterDisable,
kPORT_OpenDrainDisable,
kPORT_LowDriveStrength,
kPORT_NormalDriveStrength,
kPORT_MuxAlt0,
kPORT_InputBufferEnable,
kPORT_InputNormal,
kPORT_UnlockRegister};
void test_led_init_should_initialize_all_leds(void) {
CLOCK_EnableClock(kCLOCK_GateGPIO2);
CLOCK_EnableClock(kCLOCK_GatePORT2);
CLOCK_EnableClock(kCLOCK_GateGPIO3);
CLOCK_EnableClock(kCLOCK_GatePORT3);
RESET_ReleasePeripheralReset(kGPIO2_RST_SHIFT_RSTn);
RESET_ReleasePeripheralReset(kPORT2_RST_SHIFT_RSTn);
RESET_ReleasePeripheralReset(kGPIO3_RST_SHIFT_RSTn);
RESET_ReleasePeripheralReset(kPORT3_RST_SHIFT_RSTn);
for (int i = 0; i < NUM_LEDS; i++) {
GPIO_PinInit(leds[i].led_gpio.gpio, leds[i].led_gpio.pin, &led_gpio_config);
PORT_SetPinConfig(leds[i].led_gpio.port, leds[i].led_gpio.pin, &led_port_config);
}
led_init();
for (int i = 0; i < NUM_LEDS; i++) {
TEST_ASSERT_EQUAL(LED_STATE_OFF, leds[i].current_state);
TEST_ASSERT_EQUAL(LED_OFF, leds[i].action);
}
}
#endif
In my project.yml
I have set up my include paths as well as my defines for the project. I am treating externs and inlines as includes. I have gcov setup as well.
---
:project:
:use_exceptions: FALSE
:use_test_preprocessor: TRUE
:use_auxiliary_dependencies: TRUE
:build_root: build
:test_file_prefix: test_
:which_ceedling: gem
:ceedling_version: 0.31.1
:default_tasks:
- test:all
:environment:
:extension:
:executable: .out
:paths:
:test:
- +:test/**
:source:
- source/**
:include:
- include/**
- frdm-mcxa153-bsp/**
- frdm-mcxa153-bsp/board/**
- frdm-mcxa153-bsp/CMSIS/**
- frdm-mcxa153-bsp/CMSIS_driver/**
- frdm-mcxa153-bsp/CMSIS_driver/Include/**
- frdm-mcxa153-bsp/component/lists/**
- frdm-mcxa153-bsp/component/uart/**
- frdm-mcxa153-bsp/device/**
- frdm-mcxa153-bsp/drivers/**
- frdm-mcxa153-bsp/startup/**
- frdm-mcxa153-bsp/utilities/**
:support:
:libraries: []
:files:
:include:
- frdm-mcxa153-bsp/**
:defines:
:common: &common_defines []
:test:
- *common_defines
- CEEDLING_TESTS
- CPU_MCXA153VLH
- MCUXPRESSO_SDK
- CPU_MCXA153VLH_cm33_nodsp
- SDK_DEBUGCONSOLE=1
- CR_INTEGER_PRINTF
- __MCUXPRESSO
- __USE_CMSIS
- DEBUG
- __REDLIB__
:test_preprocess:
- *common_defines
- CEEDLING_TESTS
- CPU_MCXA153VLH
- MCUXPRESSO_SDK
- CPU_MCXA153VLH_cm33_nodsp
- SDK_DEBUGCONSOLE=1
- CR_INTEGER_PRINTF
- __MCUXPRESSO
- __USE_CMSIS
- DEBUG
- __REDLIB__
:cmock:
:exclude:
:mock_prefix: mock_
:when_no_prototypes: :warn
:enforce_strict_ordering: TRUE
:treat_externs: :include
:treat_inlines: :include
:plugins:
- :ignore
- :callback
:treat_as:
uint8: HEX8
uint16: HEX16
uint32: UINT32
int8: INT8
bool: UINT8
# Add -gcov to the plugins list to make sure of the gcov plugin
# You will need to have gcov and gcovr both installed to make it work.
# For more information on these options, see docs in plugins/gcov
:gcov:
:utilities:
- gcovr
:reports:
- Cobertura
- Xml
- HtmlBasic
:gcovr:
:xml_pretty: true
:cobertura_pretty: true
:html_medium_threshold: 70
:html_high_threshold: 90
# LIBRARIES
# These libraries are automatically injected into the build process. Those specified as
# common will be used in all types of builds. Otherwise, libraries can be injected in just
# tests or releases. These options are MERGED with the options in supplemental yaml files.
:libraries:
:placement: :end
:flag: "-l${1}"
:path_flag: "-L ${1}"
:system: [] # for example, you might list 'm' to grab the math library
:test: []
:release: []
:plugins:
:load_paths:
:enabled:
- stdout_pretty_tests_report
- module_generator
- xml_tests_report
- gcov
...
Here is a brief overview of my folder structure
When I run my tests I always run as ceedling clean; ceedling clobber; ceedling test:test_led.c
to ensure I always have a fresh workspace.
When running test_led.c
I always get the error
This is odd to me, it is stating that the file fsl_gpio.h
in build/test/mocks/
cannot find a file to include. Looking at fsl_gpio.h
in build/test/mocks/
the first line is #include "frdm-mcxa153-bsp/drivers/fsl_common.h"
. I believe it cannot find this file because it is using an absolute path from within the build/test/mocks/
folder and not the top level folder.
How do I tell this mock of fsl_gpio.c
to use a different path?
Well I did some soul searching and found an answer. In the project.yml
there are two lines in this block
:cmock:
:exclude:
:mock_prefix: mock_
:when_no_prototypes: :warn
:enforce_strict_ordering: TRUE
:treat_externs: :include
:treat_inlines: :include
Specifically
:treat_externs: :include
:treat_inlines: :include
The header files from NXP have static inline functions defined in the header files. Removing the line :treat_inlines: :include
has resolved my issues. I have to fix my tests, but the thing is building!