Lowlevel
Lowlevel => OS-Design => Thema gestartet von: DaCodaaa am 22. July 2009, 15:11
-
moin,
Ich bin gerade dabei einen Keyboard Treiber für mein OS zu schreiben. Ich habe mir dafür 2 char strings gemacht mit welchen ich das Programm nachschauen lasse welche Taste gedrückt wurde:
//das Keyboardlayout für kleinschrift
char *kbddeklein[128] =
{
"^","1","2","3","4","5","6","7","8","9","0","ß","´","\r","\t","q","w","e","r","t","z","u","i","o","p","ue","+","feststell","a",
"s","d","f","g","h","j","k","l","oe","ae","#","\n","shift",
"<","y","x","c","v","b","n","m",",",".","-","shift","ctrl","start",
"alt"," ","altgr","windows","ctrl",0
};
//Das Keyboardlayout für Grosschrift wenn Shift oder Feststell Gedrückt ist
char *kbddegross[128] =
{
"°","!","\2","§","$","%","&","/","(",")","=","?","`","\r","\t","Q","W","E","R","T","Z","U","I","O","P","UE",
"*","feststell","A","S","D","F","G","H","J","K","L","OE",
"AE","'","\n","shift",">","Y","X","C","V","B","N","M",";",":",
"_","shift","ctrl","start","alt"," ","altgr","windows","ctrl",0
};
dann Habe ich einen Handler, Der mit IRQ 1 Verbunden ist und die Tastatureingaben mit den Tabellen auswertet und das Zeichen an die Hauptfunktion des Kernels weitergibt.
Beim Compilieren bekomme ich aber immer wieder diese Fehlermeldung:
stray "\337"in Program
suggest parantheses around assignment used as truth value
comparasion with string literal results in unspecified behavior
:-o
Ich würde mich freuen wenn mir Jemand erklären könnte was vor allem die erste Fehlermeldung bedeutet. :?
ich benutze gcc als Kompiler nasm als Assembler und (was sonst :wink:) ld als Linker.
thx im Voraus.
-
also der Code compiliert bei mir prima (GCC v4.3.3 64bit)
die Fehler Meldung die du da gepostet hast ist doch bestimmt nicht Komplett?
mir fehlen da irgendwie Datei- und Funktionsnamen sowie Zeilen angaben. (Und der dazugehörige Code)
Du benutzt GCC; welche Version?
-
Ich benutze die ver 4.4.0 aus dem Einsteiger Tut (crosscompiler für win).
der komplette code:
#include "System.h"
unsigned short Groß = 0;
//das Keyboardlayout für kleinschrift
char *kbddeklein[128] =
{
"^","1","2","3","4","5","6","7","8","9","0","ß","´","\r","\t","q","w","e",
"r","t","z","u","i","o","p","ue","+","feststell","a","s","d","f","g","h","j","k",
"l","oe","ae","#","\n","shift","<","y","x","c","v","b","n","m",",",".","-","shift",
"ctrl","start","alt"," ","altgr","windows","ctrl",0
};
//Das Keyboardlayout für Grosschrift wenn Shift oder Feststell Gedrückt ist
char *kbddegross[128] =
{
"°","!","\2","§","$","%","&","/","(",")","=","?","`","\r","\t","Q","W","E",
"R","T","Z","U","I","O","P","UE","*","feststell","A","S","D","F","G","H","J",
"K","L","OE","AE","'","\n","shift",">","Y","X","C","V","B","N","M",";",":",
"_","shift","ctrl","start","alt"," ","altgr","windows","ctrl",0
};
//Handelt einen Keyboard Interrupt
void keyboard_handler(struct regs *r)
{
char scancode; //Die Var für den Scancode
char *scaned; //das Zeichen
scancode = inb(0x60); //Den Keyboardpuffer lesen
if (Groß = 0)
{
scaned[0] = kbddeklein[scancode];
}
else if (Groß = 1)
{
scaned[0] = kbddegroß[scancode];
}
else if (Groß = 2)
{
scaned[0] = kbddegroß[scancode];
Groß = Groß - 2;
}
else if (Groß = 3)
{
scaned[0] = kbddeklein[scancode];
Groß = Groß - 2;
}
//Hier kann auf besontere Tasten eingegangen werden
if (scaned == "feststell") //Feststelltaste
{
Groß = 1; //Alles Großschreiben
}
else if (scaned == "shift") //shifttaste
{
Groß = Groß + 2; //nachstes Zeichen jenachdem ob feststell
//aktiviert ist groß oder klein schriben
}
else if (scaned == "windows") //rechte windows taste
{
}
else if (scaned == "start") //linke windows taste (start)
{
}
else if (scaned == "ctrl") //Strg taste
{
}
else if (scaned == "alt") //Alt taste
{
}
else if (scaned == "altgr") //Alt Gr Taste (einige Zeichen werden hieredurch ausgelöst)
{
}
else if (scaned == 0); //Nullen sind nicht definiert: nicht handeln
else //wenn keiner der oben genannten Zeichen
{ //zutrifft ist das Zeichen Von anderen Funktionen nutzbar
InputCommandCharacter(scaned);
}
}
keyboard_install()
{
irq_install_handler(1,keyboard_handler);
}
Die Funktion InputCommandCharacter() liegt in Kernel.c und schreibt das übergebene Zeichen in einen Puffer um es dann später als Befehl zu werten.
Die irq_install_handler(1,keyboard_handler); sitzt bei mir in einer anderen recourcendatei, welche jetzt nich so wichtig ist und installiert die Funktion keyboard_handler an irq 1.
Der Errorcode:
C:\MeinOs>Umgebung\crosstools-complete\bin\i586-elf-gcc -O -Wall -Werror -c -o Keyboard.o Keyboard.c
Keyboard.c:3: error: stray '\337' in program
Keyboard.c: In function 'keyboard_handler':
Keyboard.c:31: error: stray '\337' in program
cc1.exe: warnings being treated as errors
Keyboard.c:31: error: suggest parentheses around assignment used as truth value
Keyboard.c:33: error: array subscript has type 'char'
Keyboard.c:33: error: assignment makes integer from pointer without a cast
Keyboard.c:35: error: stray '\337' in program
Keyboard.c:35: error: suggest parentheses around assignment used as truth value
Keyboard.c:37: error: stray '\337' in program
Keyboard.c:37: error: 'kbddegro' undeclared (first use in this function)
Keyboard.c:37: error: (Each undeclared identifier is reported only once
Keyboard.c:37: error: for each function it appears in.)
Keyboard.c:39: error: stray '\337' in program
Keyboard.c:39: error: suggest parentheses around assignment used as truth value
Keyboard.c:41: error: stray '\337' in program
Keyboard.c:42: error: stray '\337' in program
Keyboard.c:42: error: stray '\337' in program
Keyboard.c:44: error: stray '\337' in program
Keyboard.c:44: error: suggest parentheses around assignment used as truth value
Keyboard.c:46: error: array subscript has type 'char'
Keyboard.c:46: error: assignment makes integer from pointer without a cast
Keyboard.c:47: error: stray '\337' in program
Keyboard.c:47: error: stray '\337' in program
Keyboard.c:54: error: comparison with string literal results in unspecified beha
vior
Keyboard.c:56: error: stray '\337' in program
Keyboard.c:58: error: comparison with string literal results in unspecified beha
vior
Keyboard.c:60: error: stray '\337' in program
Keyboard.c:60: error: stray '\337' in program
Keyboard.c:63: error: comparison with string literal results in unspecified beha
vior
Keyboard.c:66: error: comparison with string literal results in unspecified beha
vior
Keyboard.c:69: error: comparison with string literal results in unspecified beha
vior
Keyboard.c:72: error: comparison with string literal results in unspecified beha
vior
Keyboard.c:75: error: comparison with string literal results in unspecified beha
vior
Keyboard.c:82: error: implicit declaration of function 'InputCommandCharacter'
Keyboard.c: At top level:
Keyboard.c:87: error: return type defaults to 'int'
Keyboard.c:86: error: conflicting types for 'keyboard_install'
System.h:57: note: previous declaration of 'keyboard_install' was here
Ich hab grade in nem anderen Forum gelesen, dass vlt gcc nich richtig funzt. Werde mal zur sicherheit gcc nochmal runterlaen...
-
gcc kommt mit 'ß','ä',… in Bezeichnern(Variablen-, Funktionsnamen usw.) nicht klar
-
ok ich hab jetzt alle nur-deutsch-Zeichen durch ss,oe,ae,ue ersetzt.
die Stray schen sin auch wech :lol:.
aber was solln die anderen Fehlermeldungen? :?
-
ich denke mal, dass Groß auf die Gleichheit mit einer der Zahlen geprüft und nicht überschrieben werden soll:
if (Groß == 0)
{
scaned[0] = kbddeklein[scancode];
}
else if (Groß == 1)
{
scaned[0] = kbddegroß[scancode];
}
else if (Groß == 2)
{
scaned[0] = kbddegroß[scancode];
Groß = Groß - 2;
}
else if (Groß == 3)
{
scaned[0] = kbddeklein[scancode];
Groß = Groß - 2;
}
Ich vermute mal, dass das vergessene = die Meldung "suggest parentheses around assignment used as truth value" hervorgerufen hat, zumindest teilweise.
Des Weiteren kannst du in C Strings nicht per == vergleichen. Dazu musst du dir die Funktion strcmp schreiben, die 0 zurückgeben sollte, falls die Strings gleich sind. Also z.B.:
// strcmp sollte bei gleichheit 0 zurückgeben, deswegen die Negation
if(!strcmp(scaned, "windows")) //rechte windows taste
{
}
Und, was mir auch noch auffält, ist, dass bei der Funktion keyboard_install der Rückgabetyp, sowie die Parameter fehlen. Das könnte so aussehen:
void keyboard_install(void)
{
irq_install_handler(1,keyboard_handler);
}
// oder
void keyboard_install()
{
irq_install_handler(1,keyboard_handler);
}
-
scaned[0] = kbddeklein[scancode];
gibt den fehler
assignment makes integer from pointer without a cast
weil scaned[0] ein char ist und kbddeklein[scancode] ein char*
(du willst hier wohl ein scaned = kbddeklein[scancode] haben)
if (scaned == "feststell") //Feststelltaste
da haben wir wohl nen Pascal Programmierer!? das geht so nicht in C,
weil das beides Pointer sind und nur die Adressen verglichen werden.
In C wäre da ein "strcmp(scaned,"feststell") == 0" nötig (strcmp musst du dir aber wohl noch selbst schreiben)
-
Mit Pascal hatte ich nie was zu tun(und das habe ich vor in Zukunft so zu lassen :-D). eigentlich programmiere ich c++, mit nem bisschen c#(wobei ich das eig. eher unflexibel finde und daher immer wieder auf c++ zurückkomme). aber in c++ ging das immer strings zu vergleichen (da muss man sich aber auch nich mit klassischen c-Strings rumschlagen, da gibts dafür nämlich ne eigene selbstverwaltende klasse "String" :wink:).
Danke für die schnellen Antworten :-)
-
Ähm, ich wollte noch frägen, ob man denn einzelne chars vergleichen kann.
Notfalls würde ich das dann nämlich mit (int)a == (int)b machn.
-
Einzelne chars kannst du natürlich vergleichen.
-
Ok, danke für die vielen Antworten :-).
-
strcmp musst du dir aber wohl noch selbst schreiben
Beispiel:
// Compare two strings. Returns -1 if str1 < str2, 0 if they are equal or 1 otherwise.
int k_strcmp(char* str1, char* str2)
{
int i = 0;
int failed = 0;
while(str1[i] != '\0' && str2[i] != '\0')
{
if(str1[i] != str2[i])
{
failed = 1;
break;
}
++i;
}
// why did the loop exit?
if( (str1[i] == '\0' && str2[i] != '\0') || (str1[i] != '\0' && str2[i] == '\0') )
failed = 1;
return failed;
}
-
Das ist aber ein komisches strcmp. Das hält sich nicht mal an die eigene Dokumentation. Es gibt immer nur 0 oder 1 zurück ...
Die Variable failed ist auch seltsam. Ein strcmp schlägt nicht fehl.
Eine korrekte Implementierung findet man z.B. hier: http://forum.osdev.org/viewtopic.php?p=160916#p160916
-
Ich hatte es so gelöst:
//vergleicht 2 angegebene char-strings und gibt eine 0 zurück wenn sie gleich sind (1 wenn nicht)
short strcmp(char *char1,char *char2)
{
int i;
for (i = 0;char1[i] != 0 && char2[i] != 0;i++)
{
if(char1[i] != char2[i])
{
return 1;
}
}
if (char1[i] == 0 && char2[i] == 0)
return 0;
else
return 1;
}
:-D
die Funktion erhöht i bei jedem Schleifendurchlauf und Kontrolliert ob Beide Sctrings bei i nicht enden (dann bricht es nämlich ab und kontrolliert ob beide da enden).
Das char1 == 0 geht, da c chars wie ints behandelt.
Ist es denn falsch, dass es nur 0 oder 1 zurückgibt? :?
-
Bei ehenkes Variante ist das Problem, dass der Kommentar sagt, dass er -1 zurückgibt wenn str1 < str2, 0 wenn sie gleich sind, und 1 wenn str1 > str2. Er gibt aber nie -1 zurück.
Die Standardfunktion strcmp verhält sich in etwa auch so, wie in seiner Dokumentation, nur die Rückgabewerte werden noch etwas weiter aufgelockert: Sie darf einen beliebigen Wert kleiner 0 zurückgeben, wenn str1 < str2 und einen beliebigen Wert > 0, wenn str1 > str2.
Eure beiden Funktionen sind eher Funktionen, die man str_not_equal oder so nennen könnte, weil sie halt die Eigenschaften von strcmp nicht erfüllen. Wenn sie in eurem Code in der Form so funktionieren, ist es okay, aber wenn ihr irgendwann Code in eurer Programm einbaut, der das richtige strcmp erwartet, seid ihr schön lange am Bugs suchen.
-
Ich würde fürs erste sowas verwenden:
int strcmp(const char* str1, const char* str2)
{
while(*str1 == *str2) {
if( *str1 == 0 ) break;
str1++; str2++;
}
return *str1 - *str2;
}
-
wenn ihr irgendwann Code in eurer Programm einbaut, der das richtige strcmp erwartet, seid ihr schön lange am Bugs suchen.
Thx, ich muss mein PrettyOS wirklich mal richtig durchkämmen. Zulange einfach nur nach vorne gestolpert.