https://github.com/54zorb/Zorb-Framework
Zorb简介
Zorb Framework是一个基于面向对象的思想来搭建一个轻量级的嵌入式框架。
搭建Zorb Framework的目的是为在不能运行Linux的芯片上快速开发应用,不用反复造轮子。
Zorb Framework的初步设计功能有:
1、时间系统功能zf_time
2、环形缓冲区功能zf_buffer
3、列表功能zf_list
4、状态机功能zf_fsm
5、事件功能zf_event
6、定时器功能zf_timer
前6个功能,就可以实现纯事件驱动的程序,基本可以满足中小型嵌入式应用程序开发的需求。加上任务功能,是为了满足部分程序对实时性要求较高的需求。
当然,也可以将前6个功能裁剪出来,然后运行在现有的嵌入式系统上面,这样子也可以满足实时性的需求。
环境搭建
采用STM32F429开发板作为硬件运行环境,硬件资源用到串口1和systick,其中串口1提供调试打印功能,systick提供系统时间计数功能。
关于硬件环境的搭建不多说,可以参照开发板提供的例程来搭建,板级初始化完成了调试串口和systick的初始化。
/******************************************************************************
* 描述 :硬件环境初始化
* 参数 :无
* 返回 :无
******************************************************************************/
void BSP_init(void)
{
/* 嵌套向量中断控制器组选择 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* 初始化调试串口 */
Debug_USART_init();
/* Systick初始化 */
SystemTick_init();
}
/******************************************************************************
* 描述 :硬件底层程序
* 参数 :无
* 返回 :无
******************************************************************************/
void BSP_process(void)
{
}
调试
开发一个程序,最开始也最重要的是搭建调试的环境,我们采用串口1作为调试输出(printf映射),然后调试信息分为三个等级,后续上位机可以根据不同等级进行高亮提示:
/**
*****************************************************************************
* @file zf_debug.h
* @author Zorb
* @version V1.0.0
* @date 2018-06-28
* @brief 调试输出的头文件
*****************************************************************************
* @history
*
* 1. Date:2018-06-28
* Author:Zorb
* Modification:建立文件
*
*****************************************************************************
*/
#ifndef __ZF_DEBUG_H__
#define __ZF_DEBUG_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stdio.h"
#include "stdbool.h"
#define LOG_D 0; /* 信息等级:正常 */
#define LOG_W 1; /* 信息等级:告警 */
#define LOG_E 2; /* 信息等级:错误 */
#define _ZF_DEBUG /* 定义调试功能 */
#define ZF_DEBUG_ON true /* 启用调试功能 */
#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 ********************************/
断言
在开发过程中,在关键地方进行一些断言,可以方便定位bug。
/**
*****************************************************************************
* @file zf_assert.h
* @author Zorb
* @version V1.0.0
* @date 2018-06-28
* @brief 断言的头文件
*****************************************************************************
* @history
*
* 1. Date:2018-06-28
* Author:Zorb
* Modification:建立文件
*
*****************************************************************************
*/
#ifndef __ZF_ASSERT_H__
#define __ZF_ASSERT_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stdint.h"
#define _ZF_ASSERT /* 定义断言功能 */
#define ZF_ASSERT_ON true /* 启用断言功能 */
#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 */
/* 断言产生时的处理 */
void ZF_assertHandle(uint8_t *pFileName, int line);
#ifdef __cplusplus
}
#endif
#endif /* __ZF_ASSERT_H__ */
/******************************** END OF FILE ********************************/
断言的处理很简单,就是告诉我们在哪个文件哪一行出错就可以,实现如下
/**
*****************************************************************************
* @file zf_assert.c
* @author Zorb
* @version V1.0.0
* @date 2018-06-28
* @brief 断言的实现
*****************************************************************************
* @history
*
* 1. Date:2018-06-28
* Author:Zorb
* Modification:建立文件
*
*****************************************************************************
*/
#include "zf_assert.h"
#include "zf_debug.h"
/******************************************************************************
* 描述 :断言产生时的处理
* 参数 :(in)-pFileName 文件名
* (in)-line 行数
* 返回 :无
******************************************************************************/
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 ********************************/
调度时间
为了减少框架对资源的消耗,所以初步设定框架的最小时间周期为1ms,因此我们需要设置systick的定时周期为1ms,然后每次进入中断为我们的框架计数即可。
/******************************************************************************
* 描述 :SysTick中断服务程序
* 参数 :无
* 返回 :无
******************************************************************************/
void SysTick_Handler(void)
{
/* 为zorb framework提供计时 */
ZF_timeTick();
}
现在时间系统提供的功能比较基础,只有系统滴答计数和系统死等待延时,后面我们开发定时器功能和任务功能的时候会重新扩展时间系统。
/**
*****************************************************************************
* @file zf_time.h
* @author Zorb
* @version V1.0.0
* @date 2018-06-28
* @brief 系统时间的头文件
*****************************************************************************
* @history
*
* 1. Date:2018-06-28
* Author:Zorb
* Modification:建立文件
*
*****************************************************************************
*/
#ifndef __ZF_TIME_H__
#define __ZF_TIME_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stdbool.h"
#include "stdint.h"
/* 系统滴答周期(ms) */
#define ZF_TICK_PERIOD 1
/* 获取系统滴答数 */
#define ZF_SYSTICK() ZF_getSystemTick()
/* 获取系统时间(ms) */
#define ZF_SYSTIME_MS() ZF_getSystemTimeMS()
/* 系统延时(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)
/* 获取系统滴答数 */
uint32_t ZF_getSystemTick(void);
/* 获取系统时间(ms) */
uint32_t ZF_getSystemTimeMS(void);
/* 系统延时 */
void ZF_delayTick(uint32_t tick);
/* 系统滴答程序(需挂在硬件的时间中断里边) */
void ZF_timeTick (void);
#ifdef __cplusplus
}
#endif
#endif /* __ZF_TIME_H__ */
/******************************** END OF FILE ********************************/
最后
本篇实现的功能比较基础,但是整个框架开发的根基,后面所有扩展的功能都需要在此环境下进行开发。
搭建良好的调试输出环境,可以帮我们快速定位bug的所在,从而提高开发效率。
Github 地址
https://github.com/54zorb/Zorb-Framework
End
「汽车电子嵌入式在CSDN上同步推出AUTOSAR精进之路专栏,本专栏每个模块完全按实际项目中开发及维护过程来详细介绍。模块核心概念介绍、实际需求描述、实际工程配置、特殊需求介绍及背后原理、实际工程使用经验总结。目的是让读者看完每一个章节后能理解原理后根据需求完成一个模块的配置或者解决一个问题。」
点击文章最后左下角的阅读原文可以获取更多信息
或者复制如下链接到浏览器获取更多信息
https://blog.csdn.net/qq_36056498/article/details/132125693
文末福利
2.为便于技术交流,创建了汽车电子嵌入式技术交流群,可尽情探讨AP,CP,DDS,SOME/IP等前沿热点话题,后台回复“加群”即可加入;
注:本文引用了一些第三方工具和文档,若有侵权,请联系作者删除!
推荐阅读
汽车电子嵌入式精彩文章汇总第一期:20210530-20230703
AUTOSAR 架构下EcuM唤醒源事件详解
AUTOSAR架构下NVM Block连续写及Default Value问题分析
AUTOSAR架构下NvM模块详细分析
AUTOSAR架构下报文掉线超时不上报问题分析
Classic Autosar下的以太网通讯架构概览
通信中间件Someip服务化通信
AUTOSAR架构下Fee详细分析
TC37x芯片FLASH基本概念介绍
AUTOSAR架构下Fls详细分析
TC3xx芯片DMU介绍
TC3xx芯片MPU介绍
TC3xx芯片的Trap详解
AUTOSAR架构下的OS错误处理
AUTOSAR架构下QM Application如何访问ASIL Application
AUTOSAR架构下多核启动
TC3xx芯片的Trap详解(二)
AUTOSAR架构下多核Shutdown
AUTOSAR架构下多核通信
RH850U2A芯片平台Spinlock的底层实现
TC3xx芯片Clock System功能详解-时钟源OSC
TC3xx芯片Clock System功能详解-锁相环PLL
TC3xx芯片Clock System功能详解-时钟分配CCU
End
欢迎点赞,关注,转发,在看,您的每一次鼓励,都是我最大的动力!
汽车电子嵌入式
微信扫描二维码,关注我的公众号