基于LED和串口通信的DBC调试工具:HAssert --- Hyper LED/Serial Assert 。

本文基于DbC思想 ,在Arduino平台上实现了两种断言显示方式---LED显示和串口输出显示。
LED显示方式
适用于没有串口(这种情况很少),或者串口已经被占用的情况,只用一个LED的显示次数来调试程序;
串口输出显示方式
可以把断言内容传送到PC机,在PC机看到出错的位置(文件名和行号)。
以下的HAssert.h和HAssert.cpp实现了DbC调试的断言。

一.HAssert.h头文件

#ifndef H_ASSERT_H
#define H_ASSERT_H
#include <stdint.h> // C99-standard exact-width integers
#include <avr/pgmspace.h>
//#define ROM_BYTE(rom_var_) pgm_read_byte_near(&(rom_var_))
//#define ROM PROGMEM
/// 1.有/无断言选择开关(配置1)
// (1)调试时, H_ASSERT = 1,断言有效
// (2)发布软件时,H_ASSERT = 0,自动去掉代码中插入的所有断言
#define H_ASSERT_EN 1
///2.LED/串口显示断言选择开关(配置2)
//(1)H_LED_ASSERT_EN = 1时,选择LED显示断言
//(2)H_LED_ASSERT_EN = 0时,选择串口显示断言
#define H_LED_ASSERT_EN 0
//=================================================
/// 状态LED引脚 (配置3)
#define H_ASSERT_LED_PIN 13 //Arduino板用13; MSR和SWT板用RxErr状态LED,7.
/// 状态LED延时时间(配置4)
// (1)仿真用了10000ms, 实际上可以修改成1秒的时间
#define H_ASSERT_LED_DELAY_TIME 1000 // ms
//================================================
///3.H_ASSERT_EN == 0,去掉断言宏
#if H_ASSERT_EN == 0
#define H_ASSERT_ID(id, test)
#define H_REQUIRE_ID(id, test)
#define H_ERROR_ID(id)
#define H_BREAKPOINT_ID(id)
#define H_DEFINE_THIS_FILE
#define H_DEFINE_THIS_MODULE(name_)
#define H_ASSERT(test)
#define H_REQUIRE(test)
#define H_ERROR()
#define H_BREAK_POINT()
///4.H_ASSERT_EN == 1,加入断言宏
#else
///4.0.声明断言函数
#ifdef __cplusplus
extern "C" {
#endif
void H_onAssert_id(uint8_t id); //LED显示断言回调函数声明
void H_onAssert(char const PROGMEM * const file, int line); //串口显示断言回调函数声明
#ifdef __cplusplus
}
#endif
///4.1.LED断言宏
#if H_LED_ASSERT_EN == 1
///LED断言---带id参数
//(1).id参数可以指示错误分类等,如用LED闪亮的次数分类
//(2). 建议id = 2~255, id=0和1都算做1次,以下类同
///断言宏
#define H_ASSERT_ID(id, test) if (test) { \
} \
else (H_onAssert_id((id)))
///必要条件
#define H_REQUIRE_ID(id, test) H_ASSERT_ID(id, test)
///错误
#define H_ERROR_ID(id) (H_onAssert_id((id)))
///断点
#define H_BREAKPOINT_ID(id) (H_onAssert_id((id)))
///4.2.串口断言宏
#else
///加入到每个文件的#include "HSAssert.h"之后,文件的前边。
//绝对路径文件,太长!
#define H_DEFINE_THIS_FILE \
static char const PROGMEM l_file[] = __FILE__;
///自己写文件名,或模块名
#define H_DEFINE_THIS_MODULE(module_name_) \
static char const PROGMEM l_file[] = #module_name_;
///断言宏
#define H_ASSERT(test) if (test) {\
} \
else (H_onAssert(l_file, __LINE__))
///必要条件
#define H_REQUIRE(test) H_ASSERT(test)
///错误
#define H_ERROR() (H_onAssert(l_file, __LINE__))
///断点 停止
#define H_BREAKPOINT() { Serial.print("--- Breakpoint --- ");\
(H_onAssert(l_file, __LINE__)); \
cli();\
while(1);\
} while(0)
#endif
#endif
#endif

二.HAssert.cpp文件

