当涉及到内核 API 的工作时,我对 IRQ 和向量有点困惑。
我想使用向量 0xfa 进行一些由可编程 lapic 生成的中断处理。
request_irq我查看了诸如和set_intr_gate(也alloc_intr_gate调用)之类的 API set_intr_gate,用于在我的 IDT 表中启用向量。两者是出于相同的目的,还是完全不同?使用它的最佳方式是什么?
我尝试在 stm32f4 上实现 i2c 从接收器中断服务例程。这是我的智能代码。
void I2C2_EV_IRQHandler()
{
switch (I2C_GetLastEvent(I2C2))
{
//The address sent by the master matches the own address of the peripheral
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
//The slave stretches SCL low until ADDR is
//cleared and DR filled with the data to be sent
I2C_ClearFlag(I2C2,I2C_FLAG_ADDR);
break;
//The application is expecting a data byte to be received
case I2C_EVENT_SLAVE_BYTE_RECEIVED:
I2C_ReceiveData(I2C2);
break;
//The application is expecting the end of the communication
//Make sure that both ADDR and STOPF flags are cleared
//if …Run Code Online (Sandbox Code Playgroud) 我遇到了以下信号处理程序代码,它存储 errno 变量,以便它不会影响主线程的 errno 处理。
void myhandler(int signo)
{
int esaved;
esaved = errno;
write(STDOUT_FILENO, "Got a signal\n", 13);
errno = esaved;
}
Run Code Online (Sandbox Code Playgroud)
但这真的能达到目的吗?如果另一个线程在 write() 之后和恢复 errno 之前检查共享 errno 变量,会发生什么?该线程会由于竞争条件而获得错误的 errno 值吗?
或者信号处理程序相对于线程/进程以原子方式执行,因此一旦信号处理程序执行,内核就不会调度线程,直到信号处理程序完成为止?
换句话说 - 一旦启动,信号处理程序是否会执行而不会被以下情况中断:
- 1) Scheduler (process/threads), or
- 2) Other signals, or
- 3) Hardware interrupt handlers ?
Run Code Online (Sandbox Code Playgroud) local_bh_disable禁用对下半部分 (softirqs) 的处理。Softirq 在中断返回路径上处理,或者由 ksoftirqd-(per cpu)-thread 处理,如果系统遭受沉重的 softirq 负载,它将被唤醒。
preempt_disable禁用抢占,这意味着当线程在preempt_disable<->preemt_enable范围内执行时,它不会被调度程序置于睡眠状态。这意味着,如果在当前线程在该范围内时发生系统定时器中断,它可能会更新调度程序的会计表,但它不会将上下文切换到另一个线程。这包括软中断。
local_irq_disable或local_irq_save禁用本地 cpu 的中断。这意味着本地 cpu 不会对任何 irq 做出反应,因此它不会运行任何中断返回路径,因此无法在那里运行软中断。
假设我的上述陈述是正确的(我不确定),那么在local_bh_disable您调用preempt_disableand local_irq_save(在进程上下文中)之后调用不是多余的吗?
我在Wine(wine my_app.exe)下运行我的应用程序,我想以编程方式或从脚本中与它进行交互.
所以我正在运行winedbg并附加到该过程:
$ winedbg
Wine-dbg>info process
00000008 3 'terminal.exe'
Wine-dbg>attach 8
0xf7709c0e __kernel_vsyscall+0xe in [vdso].so: int $0x80
Run Code Online (Sandbox Code Playgroud)
但我不确定下一步该做什么?
基本上我想向我的应用程序发送一些键盘或鼠标信号(旨在选择一个复选框并单击下一步按钮).
是否有可能使用葡萄酒调试器?
我的目标是自动执行此过程,以便从脚本安装应用程序而无需任何用户交互.或至少知道如何做到这一点.
我知道有xdotool工具可以很容易地从命令行伪造鼠标和键盘的输入,但是它有点儿麻烦,所以我想学习如何从调试器中做到这一点.
我最近被问到这个问题。我正在研究ARM架构,并且尝试过研究它,但我觉得我没有得到正确的答案。
我的想法是,关键原因是为了避免干扰正在进行的中断,我们使用设置启用寄存器来启用所有中断,使用清除启用寄存器来禁用所有中断。
这是正确的理由吗?这背后是否有更深层次的解释?有一些文件解释这个设计决策吗?
编辑:抱歉,我正在使用的芯片是 Cortex M4
根据上半部和下半部的指导方针,当任何中断发生时,都会由两个半部处理。所谓的top half就是真正响应你用request_irq注册的中断\xe2\x80\x94的例程。下半部分是由上半部分安排的例程,稍后在更安全的时间执行。上半部处理程序和下半部处理程序之间的最大区别在于,在执行下半部\xe2\x80\x94期间启用所有中断,这就是它在更安全的时间运行的原因。在典型场景中,上半部分将设备数据保存到设备特定的缓冲区,调度其下半部分,然后退出:此操作非常快。然后下半部分执行所需的任何其他工作,例如唤醒进程、启动另一个 I/O 操作等。此设置允许上半部分服务新的中断,而下半部分仍在工作。
\n\n但是,如果下半部在更安全的时间内处理中断,那么从逻辑上讲,当中断到来时,它必须等到下半部找到一些更安全的时间来执行中断,这将限制系统,并且必须等到中断处理,例如:如果我正在开发一个项目,当温度高于特定限制时提供 LED 闪烁指示,在这种情况下,如果在一些安全时间可用时完成中断处理(根据下半部分概念),那么闪烁操作将被延迟......请澄清我怀疑所有中断是如何处理的???
\n我想知道 Linux 中的 x86_64 有哪些不同类型的 IPI。特别是,我想找出 IPI 中断的不同中断处理程序。
在 Daniel P. Bovet 所著的《Understanding the Linux Kernel, 3rd Edition》中,Marco Cesati https://www.oreilly.com/library/view/understanding-the-linux/0596005652/ch04s06.html 列出了三种 IPI:
CALL_FUNCTION_VECTOR
RESCHEDULE_VECTOR
INVALIDATE_TLB_VECTOR
Run Code Online (Sandbox Code Playgroud)
然而,在最新的内核中,我在 arch/x86/include/asm/entry_arch.h 中找到了以下注释。
* This file is designed to contain the BUILD_INTERRUPT specifications for
* all of the extra named interrupt vectors used by the architecture.
* Usually this is the Inter Process Interrupts (IPIs)
*/
/*
* The following vectors are part of the Linux architecture, there
* is no hardware IRQ pin equivalent …Run Code Online (Sandbox Code Playgroud) 这个问题纯粹是学术性的,因为现在没有人使用MS-DOS,但我仍然想知道为什么。
在一些书籍和文章中,他们说如果你在另一个中断期间调用 DOS 中断,可能会导致死锁。这就是 MS-DOS 不可重入的原因。例如,RESIDENT PROGRAMS和另一本书,如下所述:
Run Code Online (Sandbox Code Playgroud)A interrupt occurs B interrupt handling C DOS command starts D new interrupt occurs E interrupt handling F DOS COMMAND starts G DOS command finished H interrupt finished I return to the original interrupt handling J return to original DOS command它说,当我完成后,转到J,它试图返回到第一个DOS命令被中断的点,但是由于所有DOS变量和堆栈都被F和G更改了,当你尝试返回到原来的位置时中断 (B),实际上会返回到第二个中断 (E),这会导致死锁。
但就我而言,中断就像调用一样。保存当前CS:IP,检查向量,找到中断处理程序,执行,返回到中断发生的地方。完全像call。僵局怎么可能发生是没有意义的。
所以我的问题是到底是什么可能导致僵局?一个具体的例子将非常感激。