Compilation et debogage de module linux, aux pros de l'algo et systeme

Compilation et debogage de module linux, aux pros de l'algo et systeme - C - Programmation

Marsh Posté le 23-06-2003 à 21:58:16    

bonjour,
 
je developpe actuellement une application sous linux necessitant le port infra rouge et apres avoir galéré a installer lirc dessus, ca ne marche finalement pas. Ou plutot tout marche mais je ne recois pas correctement les signaux.
 
ex :
 
j envoie un signal codé en RC5 (il faut savoir que le RC5 code ses bits avec des fronts montant et descendant de 889 µs, donc  je suis censé recevoir des PULSE et des SPACES d environ 889µs +- delta OU 2*889=1778µs +- delta), et je recois des donnees completement differentes (a  savoir sur une autre machine avec d autres composants ca marche tres bien).
 
Mais je recois quelque chose qui "ressemble" : je m explique
 
si j etais censé recevoir :
 
SPACE 16777216
PULSE 889
SPACE 889
PULSE 889
SPACE 1778
PULSE 889
SPACE 889
PULSE 1778
SPACE 1778
 
 
je recois a la place  
 
SPACE 1677216
PULSE 39
SPACE 1700
PULSE 39
SPACE 1765
PULSE 39
SPACE 2643
PULSE 39
etc...
 
J ai donc remarqué que les temps entre 2 pulses (somme de pulse + space ) etait le meme (+- delta je precise) entre ce que j emets et ce que je receptionne. Autrement dit, l interruption se produit bien mais le temps calculé pour le pulse est faux.  
 
D ailleurs je precise que la valeur "39" n est pas une valeur anodine mais exactement egale a la moitié d'une constante dans le driver  
soit 9bits * 1 sec / 115200 bits = 78,25 ms  
 
 
j ai donc decidé de "completer" le driver pour qu il puisse fonctionner avec mon controleur IR (car j ai pas le choix) mais j avoue que dans le source, quelques choses me laissent perplexes :
 
voici le source de la fonction invoquée lors d'une interruption (le define LIRC_SA1100 concerne les PDA de type Ipaq donc a ignorer)
 
 
 