#include <Arduino.h>
#include "HAssert.h"
///1.LED断言函数实现---显示闪亮次数
//(1).用一个LED亮表示有错,闪亮次数表示错误类型
//(2).有代码中不同的位置放id不同的断言宏,用闪亮的次数表示错误类型
//(3).建议id = 2~255,不建议用0和1.
//(4).有错误就会停止
void H_onAssert_id(uint8_t id) {
pinMode(H_ASSERT_LED_PIN, OUTPUT);
sei();
delay(H_ASSERT_LED_DELAY_TIME);
for (uint8_t i = 0; i < id; i++) {
digitalWrite(H_ASSERT_LED_PIN, LOW);
delay(H_ASSERT_LED_DELAY_TIME);
digitalWrite(H_ASSERT_LED_PIN, HIGH);
delay(H_ASSERT_LED_DELAY_TIME);
}
cli();
while(1) { ; } //停止,断言不会返回,错误就得处理掉!
//asm volatile ("jmp 0x0000"); // 复位
}
///2.串行断言函数实现---显示文件和出错行
//只有H_BREAKPOINT()会停止
void H_onAssert(char const PROGMEM * const file, int line) {
int i =0 ;
char ch, buffer[60];
do {
ch = (char)pgm_read_word(file + i);
buffer[i++] = ch;
} while((ch != 0)&&(i < 60) );
Serial.print(line - 3,DEC); Serial.print(" Line Error in ");
Serial.print(buffer); Serial.println(" file.");
}

三.DbC测试程序

1.利用LED的DbC测试

//////////////////////////////////////////////////////////////////////////////
// 名称:利用LED的DbC测试
//////////////////////////////////////////////////////////////////////////////
///LED断言要求:HAssert.h中
//配置1:H_ASSERT_EN = 1
//配置2:H_LED_ASSERT_EN = 1
#include "HAssert.h"
void setup() {
}
void loop() {
uint8_t x = 5;
uint8_t y = 6;
H_REQUIRE_ID(2,x==y); //判断逻辑错误时,闪亮2次,最后保持亮
H_REQUIRE_ID(3,x != y); //判断逻辑正确时,不亮
H_ERROR_ID(10); //闪亮10次,最后保持亮
H_BREAKPOINT_ID(10);//与 H_ERROR_ID(10)一样 delay(100);
while(1);
}

2.利用串口通信的DbC测试

 //////////////////////////////////////////////////////////////////////////////
// 名称:利用串口通信的DbC测试
//////////////////////////////////////////////////////////////////////////////
///串口断言要求:HAssert.h中
//配置1:H_ASSERT_EN = 1
//配置2:H_LED_ASSERT_EN = 0
#include "HAssert.h"
#include <Arduino.h>
H_DEFINE_THIS_MODULE("Test_HAssert.ino") //自己写文件名
//HS_DEFINE_THIS_FILE //绝对路径文件,太长!不用
void setup() {
Serial.begin(9600);
}
void loop() {
uint8_t x = 5;
uint8_t y = 6;
H_ASSERT(false);
H_REQUIRE(x == y);
H_REQUIRE(x != y); //满足条件,不输出
H_ERROR();
H_BREAKPOINT();
delay(100);
//while(1);
}

四.串口通信DbC测试效果

本文中只给出串口DbC测试的运行效果,LED的DbC测试是在Arduino板上用LED闪亮次数来表示出错的位置。

