Keyboard Issues

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
jzgriffin
Member
Member
Posts: 190
Joined: Tue Sep 26, 2006 1:40 pm
Libera.chat IRC: Nokurn
Location: Ontario, CA, USA
Contact:

Keyboard Issues

Post by jzgriffin »

Hey,

My OS freezes whenever I do something similar to the following:

Code: Select all

// code
char buffer[1024];
keyboardRead(buffer);
 
// keyboard.h
#ifndef __K_KEYBOARD_H__
#define __K_KEYBOARD_H__
 
#include <kernel.lib/assembly.h>
 
#define KEY_SHIFT 1
 
extern unsigned char keyChr;
 
extern void keyboardRead(char *buffer);
extern void keyboardClearKey();
extern void keyboardHandler(struct TRegisters *registers);
extern void keyboardInit();
 
#endif // __K_KEYBOARD_H__
 
// keyboard.c
#include <kernel.lib/hardware.h>
#include <kernel.lib/memory.h>
#include <kernel.lib/vga.h>
#include <kernel.sys/irq.h>
#include <kernel.sys/keyboard.h>
#include <kernel.sys/timer.h>
 
int keyboardScan = 0;
char *keyBuf;
unsigned short keyboardStatus = 0;
unsigned char keyboard[1][2][128] = {
  {
    {
         0,   27,  '1',  '2',  '3',  '4',  '5',  '6',  '7',  '8',  '9',  '0',  '-',
       '=', '\b', '\t',  'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',  'o',  'p',
       '[',  ']', '\n',    0,  'a',  's',  'd',  'f',  'g',  'h',  'j',  'k',  'l',
       ';', '\'',  '`',    0, '\\',  'z',  'x',  'c',  'v',  'b',  'n',  'm',  ',',
       '.',  '/',    0,  '*',    0,  ' ',    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,  '-',    0,    0,    0,
       '+',    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0
    },
    {
         0,   27,  '!',  '@',  '#',  '$',  '%',  '^',  '&',  '*',  '(',  ')',  '_',
       '+', '\b', '\t',  'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',  'O',  'P',
       '{',  '}', '\n',    0,  'A',  'S',  'D',  'F',  'G',  'H',  'J',  'K',  'L',
       ':',  '"',  '~',    0,  '|',  'Z',  'X',  'C',  'V',  'B',  'N',  'M',  '<',
       '>',  '?',    0,  '*',    0,  ' ',    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,  '-',    0,    0,    0,
       '+',    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0
    }
  }
}, keyChr = '\0';
 
/**
 * keyboardRead - Starts reading to a user-specified buffer
 *     buffer   - Pointer to the buffer
 */
void keyboardRead(char *buffer) {
  keyboardScan = 1;
  keyBuf = buffer;
 
  while (keyboardScan == 1) {
  }
}
 
/**
 * keyboardHandler - Handles keypresses
 *     registers   - Registers at the time of the event
 */
void keyboardHandler(struct TRegisters *registers) {
  unsigned char scanCode;
 
  // Get rid of those nasty unused parameter warnings
  if (registers->intNumber == 1) { }
 
  // Read the byte from port 0x60
  scanCode = readB(0x60);
 
  if (scanCode == 42 || scanCode == 54) {
    keyboardStatus |= (1 << KEY_SHIFT);
  }
  if (scanCode == 42 + 128 || scanCode == 54 + 128) {
    keyboardStatus &= ~(1 << KEY_SHIFT);
  }
 
  if (keyboardStatus & (1 << KEY_SHIFT)) {
    keyChr = keyboard[0][1][scanCode];
    printChr(keyChr);
    if (keyboardScan == 1) {
      if (keyChr == '\n') {
        keyboardScan = 0;
      } else {
        *keyBuf++ = keyChr;
      }
    }
  } else {
    // Make sure that this isn't a released key!
    if (scanCode < 128) {
      keyChr = keyboard[0][0][scanCode];
      printChr(keyChr);
      if (keyboardScan == 1) {
        if (keyChr == '\n') {
          keyboardScan = 0;
        } else {
          *keyBuf++ = keyChr;
        }
      }
    }
  }
 
  writeB(0x20, 0x20);
}
 
/**
 * keyboardInit - Initializes the keyboard
 */
void keyboardInit() {
  irqInstall(1, keyboardHandler);
}
What I'm trying to do is implement something similar to fgets, gets, etc. Please help, I've been working on this for several hours, and have tried lots of methods, but can't get it working. :(
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Please help, I've been working on this for several hours
Bugs can take more than several hours looking at it to work out. Come back if you're still stuck after about 4 days (Thats about the cutoff period I set myself before I ask for help).

JamesM
Last edited by JamesM on Mon Jul 30, 2007 2:53 am, edited 1 time in total.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Code: Select all

while (keyboardScan == 1) { 
  } 
That looks a little suspicious to me...

If that's not the problem, are you using Bochs or similar? Where exactly is EIP when the freeze occurs (always the same value, always the same function etc...)?

Cheers,
Adam
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Why don't I see the volatile keyword anywhere in this code?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

@OP: In case you didn't understand what pcmattman said, GCC will cache any variable it thinks will remain static within a specified scope, for performance reasons. This causes problems when manipulating shared data across threads/processes. Your spin variable (keyboardScan) should be declared 'volatile', to tell gcc NEVER to cache it's value.

JamesM
jzgriffin
Member
Member
Posts: 190
Joined: Tue Sep 26, 2006 1:40 pm
Libera.chat IRC: Nokurn
Location: Ontario, CA, USA
Contact:

Post by jzgriffin »

geist helped me with this on #osdev a little while after I posted this topic. I didn't know about volatiles before. But the problem was that I had my sti() in kernel() (different file) *after* the call to getStr/keyboardRead. It works perfectly now, and I've practically rewritten the driver.
Post Reply