I am new to writing Windows Device Driver.
My understanding is that at the hardware level when an x86 processor is interrupted (when the INTR line of the CPU is triggered by the device), the processor clears the Interrupt Flag bit of the EFLAGS register to disable interrupt before executing the Interrupt Service Routine (ISR). So normally, an x86 ISR cannot be interrupted again before it finishes its works and issues an IRET instruction. But why a Windows ISR is interruptible? Is Windows ISR the same as the processor's ISR?
A Windows Device Driver ISR is interruptible according to here:
MSDN:Writing an ISR
What the documentation specified by you in the link says is :
1. When a interrupt[DIRQL] is raised general rule is all the interrupts w.r.t to that device and lesser than that device IRQL.
2. When a ISR is executing and a deice with higher DIRQL interrupts then the ISR for the device with higher DIRQL will be called...
so the statement which is specified in the link points to the points i mentioned above.
Related
In one of my projects, I need a timer interrupt that should come on a specific core, and the handler should be executed on that core.
As there is a local APIC timer on each core, does the Linux kernel provide any interface to kernel space so I can program the timer to issue an interrupt?
I have an ESP32 board with GPIO0 connected to ground through a switch. The idea is that if I press the button and issue an ESP.restart() the board would get into flash mode.
Instead, ESP.restart() just restarts the app, ignoring GPIO0 state.
Is it possible to force the whole boot process, maybe with a direct JMP to the HW reset vector?
According to Ivan Grokhotkov
On ESP32 there are 3 reset reasons which cause strapping GPIOs to be sampled: power-on, RTC WDT reset, brownout reset.
So in terms of code, see below. If the pin is strapped it will never get out of the bootloader which will be waiting for a sync on serial.
#include "soc/rtc_wdt.h"
void hardReset() {
rtc_wdt_protect_off(); //Disable RTC WDT write protection
//Set stage 0 to trigger a system reset after 1000ms
rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_3_2us);
rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_SYSTEM);
rtc_wdt_set_time(RTC_WDT_STAGE0, 10000);
rtc_wdt_enable(); //Start the RTC WDT timer
rtc_wdt_protect_on(); //Enable RTC WDT write protection
}
A better solution is that not using firmware update mode for programmatically software updates, use it only for only bootloader updates. Split your code into two-part bootloader and logical program part.
To update your logical program part, your bootloader should handle burning the remaining addresses except for the bootloader. (Your bootloader code can burn any address on the microcontroller, filesystem libraries do that) So don't try to switch into firmware update mode which is available for whole firmware updates. The more advanced solution is using OTA update features as possible as.
In this way, you guarantee that you always have the bootable device in the field, which is ready to update any corrupted logical part. Any mistake during burning the bootloader in the field may cost your device shipment.
We programmed a STM32L072, using, for the lower layers, the HAL lib generated from cubeMX.
Note that the "programming style" in my enterprise does not involve to include a watchdog in their embedded devices. No comment.
During one particular field test (out of many), the device stopped working (i.e.: screen freeze, and no response on the communication bus, but the PWM driver was working).
The device has been restarted and after a few minutes of work, the freeze happened again. This happened a few times before we arrived.
We plugged a JTAG/ST-LinkV2, and nothing changed on bus or screen.
As soon as we unplugged the flasher, the device restarted working without a reset (we could have recognized a initialization pattern if it had happened).
I don't understand how JTAG specification could explain this behavior (i.e. the unfreezing)?
By the way, what can cause a freeze that can be unfrozen by a JTAG unplugging? Oscillator stopped? Auto sleeping modes? hardware breakpoint? software breakpoint? Interrupts disabled?
EDIT - Answer to comments and recap :
Not an oscillator cause because PWM is still working.
Software breakpoint? unlikely as none has been set before flashing the
program.
Concerning interrupts, I think this is an interesting lead, but how can the JTAG change anything by unplugging it?
Hard to determine without knowing more about your software. If the PWM is running, clearly the oscillator has not stopped. It sounds like the code may have an embedded software breakpoint instruction. The on-chip debug does not by default stop peripheral clocks when it hits a break-point.
Such instructions should be guarded to only block when the host debugger is attached (i.e. the debugger software, not just the physical JTAG hardware), e.g:
if (CoreDebug->DHCSR & 1) __BKPT(0);
If the breakpoint is not conditional on the debugger, the processor will halt with nothing to restart it (other than a watchdog, preferably the independent watchdog, because the windowed watchdog can be configured to have its clock stopped when a breakpoint is hit).
When a debugger is detached the break-point will be released, which may be what is happening here.
I have some source code with a driver called TVicHW32 and under Windows XP it works fine and the interrupt handler gets called every time there is an interrupt from the ISA bus card. The ISA bus IRQ on 5 is set as reserved in the BIOS.
If I run the exact same code under Windows 7 or even 10, the interrupt handler never gets called. I can see the interrupt line triggering with a scope but the code never gets called. I've even tried to run my code under admin and still the same.
I've emailed the company who supplies the driver but they are not replying. Is there something in Windows 7 or 10 that prevents access to the IRQ? IRQ5 is not used on this computer. This I have confirmed in the Device Manager.
Failing any chance to get a response from the company on this, has anyone got any alternative to handler hardware IRQ under Windows 7?
What piece of hardware executes firmware during POST?
BIOS microcontroller or CPU?
BIOS microcontroller is executing the firmware on ROM which has some configuration on CMOS (like a RAM). But during POST who is executing the firmware that is checking himself?
After POST, BIOS must "tell" CPU to assign instruction pointer to some address on memory right? that's how it jumps on startup?
There is no "BIOS microcontroller". The BIOS chip is just flash memory. All execution is done by the CPU.
When the processor comes out of reset, it begins executing from a fixed address (called the reset vector). That fixed address is mapped to the BIOS flash chip.
Once the BIOS has completed its boot time tasks (hardware initialization, POST), it begins enumerating boot devices in the order specified in the BIOS setup. The first boot device it finds with a valid boot sector, it begins executing it, and thus control of the computer is handed over to the Operating System.
One other comment, based on your comments: CMOS is just a set of registers inside the chipset that are backed by the RTC battery. They were traditionally used to store BIOS settings, but in a modern UEFI BIOS your settings are stored in flash.