Arduino平台基于DbC的软件调试的更多相关文章

  1. 《软件调试的艺术》学习笔记——GDB使用技巧摘要

    <软件调试的艺术>学习笔记——GDB使用技巧摘要 <软件调试的艺术>,因为名是The Art of Debugging with GDB, DDD, and Eclipse. ...

  2. 洪强宁:宜信PaaS平台基于Calico的容器网络实践

    洪强宁:宜信PaaS平台基于Calico的容器网络实践   本文内容来自由七牛云主办的ECUG Con,独家授权InfoQ整理完成 容器云面临的网络挑战 在传统的IDC的架构里面网络是很重要的事情,在 ...

  3. <读书笔记>软件调试之道 :从大局看调试-零容忍策略

    声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! ---------------------------------------- ...

  4. 10月12号 晚八点 Speed-BI 云平台-基于Excel数据源的管理驾驶舱构建全过程,腾讯课堂开课啦

    认真地做了一大摞一大摞的报表,老板没时间看?努力把能反馈的内容都融汇进图表里,老板嫌复杂?做了几个简单的报表,老板一眼就觉得信息不全面?每个报表都用了各种各样的图表,老板却毫无兴趣?明明很努力了,为什 ...

  5. PfSense基于BSD的软件防火墙的安装、配置与应用

    PfSense基于BSD的软件防火墙的安装.配置与应用 PfSense是一个FreeBSD下的免费开源的防火墙和路由器软件,他为了在X86平台上面建立一个高集成性的防火墙项目,下面就为大家展示如何配置 ...

  6. 【小梅哥FPGA进阶教程】第九章 基于串口猎人软件的串口示波器

    九.基于串口猎人软件的串口示波器 1.实验介绍 本实验,为芯航线开发板的综合实验,该实验利用芯航线开发板上的ADC.独立按键.UART等外设,搭建了一个具备丰富功能的数据采集卡,芯航线开发板负责进行数 ...

  7. centos平台基于snort、barnyard2以及base的IDS(入侵检测系统)的搭建与测试及所遇问题汇总

    centos平台基于snort.barnyard2以及base的IDS(入侵检测系统)的搭建与测试及所遇问题汇总 原创 2016年12月19日 01:20:03 标签: centos / snort  ...

  8. 基于Azure的软件部署和开发系列沙龙

    活动简介: Azure是一种灵活和支持互操作的平台,它可以被用来创建云中运行的应用或者通过基于云的特性来加强现有应用.它开放式的架构给开发者提供了Web应用.互联设备的应用.个人电脑.服务器.或者提供 ...

  9. .net平台 基于 XMPP协议的即时消息服务端简单实现

    .net平台 基于 XMPP协议的即时消息服务端简单实现 昨天抽空学习了一下XMPP,在网上找了好久,中文的资料太少了所以做这个简单的例子,今天才完成.公司也正在准备开发基于XMPP协议的即时通讯工具 ...

随机推荐

  1. LDA概率图模型之贝叶斯理解

    贝叶斯.概率分布与机器学习 转自:http://www.cnblogs.com/LeftNotEasy/archive/2010/09/27/1837163.html  本文由LeftNotEasy原 ...

  2. Angular js 过滤器 笔记(转自菜鸟教程)

    1.uppercase,lowercase 大小写转换 {{ "lower cap string" | uppercase }} // 结果:LOWER CAP STRING {{ ...

  3. Android应用开发基础之一:数据存储和界面展现(一)

    Android项目的目录结构 Activity:应用被打开时显示的界面 src:项目代码 R.java:项目中所有资源文件的资源id Android.jar:Android的jar包,导入此包方可使用 ...

  4. 使用 SQL SERVER PROFILER 监测死锁

    作为DBA,可能经常会遇到有同事或者客户反映经常发生死锁,影响了系统的使用.此时,你需要尽快侦测和处理这类问题. 死锁是当两个或者以上的事务互相阻塞引起的.在这种情况下两个事务会无限期地等待对方释放资 ...

  5. Zabbix监控 windows agent安装配置

    下载Windows的zabbix客户端 载地址:http://www.zabbix.com/download.php 选择windows版本的agent下载 从官方下载Zabbix Agent后,压缩 ...

  6. pl/sql 存储过程执行execute immediate 卡住

    在存储过程中,执行了create table.update table.insert into table 但是在使用pl/sql的存储过程调试的时候,一有问题就直接卡住(标识:执行中.....) 后 ...

  7. Jmeter入门12 __time函数 jmeter获取当前系统时间

    有的接口要传递当前的日期或时间,可以用__time()函数获取当前时间 ${__time()} 当前时间到计算机元年的毫秒数 ${__time(时间格式)}  以预定的格式显示当前时间  请求示例: ...

  8. PHP使用memcache长连接作为RPC客户端需要注意的地方

    memcache扩展版本 3.0.8 一. retry_interval $retry_interval 某个rpc服务器端失败后故障转移的时间,retry_interval的时间内,该节点会被一直标 ...

  9. 让免费版MarkdownPad2使用Pro版本的功能

    让免费版MarkdownPad2使用Pro版本的功能 找到配置文件 启用Markdown扩展模式 Markdown处理器:Github风格 语法检查设置 自动保存设置 找到配置文件 一般在用户的数据目 ...

  10. 用批处理在windows中导出/导入无线网络信息,复制保存为bat即可

    @echo offtitle 在windows中导出/导入无线网络信息 :Beginecho ========================echo 请选择操作:echo 1 查看可用的无线网络ec ...