Code :
  1. static void sir_interrupt(int irq, void * dev_id, struct pt_regs * regs)
  2. {
  3. unsigned char data;
  4. struct timeval curr_tv;
  5. static unsigned long deltv;
  6. #ifdef LIRC_ON_SA1100
  7. int status;
  8. static int n=0;
  9. //printk("interrupt\n" );
  10. status = Ser2UTSR0;
  11. /*
  12.  * Deal with any receive errors first.  The bytes in error may be
  13.  * the only bytes in the receive FIFO, so we do this first.
  14.  */
  15. while (status & UTSR0_EIF)
  16. {
  17.  int bstat;
  18. #ifdef DEBUG
  19.  printk("EIF\n" );
  20.  bstat = Ser2UTSR1;
  21.  if (bstat & UTSR1_FRE)
  22.   printk("frame error\n" );
  23.  if (bstat & UTSR1_ROR)
  24.   printk("receive fifo overrun\n" );
  25.  if(bstat&UTSR1_PRE)
  26.   printk("parity error\n" );
  27. #endif
  28.  bstat = Ser2UTDR;
  29.  n++;
  30.  status = Ser2UTSR0;
  31. }
  32. if (status & (UTSR0_RFS | UTSR0_RID))
  33. {
  34.  do_gettimeofday(&curr_tv);
  35.  deltv = delta(&last_tv, &curr_tv);
  36.  do
  37.  {
  38. #ifdef DEBUG_SIGNAL
  39.   printk(KERN_DEBUG LIRC_DRIVER_NAME": t %lu , d %d\n",
  40.          deltintrtv,(int)data);
  41. #endif
  42.   data=Ser2UTDR;
  43.   //printk("data: %d\n",data);
  44.   n++;
  45.  }
  46.  while(status&UTSR0_RID && /* do not empty fifo in
  47.                                              order to get UTSR0_RID in
  48.                                              any case */
  49.        Ser2UTSR1 & UTSR1_RNE); /* data ready */
  50.  if(status&UTSR0_RID)
  51.  {
  52.   //printk("add\n" );
  53.   add_read_queue(0,deltv-n*TIME_CONST); /*space*/
  54.   add_read_queue(1,n*TIME_CONST); /*pulse*/
  55.   n=0;
  56.   last_tv=curr_tv;
  57.  }
  58. }
  59. if (status & UTSR0_TFS) {
  60.  printk("transmit fifo not full, shouldn't ever happen\n" );
  61. }
  62. /*
  63.  * We must clear certain bits.
  64.  */
  65. status &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB);
  66. if (status)
  67.  Ser2UTSR0 = status;
  68. #else
  69. unsigned long deltintrtv;
  70. unsigned long flags;
  71. int iir, lsr;
  72. while ((iir = inb(io + UART_IIR) & UART_IIR_ID)) {
  73.  switch (iir&UART_IIR_ID) { /* FIXME toto treba preriedit */
  74.  case UART_IIR_MSI:
  75.   (void) inb(io + UART_MSR);
  76.   break;
  77.  case UART_IIR_RLSI:
  78.   (void) inb(io + UART_LSR);
  79.   break;
  80.  case UART_IIR_THRI:
  81. #if 0
  82.   if (lsr & UART_LSR_THRE) /* FIFO is empty */
  83.    outb(data, io + UART_TX)
  84. #endif
  85.   break;
  86.  case UART_IIR_RDI:
  87.   /* avoid interference with timer */
  88.    spin_lock_irqsave(&timer_lock, flags);
  89.   do
  90.   {
  91.    del_timer(&timerlist);
  92.    data = inb(io + UART_RX);
  93.    do_gettimeofday(&curr_tv);
  94.    deltv = delta(&last_tv, &curr_tv);
  95.    deltintrtv = delta(&last_intr_tv, &curr_tv);
  96. #ifdef DEBUG_SIGNAL
  97.    printk(KERN_DEBUG LIRC_DRIVER_NAME": t %lu , d %d\n",deltintrtv,(int)data);
  98. #endif
  99.    /* if nothing came in last 2 cycles,
  100.       it was gap */
  101.    if (deltintrtv > TIME_CONST * 2) {
  102.     if (last_value) {
  103. #ifdef DEBUG_SIGNAL
  104.      printk(KERN_DEBUG LIRC_DRIVER_NAME ": GAP\n" );
  105. #endif
  106.      /* simulate signal change */
  107.      add_read_queue(last_value,
  108.              deltv-
  109.              deltintrtv);
  110.      last_value = 0;
  111.      last_tv.tv_sec = last_intr_tv.tv_sec;
  112.      last_tv.tv_usec = last_intr_tv.tv_usec;
  113.      deltv = deltintrtv;
  114.     }
  115.    }
  116.    data = 1;
  117.    if (data ^ last_value) {
  118.     /* deltintrtv > 2*TIME_CONST,
  119.                                            remember ? */
  120.     /* the other case is timeout */
  121.     add_read_queue(last_value,
  122.             deltv-TIME_CONST);
  123.     last_value = data;
  124.     last_tv = curr_tv;
  125.     if(last_tv.tv_usec>=TIME_CONST)
  126.     {
  127.      last_tv.tv_usec-=TIME_CONST;
  128.     }
  129.     else
  130.     {
  131.      last_tv.tv_sec--;
  132.      last_tv.tv_usec+=1000000-
  133.       TIME_CONST;
  134.     }
  135.    }
  136.    last_intr_tv = curr_tv;
  137.    if (data)
  138.    {
  139.     /* start timer for end of sequence detection */
  140.     timerlist.expires = jiffies + SIR_TIMEOUT;
  141.     add_timer(&timerlist);
  142.    }
  143.   }
  144.   while ((lsr = inb(io + UART_LSR))
  145.    & UART_LSR_DR); /* data ready */
  146.   spin_unlock_irqrestore(&timer_lock, flags);
  147.   break;
  148.  default:
  149.   break;
  150.  }
  151. }
  152. #endif
  153. }


 
 
* a un moment dans le do .. while on a un truc du genre  
 

Code :
  1. data = inb(io + UART_RX);


 
je ne suis pas (encore) expert dans l ecriture des modules, mais si j ai bien compris, cela permet de lire une valeur IO a l adresse io (l adresse io de mon peripherique = l adresse io de mon controleur IR spécifiée dans le bios)
 
