Page 1 of 1

IRQ wating

Posted: Sun Nov 14, 2010 9:35 pm
by melgmry0101b
Hi everyone :D ,
I want the best way to make an IRQ waiter for floppy disk.
I am using this code:

Code: Select all

inline void flpydsk_wait_irq () {

	//! wait for irq to fire
	while ( _FloppyDiskIRQ == 0)
		;
	_FloppyDiskIRQ = 0;
}
and that is floppy disk IRQ handler for floppy disk:

Code: Select all

void _cdecl i86_flpy_irq () {

	_asm add esp, 12
	_asm pushad
	_asm cli

	//! irq fired
	_FloppyDiskIRQ = 1;

	//! tell hal we are done
	interruptdone( FLOPPY_IRQ );

	_asm sti
	_asm popad
	_asm iretd
}
Please i want a code samples
-------------
Thank you in advance.

Re: IRQ wating

Posted: Mon Nov 15, 2010 7:54 am
by thepowersgang
[quote=Mozo40]
Please i want a code samples
[/quote]

No.

As a quick note, what you are doing now will work, but could be improved depending on your multitasking code.
Most of my "tight" loops yield the processor on each iteration, and the longer ones put themselves to sleep and are woken by the interrupt handler.

Re: IRQ wating

Posted: Mon Nov 15, 2010 8:27 am
by Combuster
The logic behind that: if you will be waiting long enough to be able to do something else, do so - it allows for the maximum usage of the processor. A few rare things may respond in less time than it takes to switch tasks, but most of them are better called from an external interrupt (and floppies are amongst the slowest things in a system).


That said: no code +1; you will learn the least from using someone else's homework.

Re: IRQ wating

Posted: Mon Nov 15, 2010 8:32 am
by Brendan
Hi,
Mozo40 wrote:

Code: Select all

void _cdecl i86_flpy_irq () {

	_asm add esp, 12
	_asm pushad
	_asm cli

	//! irq fired
	_FloppyDiskIRQ = 1;

	//! tell hal we are done
	interruptdone( FLOPPY_IRQ );

	_asm sti
	_asm popad
	_asm iretd
}
You can't reliably use C directly for interrupt handlers, as the compiler can do whatever it likes to the stack (and trash "callee saved" registers) before your code runs, and your code can't make any assumptions about how to clean up the stack before doing the "iret" (and can't guarantee that the interrupted code's EBP register won't be trashed). Either use assembly only, or use a small stub in assembly that uses C's calling conventions to call a function.
thepowersgang wrote:As a quick note, what you are doing now will work, but could be improved depending on your multitasking code.
Most of my "tight" loops yield the processor on each iteration, and the longer ones put themselves to sleep and are woken by the interrupt handler.
I'd have the IRQ handler send a message to the rest of the driver, such that the rest of the driver waits for a message and the scheduler doesn't give it any CPU time until a message arrives. That way, no CPU time is wasted for polling (and there's no unnecessary task switches caused by "yeild()")... ;)

Lots of people don't design any IPC before starting to implement device drivers though.


Cheers,

Brendan