从 ISR 刷新缓冲区高速缓存

发布于 2024-10-20 08:47:51 字数 184 浏览 2 评论 0原文

我正在开发一个基于 ARM 的嵌入式系统,该系统使用 FIQ 中断来发出断电信号。当这个中断发生时,将会有几秒钟的时间刷新缓冲区高速缓存。我最初认为从ISR调用sync()可能会成功,但我想强制立即将脏缓冲区刷新到磁盘,而不仅仅是将页面标记为脏并等待系统刷新脏缓冲区(这显然是sync() 的作用是什么)。预先感谢您的任何建议。

DJW

I'm working on an ARM-based embedded system that uses the FIQ interrupt to signal a loss of power. When this interrupt occurs, there will be a few seconds flush the buffer cache. I originally thought that calling sync() from the ISR might do the trick, but I want to force the flushing of dirty buffers to disk immediately, not just mark the pages dirty and wait for the system to flush the dirty buffers (which is apparently what sync() does). Thanks in advance for any advice.

djw

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

也只是曾经 2024-10-27 08:47:51

嵌入式系统编程的第一条规则是:

永远、永远、永远永远从 ISR 进行任何工作。

ISR 在非常奇怪的处理器模式下运行,您无法从它们访问操作系统服务。您当然不能做任何阻止它们的事情(例如磁盘访问)。大多数操作系统允许您做的唯一事情就是发布事件和释放信号量。

解决此类问题的通常方法是让一个普通的用户空间任务等待信号量。当中断到来时ISR会释放信号量并退出;该任务将变得可运行,然后它只是用户空间代码。

isr()
{
  clear_interrupt_condition(); // to avoid the interrupt being retriggered
  post(semaphore);
}

task()
{
  for (;;)
  {
    wait(semaphore);
    sync();
  }
}

根据操作系统的不同,您可能会获得执行此类操作的特定帮助。如果您要求的话,我使用过的操作系统可以自动为您完成上述所有操作。或者他们会让您将其构建为一种事件机制,其中 ISR 会将消息发布到队列,并且工作将由事件处理程序完成。

顺便说一句,sync() 不会(或者至少不应该)仅仅将页面标记为脏; Posix 指定在数据刷新到磁盘之前它不能返回(只要内核可以)。

The first rule of embedded systems programming is:

Never, ever, ever ever, do any work from an ISR.

ISRs operate in really weird processor modes and you can't access operating system services from them. You certainly can't do anything that blocks from them (such as disk access). About the only thing most OSes will let you do is to post events and release semaphores.

The usual way to structure this kind of problem is to have a normal user-space task that sits waiting on a semaphore. When the interrupt comes in the ISR will release the semaphore and exit; the task will become runnable and then it's just user-space code.

isr()
{
  clear_interrupt_condition(); // to avoid the interrupt being retriggered
  post(semaphore);
}

task()
{
  for (;;)
  {
    wait(semaphore);
    sync();
  }
}

Depending on the OS, you may have specific help for doing this kind of thing. I've used OSes that did all the above for you, automatically, if you asked it to. Or they'd let you structure it as an event mechanism where the ISR would post a message to a queue and the work would be done from an event handler.

Incidentally, sync() doesn't (or at least shouldn't) just mark the pages dirty; Posix specifies that it mustn't return until the data has been flushed to disk (inasmuch as the kernel can).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文