Below is the sample function that I want to test using Ceedling:
fsp_err_t half_bridge_reset(const half_bridge_cfg_t* cfg, half_bridge_ctrl_t* ctrl, const ioport_instance_t* io)
{
/* Clear control block */
// memset(ctrl, 0, sizeof(half_bridge_ctrl_t));
/* Reset direction output */
io->p_api->pinWrite(io->p_ctrl, cfg->dir_pin, (bsp_io_level_t) HALF_BRIDGE_CONVERT_UP);
/* Clear duty cycle and return */
return cfg->pwm_tmr->p_api->dutyCycleSet(cfg->pwm_tmr->p_ctrl, 0, cfg->pwm_pin);
}
/** Timer API structure. General timer functions implemented at the HAL layer follow this API. */
typedef struct st_timer_api
{
/** Sets the number of counts for the pin level to be high. If the timer is counting, the updated duty cycle is
* reflected after the next timer expiration.
*
*
* @param[in] p_ctrl Control block set in @ref timer_api_t::open call for this timer.
* @param[in] duty_cycle_counts Time until duty cycle should expire.
* @param[in] pin Which output pin to update. See implementation for details.
*/
fsp_err_t (* dutyCycleSet)(timer_ctrl_t * const p_ctrl, uint32_t const duty_cycle_counts, uint32_t const pin);
/** Stores timer information in p_info.
*
* @param[in] p_ctrl Control block set in @ref timer_api_t::open call for this timer.
* @param[out] p_info Collection of information for this timer.
*/
fsp_err_t (* infoGet)(timer_ctrl_t * const p_ctrl, timer_info_t * const p_info);
/** Get the current counter value and timer state and store it in p_status.
*
* @param[in] p_ctrl Control block set in @ref timer_api_t::open call for this timer.
* @param[out] p_status Current status of this timer.
*/
fsp_err_t (* statusGet)(timer_ctrl_t * const p_ctrl, timer_status_t * const p_status);
/** Specify callback function and optional context pointer and working memory pointer.
*
* @param[in] p_ctrl Control block set in @ref timer_api_t::open call for this timer.
* @param[in] p_callback Callback function to register
* @param[in] p_context Pointer to send to callback function
* @param[in] p_working_memory Pointer to volatile memory where callback structure can be allocated.
* Callback arguments allocated here are only valid during the callback.
*/
fsp_err_t (* callbackSet)(timer_ctrl_t * const p_ctrl, void (* p_callback)(timer_callback_args_t *),
void const * const p_context, timer_callback_args_t * const p_callback_memory);
/** Allows driver to be reconfigured and may reduce power consumption.
*
* @param[in] p_ctrl Control block set in @ref timer_api_t::open call for this timer.
*/
fsp_err_t (* close)(timer_ctrl_t * const p_ctrl);
} timer_api_t;
/** This structure encompasses everything that is needed to use an instance of this interface. */
typedef struct st_timer_instance
{
timer_ctrl_t * p_ctrl; ///< Pointer to the control structure for this instance
timer_cfg_t const * p_cfg; ///< Pointer to the configuration structure for this instance
timer_api_t const * p_api; ///< Pointer to the API structure for this instance
} timer_instance_t;
The function is accessing elements of the structure that are function pointers. How can we test such functions with Ceedling if we want to mock them?
*
* @param[in] p_ctrl Pointer to control structure.
* @param[in] pin Pin to be written to.
* @param[in] level State to be written to the pin.
*/
fsp_err_t (* pinWrite)(ioport_ctrl_t * const p_ctrl, bsp_io_port_pin_t pin, bsp_io_level_t level);
How can I create mock for function pointer that is an element of the stucture.
{
} ioport_api_t;
typedef struct st_ioport_instance
{
ioport_ctrl_t * p_ctrl;
ioport_cfg_t const * p_cfg;
ioport_api_t const * p_api;
} ioport_instance_t;
3. Mock_HeaderFile1.h (created by Ceedling)
4. SourceFile1.c
fsp_err_t half_bridge_reset(const half_bridge_cfg_t* cfg, half_bridge_ctrl_t* ctrl, const ioport_instance_t* io)
{
/* Reset direction output */
io->p_api->pinWrite(io->p_ctrl, cfg->dir_pin, (bsp_io_level_t) HALF_BRIDGE_CONVERT_UP);
return cfg->pwm_tmr->p_api->dutyCycleSet(cfg->pwm_tmr->p_ctrl, 0, cfg->pwm_pin);
}
5. Test_SourceFile1.c