Bonjour,
Je dois rédiger un programme en C qui doit lire 4 ports series. Sur chaque ports série se trouve une balance. L'information est obtenue lorsqu'il y a une variation du poids sur la balance.
Exemple: Sur la balance A se trouve 100g de nourriture. Une sourie mange 10g. Sur A nous avons maintenant 90g. L'info est envoyé lorque le poid est stabilisé sur la balance.
Pour ne pas monopolisé le CPU en lecture sur les 4 ports, il faut mettre en place un gestionnaire d'interruption. Ansi, chaque fois qu'une infos ce présente sur un des 4 ports series, le CPU est interrompu par une IRQ en provenance de l'un des 4 ports série.
Le développement sous IRQ en C, je sais pas. Si quelqu'un à des idées, elles sont les bien venues.
Merci d'avance
# sur quelle patteforme/OS?
Posté par ecyrbe . Évalué à 1.
bah, oui, car c'est different sur chaque couple Machine/OS...
Je suppose quand même qu'il s'agit de x86 sinon, t'aurait peut être pas employé le terme IRQ...
mais, bon, sous linux il faut lire les les fichiers /dev/ttyS0 à /dev/ttyS3.... et avoir les droit dessus si tu veux écrire (un simple chmod en root devrait faire l'affaire)... ensuite tu peux affecter un thread qui vérifie s'il y a quelque chose à lire avec un simple ioctl...
si tu veux vraiment être prévenu par une interruption du système il va falloir utiliser la fonction poll() qui doit pouvoir bloquer en attendant que quelquechose arrive sur l'un de tes descripteur de fichier... mais je te conseille de mettre un timeout et de boucler dessus quand même car sinon ton appli bloquera indéfiniement si jamais rien n'arrive...
voilà, je peux entrer un peu plus dans les détails si tu veux...mais j'aimerai pas te gacher le plaisir de bidouiller avec les ports séries...
[^] # Re: sur quelle patteforme/OS?
Posté par Daniel Caujolle-Bert . Évalué à 1.
Daniel
--
[^] # Re: sur quelle patteforme/OS?
Posté par Fabien C . Évalué à 1.
Ca se passe sur Linux, Suse noyau 2.4.21
Au vu des informations, ca ne serais pas obligatoire de travailler sous interruptions ?
[^] # Re: sur quelle patteforme/OS?
Posté par Daniel Caujolle-Bert . Évalué à 1.
Daniel.
--
[^] # Re: sur quelle patteforme/OS?
Posté par Daniel Caujolle-Bert . Évalué à 1.
Daniel
--
[^] # Re: sur quelle patteforme/OS?
Posté par Fabien C . Évalué à 1.
Me lancer les interruptions ne me semble pas simple.
Pour le noyau 2.4 ou 2.6 fera l'affaire.
[^] # Re: sur quelle patteforme/OS?
Posté par TheBreton . Évalué à 2.
quand tu ouvre un port serie par ttsy le kernel gere toute la partie reception des infos sous interruption du port serie et les bufferisent.
Donc tu n'as qu'as lire regulierement les données recu sur le ttsy (par plein de methode comme pool() ou select() ou avec un thread et un blocking-read)
voir le serial programming how-to aidera beaucoup
http://www.faqs.org/docs/Linux-HOWTO/Serial-Programming-HOWTO.html(...)
[^] # Re: sur quelle patteforme/OS?
Posté par ecyrbe . Évalué à 1.
# Module noyau ?
Posté par galactikboulay . Évalué à 2.
Sur plateforme x86, pouvoir détourner une IRQ et l'exécuter nécessite
des droits particuliers en mode protégé (ring 0).
Tu ne pourras pas avoir un gestionnaire d'IRQ en user-land sachant que
ce gestionnaire d'IRQ doit toujours être accessible (il doit donc toujours
être dans un espace "fixe", à savoir l'espace noyau). La réalisation d'un
module noyau me parait nécessaire.
Un ouvrage intéressant et qui pourrait t'aider est "Linux Device Drivers":
http://lwn.net/Kernel/LDD3/(...)
Si je ne me trompe pas, la gestion des IRQ devrait être abordée dedans.
[^] # Re: Module noyau ?
Posté par Fabien C . Évalué à 1.
Plateforme x86, SuSE Linux 2.4.21
Rédiger un module...oula !!!
Je pensait pas qu'il faille aller si loin.
Je ne sais pas trop par ou commencer...
[^] # Re: Module noyau ?
Posté par galactikboulay . Évalué à 2.
au-dessus.
Un squelette écrit à la va-vite (désolé pas testé):
fd_set rfds;
int fd[4], max_fd = -1;
fd[0] = open("/dev/ttyS0",O_RDWR,0600);
fd[1] = open("/dev/ttyS1",O_RDWR,0600);
fd[2] = open("/dev/ttyS2",O_RDWR,0600);
fd[3] = open("/dev/ttyS3",O_RDWR,0600);
for(i=0;i<4;i++)
if (fd[i] > max_fd)
max_fd = fd[i];
while(1) {
FD_ZERO(&rfds);
for(i=0;i<4;i++) FD_SET(fd[i],&rfds);
select(max_fd+1,&rfds,NULL,NULL,NULL);
for(i=0;i<4;i++)
{
if (FD_ISSET(fd[i],&rfds)) {
printf("qqch recu sur ttyS%d\n",i);
}
}
}
Un "man select()" t'expliquera comment marchent FD_SET, FD_CLR,
etc.
[^] # Re: Module noyau ?
Posté par Fabien C . Évalué à 1.
Merci pour les infos
[^] # Re: Module noyau ?
Posté par Daniel Caujolle-Bert . Évalué à 2.
Daniel
--
[^] # Re: Module noyau ?
Posté par galactikboulay . Évalué à 3.
être testé :)
Dans mon petit exemple, il faut donc tester le retour des fonctions
"open" et "select".
Même sans timeout, select() peut être interrompu par un signal
(dans ce cas valeur de retour == -1 et errno == EINTR), c'est
important d'en tenir compte.
[^] # Re: Module noyau ?
Posté par Fabien C . Évalué à 1.
Merci pour les infos
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.