【嵌入式项目应用】__用于搭建调试输出、建立时间系统的嵌入式框架“Zorb Framework”

目录

一、什么是Zorb?

二、嵌入式环境搭建

三、调试输出

四、实现断言

五、建立时间系统

六、结束语

(* ̄︶ ̄)创作不易!期待你们的 点赞、收藏和评论喔。


一、什么是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
  7. 任务功能zf_task

前6个功能,就可以实现纯事件驱动的程序,基本可以满足中小型嵌入式应用程序开发的需求。加上任务功能,是为了满足部分程序对实时性要求较高的需求。当然,也可以将前6个功能裁剪出来,然后运行在现有的嵌入式系统上面,这样子也可以满足实时性的需求。

二、嵌入式环境搭建

采用 STM32F429 开发板作为硬件运行环境,硬件资源用到串口1systick,

其中串口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的所在,从而提高开发效率。

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


(* ̄︶ ̄)创作不易!期待你们的 点赞收藏评论喔。

本文来源网络,免费分享知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/176519.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库的事务四大特性(ACID)、详解隔离性以及隔离级别、锁

文章目录 🎉数据库的事务四大特性(ACID)以及隔离性一、事务的四大特性✨1、原子性(Atomicity)🎊2、一致性(Consistency)🎊3、隔离性(Isolation)&a…

双十一首日捷报 | 德施曼率先破亿,再度蝉联智能锁品类第一

10月31日晚8:00,各大平台迎来了双十一第一波现货开售。其中,在智能锁类目中德施曼势头最为迅猛,此前,德施曼凭借“全民换锁季”主题活动,在预售期间就已经全面引爆消费者换锁热潮,随着此次现货开售&#xf…

Linux内存管理的分页机制

分段机制的原理如下: 分段机制下的虚拟地址由两部分组成,段选择子和段内偏移量。段选择子就保存在段寄存器里面。段选择子里面最重要的是段号,用作段表的索引。段表里面保存的是这个段的基地址、段的界限和特权等级等。虚拟地址中的段内偏移量…

bitlocker恢复保护时出现 驱动器加密错误 向导初始化失败 系统找不到指定文件

