“Starred Public Account“, let’s improve together!
Source: https://github.com/54zorb/Zorb-Framework
1. Introduction to Zorb
Zorb Framework is a lightweight embedded framework built on object-oriented principles.
The purpose of building the Zorb Framework is to quickly develop applications on chips that cannot run Linux, without reinventing the wheel.
The initial design features of the Zorb Framework include:
1. Time system feature zf_time
2. Circular buffer feature zf_buffer
3. List feature zf_list
4. State machine feature zf_fsm
5. Event feature zf_event
6. Timer feature zf_timer
7. Task feature zf_task
The first six features can implement a purely event-driven program, basically meeting the needs of small to medium-sized embedded application development. Adding the task feature is to meet the needs of some programs that require higher real-time performance. Of course, the first six features can also be trimmed and run on existing embedded systems to meet real-time requirements.
2. Setting Up the Embedded Environment
Using the STM32F429 development board as the hardware running environment, the hardware resources include UART1 and SysTick, where UART1 provides debugging print functionality, and SysTick provides system time counting functionality.
There is not much to say about setting up the hardware environment; you can refer to the examples provided by the development board to set it up. The board-level initialization has completed the initialization of the debugging UART and SysTick.
/****************************************************************************
* Description : Hardware environment initialization
* Parameters : None
* Returns : None
******************************************************************************/
void BSP_init(void)
{
/* Select nested vector interrupt controller group */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* Initialize debugging UART */
Debug_USART_init();
/* SysTick initialization */
SystemTick_init();
}
/****************************************************************************
* Description : Hardware low-level program
* Parameters : None
* Returns : None
******************************************************************************/
void BSP_process(void)
{
}
3. Debug Output
When developing a program, the first and most important thing is to set up the debugging environment. We use UART1 as the debugging output (printf mapping), and then the debug information is divided into three levels, which can be highlighted by the upper computer based on different levels:
/**
*****************************************************************************
* @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: Created file
*
*****************************************************************************
*/
#ifndef __ZF_DEBUG_H__
#define __ZF_DEBUG_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stdio.h"
#include "stdbool.h"
#define LOG_D 0; /* Information Level: Normal */
#define LOG_W 1; /* Information Level: Warning */
#define LOG_E 2; /* Information Level: Error */
#define _ZF_DEBUG /* Define debug functionality */
#define ZF_DEBUG_ON true /* Enable debug functionality */
#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 ********************************/
4. Implementing Assertions
During development, performing some assertions at critical points can help locate bugs easily.
/**
*****************************************************************************
* @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: Created file
*
*****************************************************************************
*/
#ifndef __ZF_ASSERT_H__
#define __ZF_ASSERT_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stdint.h"
#define _ZF_ASSERT /* Define assertion functionality */
#define ZF_ASSERT_ON true /* Enable assertion functionality */
#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 */
/* Handling when an assertion occurs */
void ZF_assertHandle(uint8_t *pFileName, int line);
#ifdef __cplusplus
}
#endif
#endif /* __ZF_ASSERT_H__ */
/******************************** END OF FILE ********************************/
The handling of assertions is simple; it just tells us where in which file and line an error occurred, implemented as follows:
/**
*****************************************************************************
* @file zf_assert.c
* @author Zorb
* @version V1.0.0
* @date 2018-06-28
* @brief Implementation of assertions
*****************************************************************************
* @history
*
* 1. Date:2018-06-28
* Author:Zorb
* Modification: Created file
*
*****************************************************************************
*/
#include "zf_assert.h"
#include "zf_debug.h"
/****************************************************************************
* Description : Handling when an assertion occurs
* 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 ********************************/
5. Establishing a Time System
To reduce the framework’s resource consumption, we initially set the minimum time cycle of the framework to 1ms, so we need to set the SysTick’s timing cycle to 1ms, and then each time we enter the interrupt, we can count for our framework.
/****************************************************************************
* Description : SysTick interrupt service routine
* Parameters : None
* Returns : None
******************************************************************************/
void SysTick_Handler(void)
{
/* Provide timing for zorb framework */
ZF_timeTick();
}
The current functionality provided by the time system is quite basic, only system tick counting and system dead wait delay. We will expand the time system when we develop the timer feature and task feature.
/**
*****************************************************************************
* @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: Created file
*
*****************************************************************************
*/
#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 (needs to be hooked into the hardware time interrupt) */
void ZF_timeTick (void);
#ifdef __cplusplus
}
#endif
#endif /* __ZF_TIME_H__ */
/******************************** END OF FILE ********************************/
6. Conclusion
The functionalities implemented in this article are quite basic, but they lay the foundation for the entire framework development. A well-established debugging output environment can help us quickly locate bugs, thus improving development efficiency.
Zorb Framework GitHub: https://github.com/54zorb/Zorb-Framework
This article is sourced from the internet, freely conveying knowledge, and the copyright belongs to the original author. If there are any copyright issues, please contact me for deletion.
Previous Recommendations
“Comprehensive Guide to Embedded Linux Drivers”
How to Read Embedded Project Code Efficiently?