标签: isr

禁用中断时会发生什么,以及如何处理不知道如何处理的中断?

当您禁用中断时(使用clix86中的指令),究竟发生了什么?

  • PIC是否等待您打开中断,并在发生这种情况时触发中断?(如果是这样,它等待多长时间,如果时间'到期'会发生什么?)

  • 中断 - 从设备的角度来看 - 是否被发送到"黑洞",没有响应?

  • PIC是否以某种方式告诉设备"CPU正忙"或什么?

  • 还是会发生其他事情?

另外,你如何处理一个你不知道如何处理的中断?
有没有办法告诉PIC(或设备,如果你不知道设备是什么),"是的,我收到你的消息,但我不知道该怎么办"?

x86 assembly interrupt isr interrupt-handling

7
推荐指数
2
解决办法
2038
查看次数

静态定义的IDT

我正在开发一个具有严格启动时间要求的项目.目标体系结构是基于IA-32的处理器,以32位保护模式运行.确定可以改进的一个领域是当前系统动态初始化处理器的IDT(中断描述符表).由于我们没有任何即插即用设备且系统相对静态,我希望能够使用静态构建的IDT.

然而,由于8字节中断门描述符分割ISR地址,这证明对于IA-32拱是麻烦的.ISR的低16位出现在描述符的前2个字节中,其他一些位填充接下来的4个字节,最后ISR的最后16位出现在最后2个字节中.

我想使用const数组来定义IDT,然后简单地将IDT寄存器指向它,如下所示:

typedef struct s_myIdt {
    unsigned short isrLobits;
    unsigned short segSelector;
    unsigned short otherBits;
    unsigned short isrHibits;
} myIdtStruct;

