linux kernel delay

本文详细介绍了在内核中实现精确延时的方法。对于AtomicContext(如中断上下文),通常采用busywait的方式,通过调用ndelay(), udelay(), 和mdelay()函数来实现。而在Non-AtomicContext下,则会根据所需延时长度的不同选择udelay(), usleep_range(), 或msleep()/msleep_interruptible()等不同方法。

    如何在内核中精确的延时?

    内核文档有专门介绍如何delay的用法。

    一个是Atomic Context情况,比如中断上下文。由于Atomic Context是不能出现进程调度的,因为有可能会让

系统一直睡下去,成了植物PC。。。。所以这种情况的延时采取的都是busy wait的方式。有三个函数可以调用,

分别是ndelay(), udelay(), mdelay()。

    另一个是Non-Atomic Context情况。几种方式分别是udelay   <10us (busy wait) , usleep_range 10us~20ms  (hrtimers), msleep/msleep_interruptible 10ms+   (jiffies/legacy_timers)

 。这里会有个小疑问,udelay()应该最小粒度应该是微妙啊,如果想要纳秒级别的延时怎么办?个人猜测,第一在Non-Atomic Context情况下根本没有这种需求;第二使用ndelay()即可。

 参考文档

https://www.kernel.org/doc/Documentation/timers/timers-howto.txt

http://elinux.org/High_Resolution_Timers

https://rt.wiki.kernel.org/index.php/Cyclictest
https://lwn.net/Articles/167897/
https://www.kernel.org/doc/Documentation/timers/hrtimers.txt

AXI UART 16550 驱动程序的源代码位于 Linux kernel 4.14 中的 drivers/tty/serial/8250/8250_axilinx.c 文件中。以下是该文件的部分源代码,供参考: ```c /* * AXI 16550 UART driver */ #include <linux/clk.h> #include <linux/console.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> #include <linux/serial_core.h> #include <linux/tty.h> #include <linux/tty_flip.h> #include <linux/tty_port.h> #define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ #define XUARTPS_CR_STOPBRK 0x00000001 /* Stop transmitter break */ #define XUARTPS_CR_STARTBRK 0x00000002 /* Start transmitter break */ #define XUARTPS_CR_TORST 0x00000008 /* Transmit out-of-band reset */ #define XUARTPS_CR_TX_DIS 0x00000010 /* Transmit disable */ #define XUARTPS_CR_TX_EN 0x00000020 /* Transmit enable */ #define XUARTPS_CR_RX_DIS 0x00000040 /* Receive disable */ #define XUARTPS_CR_RX_EN 0x00000080 /* Receive enable */ /* RS485 support */ #define AXI_RS485_ENABLED (1 << 0) #define AXI_RS485_RTS_ACTIVE_HIGH (1 << 1) #define AXI_RS485_RX_DURING_TX (1 << 2) /* AXI UART 16550 registers */ struct axi_uart16550 { u32 rxfifo; u32 txdata; u32 ctrl; u32 intr_enable; u32 intr_status; u32 baud_rate_gen; u32 rcv_timeout; u32 flow_ctrl; u32 mode; }; ``` 以上是 AXI UART 16550 驱动程序的一部分源代码。完整的源代码可以在 Linux kernel 4.14 的源码中找到。如果您需要参考该驱动程序的实现细节,可以查看该文件的完整源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值