[Embedded project application] __The embedded framework “Zorb Framework” used to build debugging output and establish time systems

Table of Contents

1. What is Zorb?

2. Embedded environment construction

3. Debug output

4. Implement assertions

5. Establish a time system

6. Conclusion

(* ̄︶ ̄)Creation is not easy! Looking forward to your likes, collections and comments.


1. What is Zorb?

Zorb Framework is a lightweight embedded framework based on object-oriented ideas.

The purpose of building Zorb Framework is to quickly develop applications on chips that cannot run Linux without having to reinvent the wheel.

The preliminary design functions of Zorb Framework include:

  1. Time system function zf_time
  2. Ring buffer function zf_buffer
  3. List function zf_list
  4. State machine function zf_fsm
  5. Event function zf_event
  6. Timer function zf_timer
  7. Task function zf_task

With the first 6 functions, you can implement a purely event-driven program, which can basically meet the needs of small and medium-sized embedded application development. The task function is added to meet the high real-time requirements of some programs. Of course, you can also cut out the first 6 functions and run them on existing embedded systems, which can also meet real-time requirements.

2. Embedded environment construction

The STM32F429 development board is used as the hardware operating environment. The hardware resources use Serial port 1 and systick,

Among them, Serial port 1: provides debugging printing function, systick: provides system time counting function.

Not much to say about setting up the hardware environment. You can refer to the routines provided by the development board to build it. The board-level initialization completes the initialization of the debugging serial port and systick.

/********************************************** *********************************
 * Description: Hardware environment initialization
 * Parameters: None
 * Return: None
*************************************************** ****************************/
void BSP_init(void)
{
    /* Nested vector interrupt controller group selection */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    /* Initialize debugging serial port */
    Debug_USART_init();

    /* Systick initialization */
    SystemTick_init();
}

/****************************************************** *****************************
 * Description: Hardware underlying program
 * Parameters: None
 * Return: None
*************************************************** ****************************/
void BSP_process(void)
{

}

3. Debugging output

When developing a program, the first and most important thing is to set up a debugging environment. We use serial port 1 as the debugging output (printf mapping), and then the debugging information is divided into three levels. The subsequent host computer can highlight prompts according to different levels:

/**
  *************************************************** ***************************
  * @file zf_debug.h
  * @author Zorb
  * @version V1.0.0
  * @date 2018-06-28
  * @brief Header file for debugging output
  *************************************************** ***************************
  * @history
  *
  * 1. Date:2018-06-28
  * Author:Zorb
  * Modification:Create 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: alarm */
#define LOG_E 2; /* Message level: Error */

#define _ZF_DEBUG /* Define debugging function */
#define ZF_DEBUG_ON true /* Enable debugging */

#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 ************** ******************/

Four. Implementation of assertions

During the development process, making some assertions in key places can facilitate locating bugs.

/**
  *************************************************** ***************************
  * @file zf_assert.h
  * @author Zorb
  * @version V1.0.0
  * @date 2018-06-28
  * @brief assertion header file
  *************************************************** ***************************
  * @history
  *
  * 1. Date:2018-06-28
  * Author:Zorb
  * Modification:Create file
  *
  *************************************************** ***************************
  */

#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 */

/* Processing when assertions are generated */
void ZF_assertHandle(uint8_t *pFileName, int line);

#ifdef __cplusplus
}
#endif

#endif /* __ZF_ASSERT_H__ */

/************************************ END OF FILE ************** ******************/

The processing of assertions is very simple. It just tells us which file and which line the error occurred. 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:Create file
  *
  *************************************************** ***************************
  */

#include "zf_assert.h"
#include "zf_debug.h"

/****************************************************** *****************************
 * Description: Processing when assertions are generated
 * Parameter: (in)-pFileName file name
 * (in)-line number of lines
 * Return: None
*************************************************** ****************************/
void ZF_assertHandle(uint8_t *pFileName, int line)
{
    ZF_DEBUG(LOG_E, "file:%s line:%d:asserted\r\\
", pFileName, line);

    while (1);
}

/************************************ END OF FILE ************** ******************/

5. Establishing a time system

In order to reduce the resource consumption of the framework, the minimum time period of the framework is initially set to 1ms, so we need to set the timing period of systick to 1ms, and then count the interrupts for our framework every time.

/********************************************** *********************************
 * Description: SysTick interrupt service routine
 * Parameters: none
 * Return: None
*************************************************** ****************************/
void SysTick_Handler(void)
{
    /* Provide timing for zorb framework */
    ZF_timeTick();
}

At present, the functions provided by the time system are relatively basic, only system tick counting and system dead wait delay. We will re-expand the time system later when we develop timer functions and task functions.

/**
  *************************************************** ***************************
  * @file zf_time.h
  * @author Zorb
  * @version V1.0.0
  * @date 2018-06-28
  * @brief System time header file
  *************************************************** ***************************
  * @history
  *
  * 1. Date:2018-06-28
  * Author:Zorb
  * Modification:Create 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 the number of system ticks */
#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 the number of system ticks */
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 hung in the hardware time interrupt) */
void ZF_timeTick (void);

#ifdef __cplusplus
}
#endif

#endif /* __ZF_TIME_H__ */

/************************************ END OF FILE ************** ******************/

6. Conclusion

The functions implemented in this article are relatively basic, but they are the foundation of the entire framework development and all subsequent extended functions need to be developed in this environment. Building a good debugging output environment can help us quickly locate bugs, thereby improving development efficiency.

Zorb Framework github: https://github.com/54zorb/Zorb-Framework

(* ̄︶ ̄)Creating is not easy! I look forward to your likes, favorites and comments.

This article comes from the Internet, sharing knowledge for free, and the copyright belongs to the original author. If there is any copyright issue with the work, please contact me for deletion!