Programmer un module

salut

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

avant de penser à coder j’ai entamé un (long) travail de lecture de doc, essentiellement sur
http://www.tldp.org
et notemment "The Linux Kernel Module Programming Guide"
http://www.tldp.org/LDP/lkmpg/2.6/html/index.html

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

Tu peux trouver ici les sources des exemples des articles : pficheux.free.fr/articles/lmf/ke … ogramming/

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 :stuck_out_tongue:

Ecriture de driver sous Linux grâce au Langage C

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 :smiley: .
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

merci dmon pour tes liens

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.

oula j’ai pas dit que c’était facile !
hier soir j’ai eu droit à des magnifiques "Oops"
par contre la plomberie c’est une autre cuisine

dpkg-reconfigure robinet --mitigeur

[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. :wink:

Ba c’est simple : tu vas a casto , si tu trouve pas la bonne taille, tu refais le mur ! Mouhahahaha

---- désolé pour cette boutade

pour changer de sujet

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

merci

ça m’a l’air cohérent avec ce que je viens de lire ici:

enfin pour ce que j’y comprends qqchose. :laughing:

[quote=“mattotop”]ça m’a l’air cohérent avec ce que je viens de lire ici:

Il me semble que c’est une solution pour utiliser le RTC en mode utilisateur.

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

je met ca propre et je vous balance le code

merci pour votre aide :smiley:

Autre article sur la programmation d’un module : Stepper motor driver for your Linux Computer

merci pour le lien

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