linux内核 宏 内敛 函数,linux内核中的一个宏函数例子

在移植linux到龙芯3210的过程中,调试串口的时候,遇到了一个outb函数,却找不到这个函数的原型。当时是用VIM的跳转功能来看的代码。直接用grep工具也找不到这个函数。后问人才发现其实outb实则上是一个宏函数,而这宏函数的写法还真是少见,可能是见识少了。

在./include/asm/io.h(其实asm是一个软链接,实际上是./include/asm-mips/io.h)中:

363 #define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow)                 /

364                                                                         /

365 static inline void pfx##out##bwlq##p(type val, unsigned long port)      /

366 {                                                                       /

367         volatile type *__addr;                                          /

368         type __val;                                                     /

369                                                                         /

370         __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); /

371                                                                         /

372         __val = pfx##ioswab##bwlq(__addr, val);                         /

373                                                                         /

374         /* Really, we want this to be atomic */                         /

375         BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long));             /

376                                                                         /

377         *__addr = __val;                                                /

378         slow;                                                           /

379 }

411 #define __BUILD_IOPORT_PFX(bus, bwlq, type)                             /

412         __BUILD_IOPORT_SINGLE(bus, bwlq, type, ,)                       /

413         __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)

414

415 #define BUILDIO_IOPORT(bwlq, type)                                      /

416         __BUILD_IOPORT_PFX(, bwlq, type)                                /

417         __BUILD_IOPORT_PFX(__mem_, bwlq, type)

418

419 BUILDIO_IOPORT(b, u8)

420 BUILDIO_IOPORT(w, u16)

421 BUILDIO_IOPORT(l, u32)

从上面的代码看来,除了“##”比较难理解,其它都行。关键也是在“##”。经查资料,了解到这两个#的作用是连接字符串的作用。

从419行看来,传入的参数只有两个b,u8,那么只有两个参数,其它的字符串为空。

则看365行,明显得到:

pxf 为空字符串

bwlq = b

type = u8

那么得到两个函数:

static inline void outb(u8 val, unsigned long port)

{

... ....

}

static inline void outb_p(u8 val, unsigned long port)

{

... ....

SLOW_DOWN_IO;

}

89 #define __SLOW_DOWN_IO /

90         __asm__ __volatile__( /

91                 "sb/t$0,0x80(%0)" /

92                 : : "r" (mips_io_port_base));

可以看到outb与outb_p的区别在于执行完之后,outb_p调用了一个IO延时。但从这个SLOW_DOWN_IO中看来,相当于汇编中的:

sb $0, 0x80(mips_io_port_base)

意思是清零mips_io_port_base + 0x80这个地址保存的值????

怪怪的。

参考了LDD3中的一段话:

暂停式IO

在处理器试图从总线上快速传输数据时,某些平台(特别是i386)会遇到问题。当处理器时钟相比外设时钟快时(比如ISA)就会出现问题,并且在设备卡特别慢时表现出来。斛决的办法是在每条IO指令之后,如果还有其他类似指令,则插入一个小的延迟。在x86平台上,这种暂停可通过对端口0x80的一条out b指令实现(通常这样做,但很少使用),或者通过使用忙等待实现。相关细节可参与自己平台上asm子目录下的io.h文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值