fsync

 

6.4. 异步通知

尽管阻塞和非阻塞操作和 select 方法的结合对于查询设备在大部分时间是足够的, 一些情况还不能被我们迄今所见到的技术来有效地解决.

让我们想象一个进程, 在低优先级上执行一个长计算循环, 但是需要尽可能快的处理输入数据. 如果这个进程在响应新的来自某些数据获取外设的报告, 它应当立刻知道当新数据可用时. 这个应用程序可能被编写来调用 poll 有规律地检查数据, 但是, 对许多情况, 有更好的方法. 通过使能异步通知, 这个应用程序可能接受一个信号无论何时数据可用并且不需要让自己去查询.

用户程序必须执行 2 个步骤来使能来自输入文件的异步通知. 首先, 它们指定一个进程作为文件的拥有者. 当一个进程使用 fcntl 系统调用发出 F_SETOWN 命令, 这个拥有者进程的 ID 被保存在 filp->f_owner 给以后使用. 这一步对内核知道通知谁是必要的. 为了真正使能异步通知, 用户程序必须设置 FASYNC 标志在设备中, 通过 F_SETFL fcntl 命令.

在这 2 个调用已被执行后, 输入文件可请求递交一个 SIGIO 信号, 无论何时新数据到达. 信号被发送给存储于 filp->f_owner 中的进程(或者进程组, 如果值为负值).

例如, 下面的用户程序中的代码行使能了异步的通知到当前进程, 给 stdin 输入文件:

signal(SIGIO, &input_handler); /* dummy sample; sigaction() is better */
fcntl(STDIN_FILENO, F_SETOWN, getpid());
oflags = fcntl(STDIN_FILENO, F_GETFL);
fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC);

这个在源码中名为 asynctest 的程序是一个简单的程序, 读取 stdin. 它可用来测试 scullpipe 的异步能力. 这个程序和 cat 类似但是不结束于文件尾; 它只响应输入, 而不是没有输入.

注意, 但是, 不是所有的设备都支持异步通知, 并且你可选择不提供它. 应用程序常常假定异步能力只对 socket 和 tty 可用.

输入通知有一个剩下的问题. 当一个进程收到一个 SIGIO, 它不知道哪个输入文件有新数据提供. 如果多于一个文件被使能异步地通知挂起输入的进程, 应用程序必须仍然靠 poll 或者 select 来找出发生了什么.

6.4.1. 驱动的观点

对我们来说一个更相关的主题是设备驱动如何实现异步信号. 下面列出了详细的操作顺序, 从内核的观点:

  • 1. 当发出 F_SETOWN, 什么都没发生, 除了一个值被赋值给 filp->f_owner.

  • 2. 当 F_SETFL 被执行来打开 FASYNC, 驱动的 fasync 方法被调用. 这个方法被调用无论何时 FASYNC 的值在 filp->f_flags 中被改变来通知驱动这个变化, 因此它可正确地响应. 这个标志在文件被打开时缺省地被清除. 我们将看这个驱动方法的标准实现, 在本节.

  • 3. 当数据到达, 所有的注册异步通知的进程必须被发出一个 SIGIO 信号.

虽然实现第一步是容易的--在驱动部分没有什么要做的--其他的步骤包括维护一个动态数据结构来跟踪不同的异步读者; 可能有几个. 这个动态数据结构, 但是, 不依赖特殊的设备, 并且内核提供了一个合适的通用实现这样你不必重新编写同样的代码给每个驱动.

Linux 提供的通用实现是基于一个数据结构和 2 个函数(它们在前面所说的第 2 步和第 3 步被调用). 声明相关材料的头文件是<linux/fs.h>(这里没新东西), 并且数据结构被称为 struct fasync_struct. 至于等待队列, 我们需要插入一个指针在设备特定的数据结构中.

驱动调用的 2 个函数对应下面的原型:

int fasync_helper(int fd, struct file *filp, int mode, struct fasync_struct **fa);
void kill_fasync(struct fasync_struct **fa, int sig, int band);

