Zorb Framework is a lightweight embedded framework built on an object-oriented design philosophy.
Introduction to Zorb #
Zorb Framework is a lightweight embedded framework built on an object-oriented design philosophy.
The purpose of building Zorb Framework is to enable rapid application development on chips that cannot run Linux, avoiding repetitive work.
The initial design features of Zorb Framework include:
- Time system function
zf_time
- Circular buffer function
zf_buffer
- List function
zf_list
- State machine function
zf_fsm
- Event function
zf_event
- Timer function
zf_timer
- Task function
zf_task
The first six functions alone can create a purely event-driven program, which can basically meet the needs of small and medium-sized embedded application development. The addition of the task function is to meet the needs of some programs that require higher real-time performance.
Of course, the first six functions can also be extracted and run on existing embedded systems to meet real-time requirements.
Embedded Environment Setup #
An STM32F429 development board is used as the hardware environment, utilizing UART1 and SysTick. UART1 provides debug printing, and SysTick provides a system time counter.
I won’t elaborate on the hardware environment setup, as you can refer to the examples provided with the development board. The board-level initialization completes the setup of the debug UART and SysTick.
/******************************************************************************
* Description: Hardware environment initialization
* Parameters: None
* Returns: None
******************************************************************************/
void BSP_init(void)
{
/* Nested Vectored Interrupt Controller Group Selection */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* Initialize Debug UART */
Debug_USART_init();
/* SysTick Initialization */
SystemTick_init();
}
/******************************************************************************
* Description: Hardware-level program
* Parameters: None
* Returns: None
******************************************************************************/
void BSP_process(void)
{
}
Debug Output #
When developing a program, the first and most important step is to set up a debugging environment. We use UART1 for debug output (mapping to printf
). The debug messages are divided into three levels, which can later be highlighted by the host computer based on the level:
/**
*****************************************************************************
* @file zf_debug.h
* @author Zorb
* @version V1.0.0
* @date 2018-06-28
* @brief Header file for debug output
*****************************************************************************
* @history
*
* 1. Date:2018-06-28
* Author:Zorb
* Modification:File creation
*
*****************************************************************************
*/
#ifndef __ZF_DEBUG_H__
#define __ZF_DEBUG_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stdio.h"
#include "stdbool.h"
#define LOG_D 0; /* Message Level: Normal */
#define LOG_W 1; /* Message Level: Warning */
#define LOG_E 2; /* Message Level: Error */
#define _ZF_DEBUG /* Define debug function */
#define ZF_DEBUG_ON true /* Enable debug function */
#ifdef _ZF_DEBUG
#if ZF_DEBUG_ON
#define ZF_DEBUG(rank, x...) do \
{ \
char code[10] = "[rank=0]"; \
code[6] = '0' + (char)rank; \
if (code[6] != '0') \
{ \
printf("%s", code); \
} \
printf(x); \
} while(0)
#else
#define ZF_DEBUG(rank, x...)
#endif /* ZF_DEBUG_ON */
#endif /* _ZF_DEBUG */
#ifdef __cplusplus
}
#endif
#endif /* __ZF_DEBUG_H__ */
/******************************** END OF FILE ********************************/
Implementing Assertions #
During development, adding assertions in key places can help quickly pinpoint bugs.
/**
*****************************************************************************
* @file zf_assert.h
* @author Zorb
* @version V1.0.0
* @date 2018-06-28
* @brief Header file for assertions
*****************************************************************************
* @history
*
* 1. Date:2018-06-28
* Author:Zorb
* Modification:File creation
*
*****************************************************************************
*/
#ifndef __ZF_ASSERT_H__
#define __ZF_ASSERT_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stdint.h"
#define _ZF_ASSERT /* Define assertion function */
#define ZF_ASSERT_ON true /* Enable assertion function */
#ifdef _ZF_ASSERT
#if ZF_ASSERT_ON
#define ZF_ASSERT(expression_) ((expression_) ?\
(void)0 : ZF_assertHandle((uint8_t *)__FILE__, (int)__LINE__));
#else
#define ZF_ASSERT(expression_)
#endif /* ZF_ASSERT_ON */
#endif /* _ZF_ASSERT */
/* Assertion handler */
void ZF_assertHandle(uint8_t *pFileName, int line);
#ifdef __cplusplus
}
#endif
#endif /* __ZF_ASSERT_H__ */
/******************************** END OF FILE ********************************/
The assertion handler is simple: it tells us which file and line the error occurred on. The implementation is as follows:
/**
*****************************************************************************
* @file zf_assert.c
* @author Zorb
* @version V1.0.0
* @date 2018-06-28
* @brief Assertion implementation
*****************************************************************************
* @history
*
* 1. Date:2018-06-28
* Author:Zorb
* Modification:File creation
*
*****************************************************************************
*/
#include "zf_assert.h"
#include "zf_debug.h"
/******************************************************************************
* Description: Assertion handler
* Parameters: (in)-pFileName File name
* (in)-line Line number
* Returns: None
******************************************************************************/
void ZF_assertHandle(uint8_t *pFileName, int line)
{
ZF_DEBUG(LOG_E, "file:%s line:%d:asserted\r\n", pFileName, line);
while (1);
}
/******************************** END OF FILE ********************************/
Building the Time System #
To minimize the framework’s resource consumption, the initial minimum time period is set to 1ms. Therefore, we need to set the SysTick timer period to 1ms, and then each time the interrupt is entered, we increment the counter for our framework.
/******************************************************************************
* Description: SysTick interrupt service routine
* Parameters: None
* Returns: None
******************************************************************************/
void SysTick_Handler(void)
{
/* Provide timing for zorb framework */
ZF_timeTick();
}
Currently, the time system provides only basic functions, such as the system tick counter and a blocking delay. We will expand the time system later when we develop the timer and task functions.
/**
*****************************************************************************
* @file zf_time.h
* @author Zorb
* @version V1.0.0
* @date 2018-06-28
* @brief Header file for system time
*****************************************************************************
* @history
*
* 1. Date:2018-06-28
* Author:Zorb
* Modification:File creation
*
*****************************************************************************
*/
#ifndef __ZF_TIME_H__
#define __ZF_TIME_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stdbool.h"
#include "stdint.h"
/* System tick period (ms) */
#define ZF_TICK_PERIOD 1
/* Get system tick count */
#define ZF_SYSTICK() ZF_getSystemTick()
/* Get system time (ms) */
#define ZF_SYSTIME_MS() ZF_getSystemTimeMS()
/* System delay (ms) */
#define ZF_DELAY_MS(ms_) do \
{ \
if (ms_ % ZF_TICK_PERIOD) \
{ \
ZF_delayTick((ms_ / ZF_TICK_PERIOD) + 1); \
} \
else \
{ \
ZF_delayTick(ms_ / ZF_TICK_PERIOD); \
} \
} while(0)
/* Get system tick count */
uint32_t ZF_getSystemTick(void);
/* Get system time (ms) */
uint32_t ZF_getSystemTimeMS(void);
/* System delay */
void ZF_delayTick(uint32_t tick);
/* System tick program (must be placed in a hardware time interrupt) */
void ZF_timeTick (void);
#ifdef __cplusplus
}
#endif
#endif /* __ZF_TIME_H__ */
/******************************** END OF FILE ********************************/
Conclusion #
This article covers the basic functions, which form the foundation of the entire framework. All subsequent extended functions will be developed within this environment.
Building a good debug output environment can help us quickly locate bugs, thereby improving development efficiency.
Github Address #
https://github.com/54zorb/Zorb-Framework