J’ai profité de ce mercredi 11 novembre pour bidouiller un peu la fox
J’ai donc pu terminer mes fonctions d’entrée/sortie. J’en ai profité pour mettre un makefile et mettre une archive en ligne où vous pouvez télécharger mon code. Je pense que cela mérite quelques petites finitions, mais le code fonctionne bien chez moi en tout cas. Par défaut, mon main, dans led.c fait clignoter la ligne 9 du port J7. Pour faire clignoter la led rouge il suffira de changer PB0 par PC7. Je mettrai donc à jour l’archive tar.gz au fur et à mesure de mes modifications.
Je me suis également essayé à l’intégration de mes capteurs ultrasons SRF05, mais je me heurte encore à plusieurs problèmes. J’arrive à émettre mes salves d’ultrasons sans soucis, mais c’est la récupération des données de distance qui est un peu plus compliquée. Le capteur renvoie un signal à l’état haut, de la durée correspondant à la distance mesurée. Avec un changement d’échelle on obtient alors la distance en cm. Seul soucis, les signaux à manipuler ici sont de l’ordre de la microsecondes, et je n’arrive pas encore à estimer la durée reçue. J’utilise la fonction clock() pour travailler sur une différence de cycles d’horloge, fonction qui semble être la plus précise en C. Cependant, la durée de l’état haut relevé grâce à cette fonction me retourne 0 en permanence… Soit la fonction est trop précise, soit quelque chose ne va pas dans mon implémentation. Je vais essayer de me renseigner s’il n’existe pas mieux que la fonction clock() pour mesurer des durées de l’ordre de la dizaine/centaine de microsecondes. J’espère donc pouvoir utiliser rapidement ces capteurs, ils sont à la base du repérage de Robert.
Mots-clefs : carte fox, entrée, foxboard, G20, sortie, SRF05
-->