myIdtStruct myIdt[256] = {
    { (unsigned short)myIsr0, 1, 2, (unsigned short)(myIsr0 >> 16)},
    { (unsigned short)myIsr1, 1, 2, (unsigned short)(myIsr1 >> 16)},
Run Code Online (Sandbox Code Playgroud)

等等

显然这不起作用,因为在C中执行此操作是非法的,因为myIsr不是常量.它的值由链接器解决(只能进行有限的数学运算)而不是编译器.

关于如何做到这一点的任何建议或其他想法?

谢谢,

x86 interrupt isr

7
推荐指数
1
解决办法
553
查看次数

如何使用C/gcc从外设IO寄存器读取?

我在AVR32上有一个中断服务路由.我需要从中断状态寄存器中读取以取消中断.但是我没有使用读取的结果.我宁愿不使用asm指令,但我担心gcc会将读取优化为虚拟变量.什么是正确的方法?

目前我有:

uint32_t tmp = *(volatile uint32_t *)INTERRUPT_STATUS_REG_ADDRESS;
Run Code Online (Sandbox Code Playgroud)

tmp也应该波动吗?我担心如果没有使用tmp,gcc会跳过读取.

gcc avr volatile isr

6
推荐指数
1
解决办法
841
查看次数

使用临时volatile限定符优化共享阵列访问

我想知道在以下情况下,临时volatile限定符是否会产生正确的行为.假设ISR收集数组中的值,并且一旦收集到足够的值,它就表示准备就绪.

int array[10]; // observe no volatile here
int idx = 0;   // neither here
volatile bool ready = false; // but here
Run Code Online (Sandbox Code Playgroud)

这里的ISR是伪代码

ISR() {
  if (idx < 10)
     array[idx++] = ...;
  ready = (idx >= 10);
}
Run Code Online (Sandbox Code Playgroud)

假设我们可以保证array将是只读 ready发出信号,和元素是通过特定的方法来访问:

int read(int idx) {
  // temporary volatile semantics
  volatile int *e = (volatile int*)(array + idx);
  return *e;
}
Run Code Online (Sandbox Code Playgroud)

这似乎是根据cpp-reference允许的

向volatile类型转换非易失性值无效.要使用易失性语义访问非易失性对象,必须将其地址强制转换为指向易失性的指针,然后必须通过该指针进行访问.

为了完整起见,主程序执行以下操作

void loop() {
   if (ready) {
     int …
Run Code Online (Sandbox Code Playgroud)

c c++ volatile isr compiler-optimization

6
推荐指数
1
解决办法
119
查看次数

无法修改数据段寄存器。尝试时抛出一般保护错误

我一直在尝试按照James Molloy 的本教程创建一个 ISR 处理程序 ,但我被卡住了。每当我抛出软件中断时,通用寄存器和数据段寄存器都会被推送到堆栈中,而 CPU 会自动推送变量。然后将数据段更改为 0x10(内核数据段描述符)的值,从而更改权限级别。然后在处理程序返回后,这些值被pop编辑。但是,无论何时ds更改中的值,都会抛出错误代码为 0x2544 的 GPE,几秒钟后 VM 会重新启动。(链接器和编译器 i386-elf-gcc ,汇编器 nasm)

我尝试在hlt指令之间放置指令以定位哪个指令正在抛出 GPE。在那之后,我能够找到“mov ds,ax”指令。我尝试了各种方法,例如删除由引导程序代码初始化的堆栈以删除代码的权限更改部分。我可以从公共存根返回的唯一方法是删除更改权限级别的代码部分,但是当我想转向用户模式时,我仍然希望它们保留。

这是我常用的存根:

isr_common_stub:
    pusha                    ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
    xor eax,eax
    mov ax, ds               ; Lower 16-bits of eax = ds.
    push eax                 ; save the data segment descriptor

    mov ax, 0x10  ; load the kernel data segment descriptor
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    call isr_handler

    xor eax,eax …
Run Code Online (Sandbox Code Playgroud)

x86 assembly gcc osdev isr

6
推荐指数
1
解决办法
264
查看次数

在中断例程中使用 C++ 对象(和 volatile)的正确方法是什么?

我目前正在使用 Atmel AVR 微控制器 (gcc),但希望答案一般适用于微控制器世界,即通常是单线程但带有中断。

我知道volatile在访问可以在 ISR 中修改的变量时如何在 C 代码中使用。例如:

uint8_t g_pushIndex = 0;
volatile uint8_t g_popIndex = 0;
uint8_t g_values[QUEUE_SIZE];

void waitForEmptyQueue()
{
    bool isQueueEmpty = false;
    while (!isQueueEmpty)
    {
        // Disable interrupts to ensure atomic access.
        cli();
        isQueueEmpty = (g_pushIndex == g_popIndex);
        sei();
    }
}

ISR(USART_UDRE_vect) // some interrupt routine
{
    // Interrupts are disabled here.
    if (g_pushIndex == g_popIndex)
    {
        usart::stopTransfer();
    }
    else
    {
        uint8_t value = g_values[g_popIndex++];
        g_popIndex &= MASK;
        usart::transmit(value);
    }
}
Run Code Online (Sandbox Code Playgroud)

因为 …

c++ interrupt volatile isr

5
推荐指数
1
解决办法
1281
查看次数

ISR(中断服务程序)是否有单独的堆栈?

使用RTOS(例如FreeRTOS)时,每个线程都有单独的堆栈空间。那么,ISR(中断服务程序)呢,它们在内存中是否有单独的堆栈?还是可以配置的?

如果它们没有用于存储在ISR中声明的局部变量的堆栈?

stack interrupt task isr freertos

5
推荐指数
1
解决办法
2110
查看次数

4
推荐指数
1
解决办法
7298
查看次数

待处理中断是什么概念

我无法理解“待处理中断”这个词。我的意思是,我看到异步事件的方式就像“时间、潮汐和中断”不等待。

那么这个待处理中断是什么呢?我怎样才能满足一个已经过去但已经消失的请求。

有人可以用一个使用场景来解释一下吗?

编辑:从定义上来说,它是可以理解的(英语意义上),但是如果我应该处理之前发生的中断,我是否正在查看硬件设备上的一些数据缓冲?

x86 interrupt isr microprocessors interrupt-handling

3
推荐指数
1
解决办法
8368
查看次数

清除STM32上中断标志的正确方法

我正在STM32L4上开发裸机项目,并且从现有代码库开始。

ISR已通过以下方式实现:

  1. 读取外设中的中断状态,以了解引起中断的事件
  2. 做点什么
  3. 清除开始时已读取的标志。

是清除标志的正确方法吗?不应该在ISR的一开始就清除标志吗?我的理解是,如果在步骤2中第二次发生相同的外围事件,它将不会引发第二个IRQ,因此它将丢失。另一方面,如果您尽快清除该标志,则第二个事件将使该中断产生脉冲,该中断的CPU状态将变为“待处理且活动”:将发生第二个IRQ。

PS:从《 STM32处理器编程手册》中,我读到:“ STM32中断既对电平敏感又对脉冲敏感”。

arm interrupt stm32 isr

3
推荐指数
1
解决办法
1474
查看次数