fasync_helper 被调用来从相关的进程列表中添加或去除入口项, 当 FASYNC 标志因一个打开文件而改变. 它的所有参数除了最后一个, 都被提供给 fasync 方法并且被直接传递. 当数据到达时 kill_fasync 被用来通知相关的进程. 它的参数是被传递的信号(常常是 SIGIO)和 band, 这几乎都是 POLL_IN[](但是这可用来发送"紧急"或者带外数据, 在网络代码里).

这是 scullpipe 如何实现 fasync 方法的:

static int scull_p_fasync(int fd, struct file *filp, int mode)
{
 struct scull_pipe *dev = filp->private_data;
 return fasync_helper(fd, filp, mode, &dev->async_queue);
}

显然所有的工作都由 fasync_helper 进行. 但是, 不可能实现这个功能在没有一个方法在驱动里的情况下, 因为这个帮忙函数需要存取正确的指向 struct fasync_struct (这里是 与dev->async_queue)的指针, 并且只有驱动可提供这个信息.

当数据到达, 下面的语句必须被执行来通知异步读者. 因为对 sucllpipe 读者的新数据通过一个发出 write 的进程被产生, 这个语句出现在 scullpipe 的 write 方法中.

if (dev->async_queue)
 kill_fasync(&dev->async_queue, SIGIO, POLL_IN);

注意, 一些设备还实现异步通知来指示当设备可被写入时; 在这个情况, 当然, kill_fasnyc 必须被使用一个 POLL_OUT 模式来调用.

可能会出现我们已经完成但是仍然有一件事遗漏. 我们必须调用我们的 fasync 方法, 当文件被关闭来从激活异步读者列表中去除文件. 尽管这个调用仅当 filp->f_flags 被设置为 FASYNC 时需要, 调用这个函数无论如何不会有问题并且是常见的实现. 下面的代码行, 例如, 是 scullpipe 的 release 方法的一部分:

/* remove this filp from the asynchronously notified filp's */
scull_p_fasync(-1, filp, 0);

这个在异步通知之下的数据结构一直和结构 struct wait_queue 是一致的, 因为 2 种情况都涉及等待一个事件. 区别是这个 struct file 被用来替代 struct task_struct. 队列中的结构 file 接着用来存取 f_owner, 为了通知进程.

 

http://blog.chinaunix.net/u3/101356/showart_2108034.html

使用示列

 

 

 

### MIPI FSYNC Signal in Camera Interface Synchronization In the context of camera interfaces, particularly those adhering to MIPI standards such as CSI-2 and D-PHY, synchronization plays a critical role in ensuring that data transmission between an image sensor and processor is both accurate and reliable. The Frame Sync (FSYNC) signal serves as one mechanism for achieving this synchronization. The FSYNC signal acts as a frame synchronization pulse used by some cameras or systems where external control over frame capture timing is necessary. This signal can be utilized to synchronize multiple sensors within a system or align video frames with other events outside the imaging pipeline[^1]. When discussing how FSYNC integrates into protocols like CSI-2 primarily focuses on packetized streaming of pixel data along with embedded commands through virtual channels via high-speed differential pairs defined under D-PHY specifications, certain applications may require additional signals including VSYNC (vertical sync), HREF/HSYNC (horizontal reference/sync), and indeed FSYNC for more precise control over when frames are captured relative to each other or external triggers[^4]. For implementation purposes, handling these types of synchronous operations typically involves configuring hardware registers associated with either the transmitting side (image sensor) or receiving end (application processor). In many cases, support for generating or responding to FSYNC pulses will depend upon specific capabilities provided by individual components rather than being universally standardized across all devices implementing MIPI interfaces[^3]. ```python # Example pseudo-code showing configuration related to FSYNC generation/reception def configure_fsync(sensor_config): if "fsync_support" in sensor_config: enable_fsync_output() set_fsync_polarity(sensor_config["polarity"]) else: disable_fsync_input() configure_fsync({"fsync_support": True, "polarity": "active_high"}) ``` --related questions-- 1. How does the integration of FSYNC differ between single-sensor setups versus multi-camera configurations? 2. What considerations should designers take into account regarding power consumption when using continuous vs pulsed FSYNC signaling? 3. Can you provide examples of scenarios where utilizing FSYNC significantly improves performance compared to relying solely on internal timing mechanisms within the camera module? 4. Are there any limitations imposed by particular versions of the MIPI specification concerning the use of FSYNC alongside standard CSI-2 streams?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值