je débute dans la programmation de module
j’aimerais faire un driver de moteur sur le port parallèle
c-a-d envoyer un train d’impulsions sur une pin du port
c’est quelque chose que j’ai déjà fait (et dont j’ai déjà parlé sur ce forum) depuis l’user space en utilisant la RTC et en commandant le port avec ioctl
maintenant j’aimerais passer au stade supérieur : le module au noyau qui me permet de recupérer des timers rapides (entre autre) et de faire ca bien propre
Je commence à me faire une idée de comment pourrait fonctionner mon driver : je créerais un device /dev/stepmotor et je lui parlerais avec ioctl depuis n’importe quelle appli
Ca OK j’ai compris
Il me reste à comprendre comment accéder au port depuis mon module (ioctl ne doit pas être la bonne soluce) puis comment accéder à des timers rapides
puis tout ce que je n’ai pas encore envisagé
étant donné que la lecture des includes du noyau n’est pas tres facile sans exemple je pensais rentrer dans le code de drivers de périphériques du port parallèle afin de me familiariser avec ce type de prog sur des codes bien faits
juste une petite question : que me conseilleriez vous comme driver à analyser ? ou comme doc supplémentaire ?
et puis : est-ce que certains d’entre vous auraient suffisemment de recul, de temps et d’intérêt pour juger mon code lorsque je le presenterai ?
je pensais balancer l’URL ou se trouveront mes sources ou alors (si cela est possible) balancer ca directement sur le forum
de cette manière tout le monde pourra donner des mains à sa debian
Pour ma part, je ne pense pas que ce soit une bonne idée de demander à ton kernel de gérer un moteur si tu as besoin de précision. Que ce soit un moteur à courant continu fonctionnant en modulation de fréquence pour obtenir une valeur moyenne de la tension à ces bornes, ou le timing précis du signal de synchronisation contrôlant un moteur pas à pas. Si tu arrives à faire tourner un moteur à vitesse rapide sans varaitions, tiens moi au courant, je suis intéressé. J’aurais plutôt opter pour une carte annexe commander par un pc.
Pour accéder à un port dans la zone périphérique il faut utiliser inb(), outb()… Mais cette fois çi il n’y a plus besoin de d’utiliser iopem() ou iopl() pour demander l’autorisation au kernel d’accéder à la ressource. Ça je l’ai déjà fait.
Par contre s’il est en zone mémoire je pense qu’il faudra accéder à l’aide d’un pointeur.
Je te conseille la lecture
Programmation noyau sous Linux Partie 1 : API des modules Linux
Programmation noyau sous Linux : pilotes en mode caractère
Programmation noyau sous Linux : techniques avancées
C’est déjà un bon début.
Par contre si tu as des problèmes pour la stabilités d’une commande ou chaîne d’asservissement il faudra patcher ton système pour qu’il devienne un OS Temps Réel. Mais dans ce domaine tu es en avnce sur moi : [RESOLU]temps reel sous debian
Je ne cherche pas à tourner à “vitesse rapide”, 4tr/s (240tr/mn) me suffisent car sur un moteur pas à pas le couple tombe avec la vitesse or pour la plupart des applications quotidiennes on a besoin de couple et pas de vitesse. Or à 240tr/mn le moteur tourne proprement sans avoir fait de module. Je peux te filer mes sources, thialme, si tu veux .
D’ailleurs ca serait bien de pouvoir tester ca sur differentes machines car la vitesse maxi dépend outre le moteur des différentes IRQs captant le CPU.
Concernant la carte externe j’y ai pensé. Il en existe des toutes faites avec comm par RS485, USB, bus can…mais ce sont des solutions industrielles trop chères pour un particulier (je connais les betes j’en ai déjà mis en oeuvre).
Mon objectif étant de faire quelque chose d’accessible à tous les utilisateurs de linux je ne peux pas m’orienter vers des cartes externes, même des cartes basées PIC et soudées à la main.
Je vais regarder les liens du post de dmon et puis je me lirai quelques sources
ils sont tres tres interessants
grace à ca j’ai pu trouver comment m’en sortir et au passage m’assurer que le ticket d’entrée de “programmeur de module” était à ma portée…moyennant travail
je mettrai mes sources en lignes des que possible
si certains sont intéressés qu’ils me contactent
À croire que c’est plus facile d’écrire un module que de changer le col du cygne de l’évier de la cuisine. 4 jours que je fais les grandes enseignes, ils ont tous les mauvais cols et jamais le bon adaptateur.
[quote=“dmon”]À croire que c’est plus facile d’écrire un module que de changer le col du cygne de l’évier de la cuisine. 4 jours que je fais les grandes enseignes, ils ont tous les mauvais cols et jamais le bon adaptateur. [/quote]
Laisse tomber, si ton col est foutu, c’est que le robinet est vieux et au lieu de galérer comme je l’ai fait pendant 15 jours à la recherche d’un col que jamais je ne trouvais, va chez Castorama ou Leroy MLerlin et achète un robinet complet en promo, ça te reviendra moins cher.
[quote=“fran.b”][quote=“dmon”]À croire que c’est plus facile d’écrire un module que de changer le col du cygne de l’évier de la cuisine. 4 jours que je fais les grandes enseignes, ils ont tous les mauvais cols et jamais le bon adaptateur. [/quote]
Laisse tomber, si ton col est foutu, c’est que le robinet est vieux et au lieu de galérer comme je l’ai fait pendant 15 jours à la recherche d’un col que jamais je ne trouvais, va chez Castorama ou Leroy MLerlin et achète un robinet complet en promo, ça te reviendra moins cher.[/quote]
Salut, moi je voudrais changer ma porte d’entrée: les avis des menuisiers sont les bienvenus.
je suis toujours dans mon module et j’essaie de faire en sorte de recuperer les IRQ de la RTC
je sais, c’est récurrent chez moi
j’ai regardé RTC.h attentivement et d’apres ce que j’ai compris je dois “prendre la main” sur la RTC par :
extern struct rtc_device *rtc_device_register(const char *name,
struct device *dev,
const struct rtc_class_ops *ops,
struct module *owner);
et ensuite je dois “prendre la main” sur son irq par :
extern int rtc_irq_register(struct rtc_device *rtc,
struct rtc_task *task);
et ensuite j’ai le droit de changer sa frequence (je veux prendre 8192Hz le maxi)
et normalement à chaque IRQ je retomberai dans la fonction définie dans struct rtc_task *task
bon c’est bien tout ca mais quand je vois tous les arguments de rtc_device_register je me demande si je pars pas dans quelque chose d’un peu trop compliqué
quelqu’un pourrait-il me dire si je suis dans la bonne direction et/ou s’il a une url ou trouver de la doc car je commence à ecluser google sans avoir gagné en compréhension
Je regardais les sources rtc du noyau et c’est un peu la fête avec les différents drivers et les sources peu commentées ; Mais bravo pour le boulot open source. Je pense qu’il faut connaître un peu la chose pour rentrer dedans.
Autrement le fichier rtc.c me semble plus explicite que son header :p!
en fait la soluce etait un peu dans tout ca
à savoir qu’il fallait bien rentrer dans rtc.c, les rtc-xxx.c et rtc.h
en fait à la fin de rtc.h il existe des prototypes de fonctions permettant de rajouter une tache sur interruption sur la rtc. elles utilisent les commandes ioctl pour lancer son irq, programmer la frequence et on peut définir sa callback grace à une structure spécialisée.
ca a l’air d’etre fait pour car c’est dans l’esprit d’un device_register
j’ai galéré sauvage avant de trouver ca mais je suis bien content au final
en plus j’ai mis les pieds pour la première fois dans le kernel et ca c’est un bon point
mais il ne pilote pas son moteur tout à fait comme moi
sinon pour info :
je n’ai pas pu coder la dessus beaucoup ces derniers temps car j’ai eu pas mal de travail
mais j’étais tout bon sauf sur un point
je voulais faire un module de type character device à qui je donne une consigne de position (par ex. 1200pas) par un ioctl
le module devais prendre en charge les accélérations et freinage, à savoir faire des calculs pour déterminer le temps entre chaque pas afin de lancer un timer (tres court) OU calculer le nombre d’IRQ RTC à faire passer entre 2 pas (je compte faire cohabiter les 2 modes ce qui permet de faire tourner le module sur une machine non temps réel)
le hic c’est que les calculs sur des floats et des doubles dans un module ca ne passe pas, j’ai eu beau essayer pas mal de manip trouvées à droite ou à gauche les seuls résultats sont soit des erreurs de compil soit le plantage de la machine.
je me suis donc repporté vers une structure de type :
programme utilisateur => préprocesseur => module
le prog utilisateur demande une consigne en envoyant une requète à un démon (prérpocesseur)
le démon réalise tous les calculs et génère un tableau de dimension le nombre de pas de la consigne
le tableau est envoyé dans le kernel space et le module réalise le mouvement
j’aurais pu shunter le démon mais j’ai trouvé que c’était plus propre que d’intégrer le calcul dans le prog utilisateur, ne serait-ce que pour faire quelque chose de standard qui puisse servir à tout le monde
je pourrai me remettre à coder la semaine prochaine
je donnerai alors des nouvelles