环境: Win 10专业版 联想E14 Gen2 问题描述: bitlocker恢复保护时出现 驱动器加密错误 向导初始化失败 系统找不到指定文件 电脑更换主板后,重新恢复保护出现 驱动器加密错误 解决方案: 1.尝试重启电脑(未解决&a…

Java进阶(List)——面试时List常见问题解读 结合源码分析

前言 List、Set、HashMap作为Java中常用的集合,需要深入认识其原理和特性。 本篇博客介绍常见的关于Java中List集合的面试问题,结合源码分析题目背后的知识点。 关于的Set的博客文章如下: Java进阶(Set)——面试时…

PowerToys使用:Windows自定义键盘(非编程)

使用紧凑型键盘或者苹果键盘有时候觉得挺麻烦,常用的键偏偏没有,特别是苹果键盘,没有【del】键,非常非常不爽。 笔记本电脑用久了,难免弄坏一两个键,比如【s】键,维修挺麻烦的,换新太…

爬虫 | 【实践】百度搜索链接爬取,生成标题词云 | 以“AI换脸”为例

目录 📚链接爬取 🐇流程梳理 🐇代码实现 🐇结果 📚词云生成 🐇代码实现 🐇结果 📚链接爬取 🐇流程梳理 总体流程是:构建搜索链接 -> 发送HTTP请求…

脉冲输出的三种模式

1.脉冲 方向 2.CW/CCW 3.A/B相(AB正交脉冲) 脉冲输出模式: 是指控制信号是单脉冲方式还是双脉冲方式,主要由控制器决定; 如果控制器发送的控制脉冲是单脉冲控制方式,驱动器需要采用单脉冲&#xff1b…

为什么要安装防静电门禁闸机

安装防静电门禁闸机可以带来以下几个方面的好处: 防止静电干扰:静电是一种非常危险的物理现象,它可以对电子元器件、电路板和其他敏感设备造成损害,甚至导致设备故障和生产中断。防静电门禁闸机可以有效地防止静电的产生和传导&am…

Spring Security 中自定义权限表达式

Spring Security 中自定义权限表达式 一. SpEL中使用自定义Bean二. 通过类继承自定义权限表达式2.1 自定义 ExpressionRoot 三. 参考文章 前言 这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。 作者:神的孩子都在…

Linux学习第27天:Platform设备驱动开发(一): 专注与分散

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 专注与分散是我在题目中着重说明的一个内容。这是今天我们要学习分离与分层概念的延伸。专注是说我们要专注某层驱动的开发,而对于其他层则是芯片厂商…

robot framework导入库和资源

robot framework导入库和资源 一 导入系统库和第三方库(Library)二 导入自己写的py文件三 建立资源作为关键字3.1 创建资源3.2 在资源里创建用户关键字3.3 使用用户关键字 四 将自己写的py文件中类的函数作为关键字4. 1编写py文件,文件名和里…

搭建VM虚拟机+Centos7 Oracle版 + 配置ssh + Xftp + secureCRT

文章目录 1 视频地址1.1 基本参数1.2 ISO下载地址:1.3 开启ssh1.3.1 使用root用户进行1.3.2 修改ssh配置1.3.3 关闭 SELINUX 2 查询虚拟机的ip2.1 联网2.2 桌面打开终端查询虚拟机ip 3 连接Xftp4 连接SecureRT 1 视频地址 01-搭建VM虚拟机Centos7 Oracle版 配置ss…

计算机网络-IP地址

文章目录 子网划分定长子网划分子网划分的方法子网掩码 可变长子网划分 无类别编址网络前缀路由聚合 特殊用途的IP地址专用网络地址链路本地地址运营商级NAT共享地址用于文档的测试网络地址 IP地址的规划和分配IP地址的规划和分配方法IP地址的规划和分配实例 子网划分 定长子网…

基于未来搜索算法的无人机航迹规划-附代码

基于未来搜索算法的无人机航迹规划 文章目录 基于未来搜索算法的无人机航迹规划1.未来搜索搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用未来搜索算法来优化无人机航迹规划。 …

装备制造行业云MES解决方案

一、装备制造行业发展现状: 机械制造业主要是通过对金属原材料物理形状的改变、加工组装进而成为产品。机械制造业生产的主要特点是:离散为主、流程为辅、装配为重点。 工业生产基本上分为两大方式: 1.离散型:离散型是指以一个…

《数据安全与流通:技术、架构与实践》新书发布

随着数据成为关键生产资料和要素,国内外数据安全相关的法律法规在快速完善,数据安全技术也在快速发展。5月25-26日,由星环科技、上海数据交易所、上海大数据联盟、财联社联合主办的向星力未来数据技术峰会 (FDTC)上&am…

C#__委托delegate

委托存储的是函数的引用(把某个函数赋值给一个委托类型的变量,这样的话这个变量就可以当成这个函数来进行使用了) 委托类型跟整型类型、浮点型类型一样,也是一种类型,是一种存储函数引用的类型 using System.Reflec…

目标检测理论知识

目标检测 1.基本概念 目标检测(Object Detection)的任务是找出图像中所有感兴趣的目标(物体),确定它们的类别和位置,是计算机视觉领域的核心问题之一。由于各类物体有不同的外观、形状和姿态,…

安装最新版vue-cli,并搭建一个vue2项目

安装最新版vue-cli,并搭建一个vue2项目 卸载旧版本环境 卸载node.js 可以使用qq电脑管家,找到nodejs卸载即可 cmd查看vue cli版本(可以看到我们是vue cli 2.x) C:\Users\youzhengjie666> vue -V 2.9.6卸载vue cli 2.x np…