Problem with keyboard driver
Problem with keyboard driver
For weeks Ive been trying to write a basic keyboard driver. On my first attempt I polled the keyboard and was successful in outputing characters to the screen when a key was pressed.
When I modified the code to work with interrupts, I was unable to get anything to print out when a certain key was pressed. Does any body know what could be wrong?
Thanks in advance.
When I modified the code to work with interrupts, I was unable to get anything to print out when a certain key was pressed. Does any body know what could be wrong?
Thanks in advance.
Re:Problem with keyboard driver
The keyboard IRQ number is at 0x21(hex) not 21(decimal). Also you might want to consider calling the C functioon from within an ASM wrapper with EOI etc.
Only Human
Re:Problem with keyboard driver
Code: Select all
if(shift) // Same as if(shift == 1)
Only Human
Re:Problem with keyboard driver
I changed the 21(decimal) to 0x21(hex) and it didnt make a difference. My ASM wrapper calls the C function and sends an EOI at the end.The keyboard IRQ number is at 0x21(hex) not 21(decimal). Also you might want to consider calling the C functioon from within an ASM wrapper with EOI etc.
I guess, not too sure what your mean.Just thought i'd mention this, your comment is not exactly correct. if(shift) actually means 'shift' is any non-zero value not necessarily '1'.
Re:Problem with keyboard driver
after your code in c do an outb 0x20,0x20
at the end of the wrapper code is there iret
at the end of the wrapper code is there iret
Re:Problem with keyboard driver
The comment on this line is false:beyondsociety wrote:I guess, not too sure what your mean.Just thought i'd mention this, your comment is not exactly correct. if(shift) actually means 'shift' is any non-zero value not necessarily '1'.
Code: Select all
if(shift) // Same as if(shift == 1)
Code: Select all
if(shift) // Same as if(shift != 0)
Re:Problem with keyboard driver
Hi beyondsociety,
since your code worked when you were polling the keyboard, I suppose that there's a problem with the way you set up your interrupt handler. Change the ISR so that it simply prints a message to the screen. Is the message printed when you press a key ? If not - is the message printed when the ISR is called manually (asm: int 0x21) ? Make sure that interrupts are enabled after all. If it still doesn't work, please post the code of install_handlers() and irq_mask().
regards,
gaf
btw: Why are you calling the ISR at the end of your ini-code ? Maybe this confuses the PIC...
since your code worked when you were polling the keyboard, I suppose that there's a problem with the way you set up your interrupt handler. Change the ISR so that it simply prints a message to the screen. Is the message printed when you press a key ? If not - is the message printed when the ISR is called manually (asm: int 0x21) ? Make sure that interrupts are enabled after all. If it still doesn't work, please post the code of install_handlers() and irq_mask().
regards,
gaf
btw: Why are you calling the ISR at the end of your ini-code ? Maybe this confuses the PIC...
Re:Problem with keyboard driver
@dreamsmith:
a real comment would say what the code intends to do (and should do), not what it does. The comment would best be:
if (shift) { // if the combination of caps lock and shift should produce a shifted value
But this guesses as to what the shift value stands for.
a real comment would say what the code intends to do (and should do), not what it does. The comment would best be:
if (shift) { // if the combination of caps lock and shift should produce a shifted value
But this guesses as to what the shift value stands for.
Re:Problem with keyboard driver
Indeed. I was simply clarifying Neo's comment about how what the comment says is false, by showing what a similar but true comment would say.Candy wrote:a real comment would say what the code intends to do (and should do), not what it does.
Point in fact, that particular comment shouldn't be there at all. Whether something else should be there instead is debatable. As Allen Holub points out in his book Enough Rope to Shoot Yourself in the Foot (which ought to be required reading for any C/C++ programmer), unnecessary comments distract attention away from important comments. Always comment when you should, but never comment when you shouldn't. And, as you say, a comment should never explain what code does -- the code explains what it does precisely. A comment needs to explain why...
Re:Problem with keyboard driver
<from earlier post>...your comment is not exactly correct. if(shift) actually means 'shift' is any non-zero value not necessarily '1'.</from earlier post>Dreamsmith wrote:Indeed. I was simply clarifying Neo's comment about how what the comment says is false, by showing what a similar but true comment would say.Candy wrote:a real comment would say what the code intends to do (and should do), not what it does.
Only Human
Re:Problem with keyboard driver
Right, and I thought that was perfectly clear myself, but beyondsociety responded:Neo wrote:<from earlier post>...your comment is not exactly correct. if(shift) actually means 'shift' is any non-zero value not necessarily '1'.</from>
Thus, my attempt to clarify further by using an example.I guess, not too sure what your mean.
Okay, now that we've disected that thread to death... ::)
Re:Problem with keyboard driver
BTW beyond inf, why are you calling the handler from your init() function?
Your handler should only be called when an INT is generated by the keyboard controller.
Your handler should only be called when an INT is generated by the keyboard controller.
Only Human
Re:Problem with keyboard driver
I'm new to os dev so please excuse any innacurate information, but what I would do is first make sure that the interrupt handler is infact properly installed.
With bochs you can run the debug version, control+c to halt execution, then type "info idt 33" which will write out entry 0x21 in the interrupt table. Check that the values make sense. Just to double check, I would then "disas" (disassemble) the first couple of bytes at the address written in the interrupt table and make sure that your asm code for your interrupt handler is indeed there.
Assuming that's ok, I would then place some code in the interrupt handler which does something very simple that you can recognise such as print some text to the screen (make sure that does actually work!) and try to using a software itnerrupt like so:
If that doesn't work, then make sure interrupts are enabled. heh. If they are, something in your idt must be wrong. Double check every detail of it.
If that does work however, but the interrupt doesn't fire when you press a key on the keyboard, then I would suspect your PIC code. The interrupt itself works fine as shown by the software interrupt, but the hardware doesn't fire it - dead give away that it's the PIC. I wouldn't really know how to debug that other than to go over the PIC code very closely and make double sure that everything is correct. Another thing to watch out for is to make sure that the keyboard IRQ line is unmasked (IRQ number 1, the second one, if i recall correctly).
I see you mentioned it above, but for completenes, remember to send the EOI command word to the PIC (for the keyboard line - just the master). Even if that's wrong though, it should still work once at least.
That's about all I can suggest. I have a few minor hitches when setting up my keyboard driver, but I got it all working perfectly in the end using those simple debugging techniques.
Good luck.
With bochs you can run the debug version, control+c to halt execution, then type "info idt 33" which will write out entry 0x21 in the interrupt table. Check that the values make sense. Just to double check, I would then "disas" (disassemble) the first couple of bytes at the address written in the interrupt table and make sure that your asm code for your interrupt handler is indeed there.
Assuming that's ok, I would then place some code in the interrupt handler which does something very simple that you can recognise such as print some text to the screen (make sure that does actually work!) and try to using a software itnerrupt like so:
Code: Select all
__asm__ __volatile ("int $33");
If that does work however, but the interrupt doesn't fire when you press a key on the keyboard, then I would suspect your PIC code. The interrupt itself works fine as shown by the software interrupt, but the hardware doesn't fire it - dead give away that it's the PIC. I wouldn't really know how to debug that other than to go over the PIC code very closely and make double sure that everything is correct. Another thing to watch out for is to make sure that the keyboard IRQ line is unmasked (IRQ number 1, the second one, if i recall correctly).
I see you mentioned it above, but for completenes, remember to send the EOI command word to the PIC (for the keyboard line - just the master). Even if that's wrong though, it should still work once at least.
That's about all I can suggest. I have a few minor hitches when setting up my keyboard driver, but I got it all working perfectly in the end using those simple debugging techniques.
Good luck.
Re:Problem with keyboard driver
The reason it wasnt doing anything at all, was because I had previously been working on my delay function and I left it running, problem solved as interrupts are working. Tested by printing a message to the screen from my keyboard handler.since your code worked when you were polling the keyboard, I suppose that there's a problem with the way you set up your interrupt handler. Change the ISR so that it simply prints a message to the screen. Is the message printed when you press a key ? If not - is the message printed when the ISR is called manually (asm: int 0x21) ? Make sure that interrupts are enabled after all. If it still doesn't work, please post the code of install_handlers() and irq_mask().
regards,
gaf
btw: Why are you calling the ISR at the end of your ini-code ? Maybe this confuses the PIC...
Though when my code gets to this
Code: Select all
if(ascii_key != 0)
putc(ascii_key);
Code: Select all
{
NEO
I dont know, I guess its a stupid mistake I made, happens when you code at all hours of the night. ;DBTW beyond inf, why are you calling the handler from your init() function? Your handler should only be called when an INT is generated by the keyboard controller.
If my interrupts are working, then it should generate an interrupt which you are right.
Thanks in advance.