mais plus loin dans le code , on s apercoit qu on ecrase la valeur data (data=1;) sans avoir testé cette valeur auparavant... quel interet ? (j ai pas compris)
 
 
* juste apres je vois le test :
 

Code :
  1. if (data ^ last_value)


 
c est un XOR bit a bit il me semble. Sachant que data vaut forcement 1 , cela signifie donc qu on passe dans le if si le premier bit de last_value est a 0 .. donc pourquoi ce test ?
 
*  a un moment , on a : "if nothing came in last 2 cycles, it was gap "  
 
Je ne comprends pas ce que signifie cette phrase... apparemment a chaque interruption il passe dedans OR il ne devrait pas passer dedans.Quelqu un peut m eclairer ?
 
 
* enfin, je n ai pas trouvé de doc parlant des constantes du genre  
 
UART_RX
UART_LSR
UART_IIR_RDI  
etc...
 
quelqu un peut il me dire ou trouver de la doc ?
 
 
 
merci de m aider car je ne comprends pas bien l interet de l algo  permettant de calculer le temps du PULSE et le temps du SPACE.
 
 
 
merci d avoir lu jusque la ;-)

Reply

Marsh Posté le 23-06-2003 à 21:58:16   

Reply

Marsh Posté le 24-06-2003 à 08:17:30    

 :ouch:  :ouch: :pt1cable: Yen a qui ont bien du courage si tot le matin!!!!

Reply

Marsh Posté le 24-06-2003 à 10:08:20    

quelle version du noyau as-tu? S'on regard la configuration du module Ir dans le noyau 2.4.20 de base, beaucoup d'options sont inaccessibles ou 'EXPERIMENTAL', c'est-à-dire qu'elles sont en cours de développement. Tu peux essayer de regarder sur kernel.org les sources du noyau en cours de dével (2.5.* où * est suppérieur à 75 ;-) ...

Reply

Marsh Posté le 24-06-2003 à 12:15:34    

je suis en noyau 2.4.20 et je  n ai pas besoin de la gestion IR du noyau (je dois meme l enlever) car c est directement mon module qui pilote le controleur. D ailleurs ca marche bien vu que je recois des interruptions.
 
Par contre apres renseignements , le controleur IR fait partie d une puce (contenant d autres controleurs) de chez winbond modele : W83877TF.
 
Apparemment, apres tests, je recois une interruption lors d'un front descendant (chute du signal si vous preferez) mais pas lors  d un front montant (verifié avec un oscilloscope et debugage du module).
 
Donc je pense que l initialisation de mon controleur est mauvaise ... mais je n ai pas trop d infos a ce niveau.
 
 
 
 

Reply

Marsh Posté le 24-06-2003 à 15:44:01    

up .... personne ne sait ?

Reply

Marsh Posté le 25-06-2003 à 08:15:05    

up

Reply

Marsh Posté le 25-06-2003 à 12:40:42    

:cry:

Reply

Marsh Posté le 25-06-2003 à 15:43:16    

chtit informations supplémentaires :
 
j ai configuré mon controleur sur irq 11 et IO 0x03E8
 
j ai recupéré les valeurs des registres du controleur ... voici les valeurs :
 
         hex :       bin :
io + 0 : 0x7F        01111111
io + 1 : 0x01        00000001
io + 2 : 0xC1        11000001  
io + 3 : 0x02        00000010
io + 4 : 0x0B        00001011
io + 5 : 0x60        01100000
io + 6 : 0x00        00000000
io + 7 : 0x00        00000000
 
j'ai regardé la doc technique du W83877TF mais ca ne m apporte pas grand chose (et je ne comprends pas tout).

Reply

Marsh Posté le 26-06-2003 à 08:44:06    

j'm'etais deja pris des bides mais a ce point la ...

Reply

Marsh Posté le 14-07-2003 à 17:44:21    

J'ai déjà bricolé un module, mais c'était pas aussi près du hard.
 
Le inb, ça correspond à l'instruction assembleur IN, qui te permet de lire un octet sur le port donné en argument.
 
Par contre, je dis ça comme ça: tu es sûr d'avoir les mêmes paramètres pour les bits d'arrêt et de parité et tout ça ? C'est généralement des trucs comme ça qui empêche le matos de tourner.
 
Sinon si tu tiens à faire un module perso, dégage ce qui ne concerne pas ton matériel on y verra plus clair.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed