当前位置: 首页 > news >正文

Linux动态debug使用方法

打开驱动中的动态打印方法什么是动态打印动态打印跟 printk 的主要区别在于动态打印在进入系统后可以手动控制是否开启打印能具体到某个驱动甚至驱动中的某个函数的打印。如何使用调试驱动的时候有些中断中的打印用printk很容易造成内核崩溃但是有些人家已经加好的打印之前不知道怎么使用这次就介绍一下使用方法。在调试全志T717 openEuler内核的uart驱动的时候想看下串口接收到的数据人家驱动中(sunxi-uart.c)其实已经加好了打印了只需要咱们把他打开就能通过 “dmesg -w” 来看了先看下驱动源码中是怎么写的static unsigned int sw_uart_handle_rx(struct sw_uart_port *sw_uport, unsigned int lsr) { unsigned char ch 0; int max_count 256; char flag; /* * * */ //在这会通过SERIAL_DBG将收到的每个字符打印出来 SERIAL_DBG(sw_uport-port.dev, receive data 0x%x\n, ch); uart_insert_char(sw_uport-port, lsr, SUNXI_UART_LSR_OE, ch, flag); lsr serial_in(sw_uport-port, SUNXI_UART_LSR); return lsr; }然后看下 “SERIAL_DBG” 的宏定义#define SERIAL_DBG(dev, fmt, arg...) \ do { \ if (!sw_is_console_port(sw_uport-port)) \ sunxi_debug(dev, %s()%d - fmt, __func__, __LINE__, ##arg); \ } while (0) /* 再看下sunxi_debug宏定义 */ /* void sunxi_debug(struct device *dev, char *fmt, ...); */ #define sunxi_debug(dev, fmt, ...) \ do { if (dev) \ pr_debug(-%s:[DEBUG]: fmt, sunxi_log_dev_name(dev), ## __VA_ARGS__); \ else \ pr_debug(:[DEBUG]: fmt, ## __VA_ARGS__); \ } while (0) /* CONFIG_AW_LOG_VERBOSE */可以看到要想使用“sunxi_debug”这个宏要先打开CONFIG_AW_LOG_VERBOSE然后还要打开内核的动态打印功能所以一共需要在defconfig中添加三个宏定义# 打开全志的日志打印 CONFIG_AW_LOG_VERBOSEy #打开内核动态打印支持 CONFIG_DYNAMIC_DEBUGy CONFIG_DYNAMIC_DEBUG_COREy打开完了重新编译并烧录内核以后就可以在 /sys/kernel/debug/dynamic_debug/control 中查看动态打印都支持写什么打印了这个动态打印默认是关闭的需要手动去修改下 control 文件将打印打开打开方法如下# 打开bsp/drivers/uart/sunxi-uart.c 这个驱动中的所有动态打印echofile bsp/drivers/uart/sunxi-uart.c p/sys/kernel/debug/dynamic_debug/control# 修改下内核的打印登记直接拉满echo8/proc/sys/kernel/printk# 使用dmesg -w 动态更新打印这个就跟tail -F 一样的dmesg-w自己驱动中怎么使用debug这些打印的宏定义在 openeuler-kernel-t717/include/linux/printk.h 中其中pr_emerg() pr_alert() pr_crit() pr_err() pr_warn() pr_notice() pr_info()这些都是printk level 的封装如#define pr_err(fmt, ...) \ printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)只有pr_debug()会用到动态打印他的宏定义如下/* If you are writing a driver, please use dev_dbg instead */ #if defined(CONFIG_DYNAMIC_DEBUG) || \ (defined(CONFIG_DYNAMIC_DEBUG_CORE) defined(DYNAMIC_DEBUG_MODULE)) #include linux/dynamic_debug.h /** * pr_debug - Print a debug-level message conditionally * fmt: format string * ...: arguments for the format string * * This macro expands to dynamic_pr_debug() if CONFIG_DYNAMIC_DEBUG is * set. Otherwise, if DEBUG is defined, its equivalent to a printk with * KERN_DEBUG loglevel. If DEBUG is not defined it does nothing. * * It uses pr_fmt() to generate the format string (dynamic_pr_debug() uses * pr_fmt() internally). */ #define pr_debug(fmt, ...) \ dynamic_pr_debug(fmt, ##__VA_ARGS__) #elif defined(DEBUG) #define pr_debug(fmt, ...) \ printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) #else #define pr_debug(fmt, ...) \ no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) #endif如果打开了CONFIG_DYNAMIC_DEBUG那么pr_debug()就会调用dynamic_pr_debug()否则如果定义了DEBUG宏那么pr_debug()就会调用printk()否则就会调用no_printk()。但是你看最开始一行写着如果你在写一个驱动请使用dev_dbg(),下面来看下dev_dbg()的宏定义openeuler-kernel-t717/include/linux/dev_printk.h#ifndef dev_fmt #define dev_fmt(fmt) fmt #endif #define dev_emerg(dev, fmt, ...) \ _dev_emerg(dev, dev_fmt(fmt), ##__VA_ARGS__) #define dev_crit(dev, fmt, ...) \ _dev_crit(dev, dev_fmt(fmt), ##__VA_ARGS__) #define dev_alert(dev, fmt, ...) \ _dev_alert(dev, dev_fmt(fmt), ##__VA_ARGS__) #define dev_err(dev, fmt, ...) \ _dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__) #define dev_warn(dev, fmt, ...) \ _dev_warn(dev, dev_fmt(fmt), ##__VA_ARGS__) #define dev_notice(dev, fmt, ...) \ _dev_notice(dev, dev_fmt(fmt), ##__VA_ARGS__) #define dev_info(dev, fmt, ...) \ _dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__) #if defined(CONFIG_DYNAMIC_DEBUG) || \ (defined(CONFIG_DYNAMIC_DEBUG_CORE) defined(DYNAMIC_DEBUG_MODULE)) #define dev_dbg(dev, fmt, ...) \ dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__) #elif defined(DEBUG) #define dev_dbg(dev, fmt, ...) \ dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__) #else #define dev_dbg(dev, fmt, ...) \ ({ \ if (0) \ dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ }) #endifdev的打印会自动给加设备名会传入dev嘛就是struct device * 类型的设备指针这个会打印设备名所以在写驱动的时候优先使用这个。
http://www.gsyq.cn/news/1343636.html

相关文章:

  • C++变参模板应用
  • 把 Cocos Creator 编辑器接入 AI:Funplay MCP for Cocos 介绍
  • C 语言通讯录(终版)|新手踩坑全总结 + 最终可运行代码博客简介
  • C 语言通讯录(终版)|新手踩坑全总结 + 最终可运行代码博客简介
  • 天勤策略钉钉告警:交易信号与异常通知怎么分流
  • 淮南家长必看:淮南哪里学少儿编程靠谱?原来这样选才不踩坑。
  • VMware虚拟机安装及配置
  • AI API 中转站完全指南:从 Claude、GPT 到“满血”“翻车”,一次搞懂整个 AI API 圈子
  • 一幅精细绝伦的[城市或地点]微缩模型
  • (QBuffer配合 QDataStream)二进制序列化
  • ISCC2026 pwn Ring factory
  • 主芯片LP3717BTT+LP3568C,5V3.1A过认证适配器⽅案(电路原理图)
  • 微信机器人二次开发框架
  • 三、深入理解MySQL索引底层
  • DDD 中的代码组织:按技术层分 vs 按领域模块分,哪种才是正解?
  • 从CDP“3A”到千亿美元目标:联想集团的创新路径与AI原生转型
  • 2026最新诚信优选 安顺市平坝区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • 解密Palantir系列一:1. 决策的三元闭环
  • 2026最新诚信优选 安顺市西秀区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • 2026最新诚信优选 安阳市龙安区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • AI API 实践三:为什么要关注 Token,而不只是请求次数?
  • 2026最新诚信优选 安阳市文峰区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • 批量将目录下的栅格数据重采样至不同分辨率
  • 影刀RPA 从0到1:自动化系统架构收敛与工程化演进总结
  • 【JUC】线程
  • 2026最新诚信优选 重庆市铜梁区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • 2026:AI超级员工崛起,谁是真正的市场赢家?
  • 2026最新诚信优选 重庆市开州区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • 2026最新诚信优选 重庆市梁平区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • 2026最新诚信优选 上海市宝山区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收