différence entre un accès I/O et accès mémoire. [C embarqué] - C++ - Programmation
Marsh Posté le 21-03-2003 à 14:37:30
accés mémoire = accés à la mémoire
accès IO = accés aux périphériques d'entrée/sortie (HD, disquette, clavier, etc...)
Marsh Posté le 21-03-2003 à 15:37:01
Et au nivo logiciel ca change coi? parce que au niveau matériel, c quand même assez différent, on utilise IOR et IOW au lieu de MEMR et MEMW mais je vois pas très bien pourquoi on pourrais pas utiliser les memes lignes de controles pour ces deux types d'accès.
Marsh Posté le 21-03-2003 à 17:07:29
la je t'avoue que je sais pas du tout, sorry
Marsh Posté le 21-03-2003 à 20:19:39
ça viens du fait du faible espace mémoire initial des 80x86.
bien qu'à l'origine les 80x86 avaient un plus grand adressage mémoire qu'un 6809 (20 bits=>1Mo au lieu de 16 bits=>64Ko), Intel à décidé de faire "philosophiquement" un espace mémoire, pour réellement de la mémoire, et un espace périphérique ou on attaque uniquement les registres de contrôle des périphériques.
alors que chez motorola, les périphériques (leur registres) sont atteints via l'adressage mémoire standard.
quel était le désavantage ? je dirais la perte d'espace mémoire dû au décodage d'adresse.
en effet généralement les décodages d'adresses ne descendent pas bien "bas" en granularité de pas, en gros un périph qui a juste 64 octets de ports d'entrée/sorties pourrait bouffer 1ko/2ko et + suivant comment était cablé le décodage d'adresse.
c'est pour ça que je penses qu'intel a crée un (faux) bus i/o et ptet aussi pouvoir appliquer des timings différents entre la ram et les périphs, car au contraire le 68000 avait un bus asynchrone (avec watchdog) pour communiquer avec des périphériques répondant à des vitesses différentes.
sur les 80x86 ont avait que 1 mo de ram, donc comme on voulait pas en perdre une miette, ce "bus" a dû être crée.
sur le 680x tout était accédé par l'espace mémoire normal (et donc de la perte dû au décodage d'adresse)
sur le 68k, idem, mais on s'en fout le 68000 avait 24 bits (sur 32 bits) de cablé et pouvait donc adresser 16 mo de ram ou de périps (à l'époque ou 4mo c'était pour les stations de travail ).
comme actuellement (en fait depuis le 386) le cpu adresse sur 32 bits, les registres de contrôles des périphs PCI sont exposés via des ports I/O mais aussi des plages mémoires.
porké ?
- la plage I/O pour la compatiblité historique avec les os en mode réel (dos), comme c'est le cas avec les cartes réseaux PCI qui ont leurs regs en I/O pour avoir un driver dos (et aussi en espace mémoire).
- la plage mémoire classique, car plus performant (on peut utiliser des mov & co au lieu de in/out), mais aussi c'est relativement obligatoire avec le PCI qui rends le matos portable de machine en machine.
En effet le PowerPC n'ayant pas de notion de bus I/O comme les 80x86, un périphérique PCI qui n'aurait ses registres de contrôle qu'en port I/O ne serait pas exploitable sur Mac ou sur tout autre machine que le PC.
voilà.
désolé si j'ai dit une bêtise, mais dans l'idée c'est un peu ça.
Marsh Posté le 21-03-2003 à 20:30:28
au niveau logiciel:
les plages mémoires sont accédées normalement (ce que tu veux en C, des mov/instructions classiques en assembleur).
les ports d'entrée/sortie sont avec des inportb/outportb inport/outport en C, et in & out en assembleur.
l'autre avantage du modèle de programmation avec la plage mémoire, c'est que du décrits une structure en C décrivant les registres du périphériques, tu fait un pointeur, et tu fais mumuse.
par exemple:
typedef struct
{
short état;
short commande;
char etendu_truc...
} mon_périph_amoa;
et dans ton code, tu fais:
mon_périph_amoa *Périph=ADRESSE_BASE;
Periph->état=0; // reset
if( Perph->état & 2 )
// gnagna reset échoué etc etc...
alors qu'en modèle port d'entrée/sortie, fo faire:
outport(ADRESSE_BASE,0);
if( inport(ADRESSE_BASE+2) & 2 )
// gna gna gni gni
en c++ tu pourrais même faire un constructeur qui initialise le périphérique, un destructeur qui le ferme (inhibition int & co), et initialiser le périph avec un placement new...
mé bon c'est une autre histoire.
du style:
class mon_périph_amoa
{
public:
short état;
short commande;
char etendu_truc...
mon_périph_amoa()
{
état=0; // reset
if( état & 2 )
throw("bordelz de merdz" );
}
~mon_périph_amoa()
{
état=0; //reset
état|=8; // on va dire que ça coupe les interruptions hein
}
};
et là tu fais:
// initialisation du matos
mon_périph_amoa=new mon_périph_amoa(ADRESSE_BASE);
mon_périph_amoa->transfère();
....
// on ferme et on éteint la lumière...
delete mon_périph_amoa;
Marsh Posté le 23-03-2003 à 10:58:09
Ne soit pas si impatient! Laisse moi profiter de mon Samedi!
En tout cas merci bcp, je comprends mieux toutes ces nuances. Dès Lundi , je met çà en application!
Marsh Posté le 21-03-2003 à 14:32:48
Salut,
Je débute en C et je dois programmer une application embarqué sur un automate à base de intel 386ex
J'ai avant tout une question, Quelle est la différence entre un adressage Mémoire et un adressage I/O ? J'ai en effet les deux types d'accès à effectuer sur un bus ISA (PC104) et je ne comprends pas bien la différence, tant au niveau matériel que au niveau logiciel. Dans mon soft, qu'est-ce qui va différer ?
Merci pour votre aide,
Sorg