Je dis ça comme une piste potentielle qui me vient à l’esprit, mais plutôt que d’utiliser clock() tu ne peux pas avoir accès aux ticks du cpu directement ? De mes maigres connaissances je vois la chose comme ça : Une interruption matérielle enclenchée sur un changement d’état de la ligne, qui stocke dans un buffer le nombres de ticks du processeur (et donc sa différence quand tu retombes à l’état 0)…
Mais comme je n’ai aucune idée de l’architecture de la carte ni des solutions que tu as déjà testées, je risque fort d’être à coté :]
L’idée est intéressante, je pourrais le faire sur un simple PIC. Mais là c’est directement un processeur ARM, je sais pas si c’est faisable. Pour l’instant je semble être le premier à me soucier du problème du développement en C sur cette carte avec les IO, donc il n’y a pas de doc de dispo. Je vais continuer à fouiner, et essayer de voir si je peux pas m’en sortir. Parce que c’est quand même bête de se retrouver bloqué à cause de ça.
Merci pour l’idée en tout cas
Au sujet de ton problème, sauf erreur, il dépend de la précision de clock() qui donne un résultat en unité de mesure CPU, à convertir en micro-secondes via une division par la constante CLOCKS_PER_SEC (POSIX). Avoir un résultat en microsecondes ne signifie pas que la précision est d’une microseconde. J’ai une expérience de vieux systèmes où la précision était moyenne (dixième/centième de seconde). Ca veut dire que si la mesure dure moins de cette précision, la différence entre deux mesure de clock est 0.
Un test de mesure de clock sur une seconde permettrait de mesurer le nombre d’unités effectivement comptés (clock1=clock(); sleep(1); clock2=clock(), affichage clock2-clock1, sans conversion en seconde. Le calcul doit être fait en clock_t, non en int, sous peine d’une perte de précision.
Pardon si tout cela constitue des évidences pour toi.
Très intéressant ton site ! En particulier sur la FOX G20… tu travailles sur un totoriel ? j’attends avec impatience. Cela me donnera le courage de me (re)plonger dans l’électronique numérique..
Bonsoir,
Effectivement c’est bien là mon problème. L’utilisation de clock() ne me permet pas d’être suffisamment précis. Je travaille effectivement avec une différence de valeurs avant et après mon traitement, le tout divisé par CLOCKS_PER_SEC.
Mes capteurs ultrasons me renvoient un état haut, qui sera plus ou moins long selon la distance. Quand je ne mets aucun obstacle, je récupère effectivement une différence de tick horloge que je peux convertir en durée. Par contre quand je rapproche un obstacle à moins de 20 cm de mon capteur (l’état haut devient beaucoup plus court) et la durée (une dizaine de tour de boucles while) est trop faible pour être détectée par ma différence de ticks horloge. Ma durée est alors de 0 sec.
Autre problème, j’ai également testé ce week-end le coup du sleep entre 2 clock(), mais cela ne fonctionne pas. clock() me retourne la même valeur avant et après mon sleep … C’est assez embêtant.
Sinon, je manipule également des variables de type clock_t pour mes valeur avant/après.
Du coup, je suis assez dépité, je ne sais pas trop comment m’y prendre pour calculer des périodes de temps très petites (entre 100µs et 25ms). Peut-être en installant un patch temps réel sur le noyau… Bref, à voir.
Merci en tout cas à toi. Je vois au moins que mes tentatives n’étaient pas aussi stupides
Concernant la Fox G20, pour l’instant je n’ai pas trop de projet de tutoriel de prévu. Disons que je ne sais pas trop quoi aborder pour l’instant. Enfin certainement les entrées sorties en C quand j’en saurai plus. Mais il est difficile de savoir ce qui est en cours d’écriture par les autres utilisateurs de la fox G20 (cf le groupe de discussion google français en pleine ébullition). Quoi qu’il en soit, je continuerai à poster mes bidouilles ici (j’en ai plein de prévues). Et si matière il y a, je me lancerai dans un tutoriel
Je crois que j’ai compris. C’est ton test d’un sleep entre deux appels de clock qui m’a fournit la solution : Clock est orientée « temps processus utilisateur ». Ton programme est un processus parmi d’autres.
Le temps passé dans le noyau (lors d’un appel système comme sleep par exemple) ou dans d’autres processus, ne compte pas !!!
Une fonction comme gettimeofday prend le temps machine, vue de l’utilisateur, non du process. C’est là peut-être la solution pour bien mesurer le temps en prenant en compte toute l’activité de la machine.
#include
struct timeval tv1 ;
struct timezone tz;
gettimeofday(&tv1, &tz) alimente les deux structures passées par adresse.
tv est une structure dont voici le prototype :
struct timeval {
int tv_sec; /* secondes */
int tv_usec; /* microsecondes */
};
Bon courage.
Oui voilà, j’ai supposé que le sleep n’intervenait pas dans la gestion des ticks effectivement. Vu que cela met en pause simplement le processus, et que clock() renvoie le temps d’exécution depuis le début du processus. C’est même logique.
Merci pour la piste, c’est pas bête ! Je vais essayer ça dès que j’ai un peu de temps.
Bonjour je suis en BTS électronique et mon projet porte sur la foxboard, je ne sais pas comment utiliser le bus I2C et les entrées analogiques j’utilise le system GENTOO fournis avec.
En temps normal j’utilise des PIC donc je suis un peu perdu, mais j’ai vu que tu avait créer une librairie pour utiliser les I/O PC7 etc, c’est pareil pour le bus I2C ou elle sont intégrer? et pour les entrées analogiques aussi?
Merci d’avance
I2C est un peu plus complexe à interfacer que les entrées sorties classiques. D’ailleurs, je n’ai toujours pas trouvé le temps, mais il faudrait carrément développer au niveau kernel un peu de code pour interagir sur les I/O avec plus de précision.
Pour l’I2C, il semblerait que cela soit similaire. Hélas, je n’ai pas encore réellement regardé pour le portage, n’utilisant aucun périphérique I2C pour le moment. Je t’invite à te rendre sur le groupe de discussion anglais de la carte Fox où tu pourras trouver quelques discussions autour du Bus I2C
http://groups.google.fr/group/netusg20/browse_thread/thread/3f1abef0d88159db/5c27a62b06e0d527?hl=fr&lnk=gst&q=I2C#5c27a62b06e0d527
http://groups.google.fr/group/netusg20/browse_thread/thread/de9ff3f1c2c0a2f5/fd667045033254ea?hl=fr&lnk=gst&q=I2C#fd667045033254ea
Hélas, toutes les fonctions ne sont pas encore disponibles. Le convertisseur A/N ne semble pas encore non plus au point. Je ne peux que te conseiller de t’inscrire sur le groupe de discussion pour suivre l’avancée sur ces points précis. Tu peux même poser directement tes questions
Quelqu’un aura peut-être plus d’informations à te donner.
Bonjour,
Pourquoi ne ferais tu pas une boucle du genre :
static inline unsigned long long int get_clock()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (unsigned long long int)tv.tv_usec + 1000000*tv.tv_sec;
}
int getvalue()
{
…
unsigned long long int start = get_clock()
while ( get_clock()-start < 5)
continue; // ou bien une quelconque commande qui prend un peu de temps CPU pour être sur que le compilo prend bien en compte la boucle
…
}
Je sais que ce n'est pas très beau, on prend du cpu pour rien… mais peut-être que cela sera suffisant.
Je suis moi même très intéressé par faire fonctionner l'I2C, le PWM, et les entrées analog de la G20. Je me suis lancé dans la recompilation du kernel avec le tuto acme:
http://netus.acmesystems.it/doku.php?id=debian:how_to_cross_compile_a_kernel_and_create_the_debian_root_file_store
// coupure du message volontaire pour passer le spam detector :s
Désolé, je n’arrive pas à mettre la suite de mon message, ce spam détector me fait des misères…
BiLocK
Je pense que c’est la bonne voie, mais je ne suis pas sur de pouvoir configurer l’i2c proprement (je ne suis pas un expert dans la sujet :s ). L’idéal serait d’avoir quelques comme le newi2cdriver.rar mais adapté à la G20 (tech . groups . yahoo . com / group / foxboard / files / GeertVc / )
As tu recompilés ton kernel ? si oui, quel tuto as tu suivis ? ou bien tout de tête
?
Concernant le pwm, je n’ai pas vu les pin en question sur la G20, aurais je loupé quelque chose?
Merci pour ton site bien utile.
Bonsoir bilock,
J’ai reçu ton mail ce matin, mais je vois que tu as pu venir à bout de mon système anti-spam =) Bon, ce n’est absolument pas voulu, et c’est d’ailleurs curieux. Tu n’es pas le seul à avoir eu des soucis avec ce système de filtrage. Je vais voir si je ne peux pas le rendre un peu plus permissif.
Je testerai à l’occasion ta solution. Maintenant, il me semble qu’il ne s’agit là que d’un report du problème. La précision est juste bien trop mauvaise pour déterminer une courte période dans le temps. Je pense avoir la solution, c’est à dire écrire un driver adapté, mais je n’ai pas encore eu réellement le temps de m’y atteler. J’y compte bien, dès que j’aurai un peu de temps libre =)
Sinon, de la même façon, je n’ai pas encore eu le temps de recompiler le noyau de la G20. Je comptais m’y mettre, mais ma carte fox est tombée en panne (module netus défectueux) et Acme Systems m’a renvoyé une nouvelle carte fraichement flashée avec une Debian. Je n’ai pas poussé le vice jusqu’à la reflasher pour le fun. Donc je n’ai aucun mérite, et toutes les informations je les récupère sur le site du constructeur et sur les groupes de discussion google.
Pour le PWM, d’après la personne qui m’a donné de précieuses informations, il s’agirait de travailler avec le périphérique Timer/Counter (TC) en travaillant avec les GPIO et TIOA & TIOAB. Se référer à la doc du processeur AT91SAM9G20. Il faut écrire un driver pour cela, mais je n’ai pas encore eu le temps de m’y mettre =(
Je ne manquerai pas de poster mon avancement sur mon blog !
Et merci, c’est un plaisir si mon site peut t’être utile
Yoann
Salut Yoann,
Il semble que ce soit l’url qui m’empêchait de poster.
Il est sur que la solution que je propose est un peu tricky, mais elle est utilisée pour augmenter facilement la précision de sleep. On perd du CPU mais on gagne de la précision… (http://defectivecompass.wordpress.com/2006/09/01/high-precision-sleep/)
As tu essayer la recommandation de dougg sur cette page ?
http://groups.google.fr/group/netusg20/browse_thread/thread/3f1abef0d88159db/5c27a62b06e0d527?hl=fr&lnk=gst&q=I2C#5c27a62b06e0d527
Qui consiste à modifier le .config avec les variables :
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_GPIO=y
J’y suis mais je découvre en même temps
donc ca me prend du temps…
Jerome
C’est bien intéressant tout ça ! Merci pour le lien.
Je vais tenter tes recommandations dès que je trouve un peu de temps.
Sinon, je ne me suis pas encore penché sur l’I2C, n’ayant pas de périphérique I2C sous la main. Mais j’irai regarder à l’occasion dans les options du kernel. Il semble y avoir des choses intéressantes.
Pour info,
en suivant le tutorial de cross compilation du kernel de Lee : http://netus.acmesystems.it/doku.php?id=debian:how_to_cross_compile_a_kernel_and_create_the_debian_root_file_store#experimentaldebian_squeeze_testing
et en applicant les modifs suggérées par dougg alors j’arrive a voir un device I2C qui répond bien à l’i2cdetect :
debarm:~# i2cdetect -F 0
Functionalities implemented by /dev/i2c-0:
I2C yes
SMBus Quick Command yes
SMBus Send Byte yes
SMBus Receive Byte yes
SMBus Write Byte yes
SMBus Read Byte yes
SMBus Write Word yes
SMBus Read Word yes
SMBus Process Call yes
SMBus Block Write yes
SMBus Block Read yes
SMBus Block Process Call yes
SMBus PEC yes
I2C Block Write yes
I2C Block Read yes
Maintenant il faut sortir l’oscillo pour vérirfier