查看定义的外设头文件地址是否正确

通常我们喜欢将一个外设的寄存器定义成一个结构体的形式来访问,但有些外设寄存器比较庞大,同时寄存器地址不连续,跨度也比较大,这样我们在定义头文件的时候就比较麻烦了,编写完成后一定要检查一遍,避免以后捅娄子。今天分享一个较为方便的检查方法。

uart_hw.h

#ifndef _UART_HW_H_
#define _UART_HW_H_

typedef volatile unsigned int _RW;
typedef volatile unsigned int _W;
typedef volatile const unsigned int _R;
typedef const unsigned int _NU;
#define BASE_UART_ADDR  0x40000000

typedef struct {
	union {
		_R RXH;    /* Offset 0x00 */
		_W TXH;    /*  Offset 0x00*/
	};
	_RW BAUD;      /*  Offset 0x04*/
	_RW CON;       /*  Reserved 0x04*/
	_NU RESERVED0[1];      /*  Reserved 0x04*/
	_RW SR;        /*  Reserved 0x10*/
	_NU RESERVED1[3];     /*  Reserved 0x0C*/
	_RW IE;        /*  Reserved 0x20*/
} UART_Struct;

#define UART   ((UART_Struct *)BASE_UART_ADDR)

#endif /* _UART_HW_H_ */

此处使用Linux,我直接写个PC的程序来打印各个寄存器成员的实际地址。

main.c

#include "uart_hw.h"

#define AA(x,y)  volatile uint32_t *addr##x = (uint32_t *)y

int main(int argc, char *argv[])
{
	(void)argc;
	(void)argv;
	/* 此处仅仅是引用uart_hw.h文件中的内容,目的是编译时
	 * 让gcc将uart_hw.h中的信息包含进来 。若有多个IP,则
	 * 可以继续定义AA(1, SPI)等等。该数字仅仅是保证定义的
	 * 变量不重复,无它用。 */
	AA(0, UART);
	while(1);
}

编译运行

$ gcc -g3 main.c -Idrivers/include(此处`-I`后面为uart_hw.h的相对/绝对路径)
$ gdb a.out
(gdb) r
此处会退出将gdb切到后台,需要CTRL+D退出shell回到gdb,在CTRL+C,让程序停下来。
(gdb) source uart_hw.gdb
(gdb) uart
========== UART ==========
0x40000000 RXH
0x40000000 TXH
0x40000004 BAUD
0x40000008 CON
0x40000010 SR
0x40000020 IE
(gdb) q
$

这里我们就可以比较直观的对比各个寄存器成员的实际地址与手册上的差异了。下面我们需要来编写uart_hw.gdb。需要使用vim编辑器,因为它支持块编辑。

  1. 拷贝uart_hw.h为uart_hw.gdb:cp uart_hw.h uart_hw.gdb
  2. 使用vi打开uart_hw.gdb:vi uart_hw.gdb
  3. 以下在vi中操作,定位到文件头:gg
  4. 删除前11行,删除union {及以前的内容:d11d
  5. 定位到UART_Struct行,删除至结尾:dG
  6. 删除包含RESERVED的行::g/RESERVED/d
  7. 删除;至行尾::%s/;.*$//g
  8. 定位到_R RXH这两行,删除行首空白将其与下面的成员对齐:x
  9. 定位并删除}这一行:dd

当前处理结果如下:

uart_hw.gdb

	_R  RXH
	_W  TXH
	_RW BAUD
	_RW CON
	_RW SR
	_RW IE
  1. 定位到_R RXH中第一个R块选中至_RW IE中的WCTRL+v
  2. 删除选中块:x
  3. 块选中RTBCSRCTRL+v
  4. 块前插入:I
  5. 输入:see UART-> (此处有个空格)
  6. 退出块编辑:ESC

当前处理结果如下:

uart_hw.gdb

	see UART-> RXH
	see UART-> TXH
	see UART-> BAUD
	see UART-> CON
	see UART-> SR
	see UART-> IE
  1. 继续编辑结果如下,see是自己定义的指令用来格式化打印。

uart_hw.gdb

define see
	printf "0x%08X $arg1\n", &$arg0$arg1
end

define uart
	echo ========== UART ========== \n
	see UART-> RXH
	see UART-> TXH
	see UART-> BAUD
	see UART-> CON
	see UART-> SR
	see UART-> IE
end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值