今天周六,写点轻松一点的内容,相信很多朋友都有使用宏定义的经历。宏定义写得好,你的代码修改、调试、移植等都方便;相反,写的不好,可能你的头脑会炸掉。
1问题来源
我前面移植一部分代码,忽略了一些细节问题,直接测试,一有数据(正常应该是进入中断),程序就挂了,进入了“b .”处,如下图:
这代表什么意思呢?网上一搜b .的意思就知道,程序运行到这个地方,在这里死循环了。
2问题跟踪,并解决
遇到上面问题,于是我就开始了在线调试查找问题。果然,在线调试一眼就看出了问题,中断函数体没有被触发,先看下图:
看上图,经常调试的人就知道,前面没有灰色的标记代表程序不会运行到这个位置。
上面那个debug_com_irqhandler函数,我使用的是宏定义:
那么,问题来了,我使用了宏定义中断函数接口,为什么没有进入中断函数?
问题就出在宏定义和被定义函数体的包含关系,简单说就是:stm32f4xx_it.c文件里面应该添加#include bsp_usart.h这行代码。
不添加包含宏定义的文件,编译时就会把debug_com_irqhandler当做成一个普通函数,也不会出错。此时,中断函数其实是没有定义的,那么,程序运行中断函数时,没有定义函数体,自然就会跳转到b .处去。
解决的办法就如上所说:stm32f4xx_it.c文件添加添加#include bsp_usart.h即可。
3总结
针对以上问题,拓展并总结几点内容:
1.宏定义注意事项
宏定义与源代码最好要高度一致,就拿usart时钟的宏定义来说,如下这种方式就容易出错。
宏定义:
#define debug_com_clk rcc_apb2periph_usart1
调用方式:
rcc_apb2periphclockcmd(debug_com_clk, enable);
假如我修改时钟:
rcc_apb2periph_usart1改为rcc_apb1periph_usart2
发现问题没有:
apb2和apb1混乱调用了。
2.b .含义
这里提出来,是让有些初学者顺便了解一下(其实网上一搜就明白)。这是一个汇编指令,“b”代表不返回的跳转,比如跳到某个标号处。“.”是指定当前的地址,b .这条指令,其实就是死循环。
3.在线调试代码覆盖
经常有朋友问题:我在线调试,为什么有些地方不能打断点?处理需要配置输出调试信息之外,就是这里说的代码覆盖问题。
看见我上面有两个中断函数那张图没有,里面我有文字说明:前面有灰色标记的代码,代表程序可执行(已覆盖)。相反,则没有被覆盖。
4.中断函数接口宏定义
一般很多初学者不知道函数接口可以使用宏定义。其实,有很多地方,包括一些标准的代码都有用到使用宏定义函数接口。拿我们比较熟悉的freertos来说,为了移植方便,使用宏定义三个中断函数,如下图:
这里需要注意的就如上面分析的,包含关系需加上。
唐华斌:OOTII项目进展符合预期,业务负载能力是重要挑战
华为余承东:2021年华为手机将全面支持鸿蒙OS 2.0
采用运放实现的单按键开关电路图
max6675 c语言程序
锂电池材料之磷酸铁锂
宏定义 “中断函数接口”的注意事项
VR实验课上线 虚拟现实赋能教育
运营商美股退市是早应该有预期的
关于机器人3D视觉的几种典型方案
英国真尚有激光位移传感器用于轨道交通中桥梁梁体位移监测
深圳民企成低碳经济“急先锋”
华为目前最好的一款手机:荣耀8!估计连iphone都很难和它媲美
魅族Pro6升级版Pro6Plus开箱评测:弃用联发科 用上三星核心真旗舰性能如何?
基于FPGA便携式数据采集可使用GAD2245,兼容LTC2245
嵌入式工控机主板出现故障时该如何解决
百度谢永康:加速AI平台化建设,让开发者人人可用
电瓶修复技术—充电是否可以估算电池容量
一加7Pro与iPhoneXSMax屏幕对比 区别到底有多大
一文搞懂割接到底是什么?
如果比特币被违反了GDPR规则,那么欧盟会对谁处以罚款