IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Administration système Discussion :

Driver - Programmation Bas niveau


Sujet :

Administration système

  1. #1
    Nouveau membre du Club
    Inscrit en
    Juillet 2006
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 55
    Points : 38
    Points
    38
    Par défaut Driver - Programmation Bas niveau
    Bonjour,
    J'écris actuellement une application pour une carte Axis composée :
    - d'un processeur Etrax 100 , Linux embarqué
    - d'un circuit programmable (FPGA)
    - d'une FIFO

    Mon application consiste en la mise en oeuvre d'un transfert DMA entre la FIFO et une mémoire qui se trouve également sur la carte.
    J'utilise donc un pilote DMA, dans lequel sont définies plusieurs file_operations : dma_open, dma_release, dma_read, dma_write, dma_poll, etc...
    Dans mon application, j'appelle donc la fonction read ; cette fonction, losqu'elle est appelée, endort le processus, et attend d'être réveillée par une requête DMA pour se réveiller et lire effectivement les données

    Il y a pour cela dans le pilote une fonction rx_interrupt() , qui est censée être appelée dès que la FIFO commence à se remplir... en gros, quand la FIFO est remplie à un certain seuil, elle émet une requête DMA au processeur, et le processeur doit alors appeler la fonction rx_interrupt, qui réveille la fonction read, et la fonction read lit alors les données.

    Mon problème est le suivant : comment "expliquer" au processeur que lorsqu'il reçoit le signal physique correspondant à la requête DMA, il doit alors appeller la fonction rx_interrupt() .......
    Ca serait tres gentil si on pouvait me filer un coup de main...

  2. #2
    Membre éprouvé Avatar de gnto
    Homme Profil pro
    Ingénieur système logiciel
    Inscrit en
    Janvier 2006
    Messages
    923
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur système logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2006
    Messages : 923
    Points : 1 210
    Points
    1 210
    Par défaut
    Salut,

    Je suis loin d'etre un pro des drivers linux, j'en ai fais un pour l'école il'y a 2 ans et c'était un driver pour carte ISA. Bref j'ai pas réellement compris ce que tu veux que l'on t'explique ? Tu veux récupérer l'interruption généré par ta carte ?

  3. #3
    Membre éprouvé Avatar de gnto
    Homme Profil pro
    Ingénieur système logiciel
    Inscrit en
    Janvier 2006
    Messages
    923
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur système logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2006
    Messages : 923
    Points : 1 210
    Points
    1 210
    Par défaut
    Bon voila ce que j'ai trouvé pour les interruptions ISA je suppose que c'est plus compliqué en DMA.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /*attribution des interruptions */
    result = request_irq(5,gestionnaire,SA_INTERRUPT,"Decor", NULL);
        if (result) 
            printk(KERN_INFO "decor: Ne peut traiter l'interruption 5\n");
    Donc l'interruption IRQ 5 est associé a une fonction nommé gestionnaire. SA_INTERRUPT, je crois que c'est le type d'interruption et "Decor" c'est le nom que je lui donne a cette interruption.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    freak@Qouark /opt/coloration $ cat /proc/interrupts
              CPU0
      0:    6630946          XT-PIC  timer
      1:      37538          XT-PIC  i8042
      2:          0          XT-PIC  cascade
      5:    2158704          XT-PIC  EMU10K1
      9:          0          XT-PIC  acpi
     10:    2252832          XT-PIC  fglrx
     11:    1484240          XT-PIC  ohci_hcd:usb1, ohci_hcd:usb2, ra0
     12:    1486838          XT-PIC  i8042
     14:     145954          XT-PIC  ide0
     15:     470786          XT-PIC  ide1
    NMI:          0
    ERR:          0
    si j'avais eut la carte ISA j'aurais eut

    où 5 indique le numéro de l'interruption 0 le nombre d'interruption déclenché XT-PIC je ne sais pas depuis le 2.6 et enfin le nom que j'ai donné a l'interruption.

    sinon il te reste le pdf du oreilly traitant des drivers sous linux
    Linux Device Drivers, Third Edition

  4. #4
    Nouveau membre du Club
    Inscrit en
    Juillet 2006
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 55
    Points : 38
    Points
    38
    Par défaut
    Excellent c'est nickel, ca me met vraiment sur la piste, parce qu'en farfouillant j'ai vu des choses équivalentes y a quelques temps, genre une fonction
    request_dma() et d'autres ds le genre, ds un fichier dma.h
    merci bcp

  5. #5
    Nouveau membre du Club
    Inscrit en
    Juillet 2006
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 55
    Points : 38
    Points
    38
    Par défaut
    En fait, je suis embetté, je m'en sors pas
    J'ai trouvé dans un fichier include/asm/dma.h une méthode request_dma()
    qui est implémentée dans kernel/dma.c

    là voici

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int request_dma(unsigned int dmanr, const char * device_id)
    {
    	if (dmanr >= MAX_DMA_CHANNELS)
    		return -EINVAL;
     
    	if (xchg(&dma_chan_busy[dmanr].lock, 1) != 0)
    		return -EBUSY;
     
    	dma_chan_busy[dmanr].device_id = device_id;
     
    	/* old flag was 0, now contains 1 to indicate busy */
    	return 0;
    } /* request_dma */
    si je comprends bien, l'argument dmanr correspond au numéro du canal que je veux réserver, et device_id... à l'adresse du périphérique?
    en tout cas j'aurais vraiment aimé avoir un argument correspondant à la "routine d'interruption", c'est à dire là où je mettrai l'adresse de ma fonction rx_interrupt()
    ma fonction rx_interrupt() est la suivante , je rappelle qu'elle est définie dans le pilote
    si t'as une idée, je suis très preneur
    merci d'avance



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    static void rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
    {
    	etrax_dma_descr* dma_d;
    	unsigned long ireg = *R_IRQ_MASK2_RD;
    	int i;
     
    	DIRQ(printk("RX IRQ\n"));
     
    	for (i = 0; i < NBR_OF_PORTS; i++)
    	{
    		ext_dma_port* port = &ports[i];
    		if (ireg & (1 << port->input_dma_descr_bit))
    		{
    			dma_d = (etrax_dma_descr*)phys_to_virt(*port->input_dma_descr);
    			if (!dma_d)
    				dma_d = port->prev_in_descr;
     
    			while (port->next_in_descr != dma_d) {
    				port->writep += TRANSFER_SIZE;
    				port->next_in_descr = phys_to_virt(port->next_in_descr->next);
    			}
    			wake_up_interruptible(&port->in_wait_q);
    			*port->output_dma_clr_irq = IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do);
    		}
    	}
     
    }

  6. #6
    Membre éprouvé Avatar de gnto
    Homme Profil pro
    Ingénieur système logiciel
    Inscrit en
    Janvier 2006
    Messages
    923
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur système logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2006
    Messages : 923
    Points : 1 210
    Points
    1 210
    Par défaut
    Alors la mon doute s'est réveillé DMA Direct Memory Access c'est une méthode pour accéder a la mémoire. Maintenant ta carte est soit PCI ou ISA. Je ne pense pas que le DMA existe en USB

    Si c'est une interruption PCI
    page 17

  7. #7
    Nouveau membre du Club
    Inscrit en
    Juillet 2006
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 55
    Points : 38
    Points
    38
    Par défaut
    j'ai que le 2nd Edition
    il est consultable sur le net le third edition ? ou alors faut l'acheter ?

  8. #8
    Nouveau membre du Club
    Inscrit en
    Juillet 2006
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 55
    Points : 38
    Points
    38
    Par défaut
    ah c'est bon, j'ai trouvé
    merci

  9. #9
    Membre éprouvé Avatar de gnto
    Homme Profil pro
    Ingénieur système logiciel
    Inscrit en
    Janvier 2006
    Messages
    923
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur système logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2006
    Messages : 923
    Points : 1 210
    Points
    1 210
    Par défaut
    Ta carte c'est bien une carte PCI ?

  10. #10
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par abennis
    j'ai que le 2nd Edition
    il est consultable sur le net le third edition ? ou alors faut l'acheter ?
    Plutot que de chercher sur le net : Le kit de survie du developpeur Linux

  11. #11
    Nouveau membre du Club
    Inscrit en
    Juillet 2006
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 55
    Points : 38
    Points
    38
    Par défaut
    c ni une isa ni une pci
    c pas une carte pour pc

    mais dis,est ce qu'il suffit pas tt simplement d'utiliser sigaction() pour associer mon signal à ma fonction rx_interrupt() ? le probleme qui se pose alors, c'est comment connaitre le numéro du signal de la requête DMA ? sachant que cette requête DMA, a été programmée physiquement par mon tuteur de stage (actuellement en vacances) pr se déclencher quand la fifo se remplit jusqu'à un certain seuil

  12. #12
    Membre éprouvé Avatar de gnto
    Homme Profil pro
    Ingénieur système logiciel
    Inscrit en
    Janvier 2006
    Messages
    923
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur système logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2006
    Messages : 923
    Points : 1 210
    Points
    1 210
    Par défaut
    Citation Envoyé par abennis
    c ni une isa ni une pci
    c pas une carte pour pc

    mais dis,est ce qu'il suffit pas tt simplement d'utiliser sigaction() pour associer mon signal à ma fonction rx_interrupt() ? le probleme qui se pose alors, c'est comment connaitre le numéro du signal de la requête DMA ? sachant que cette requête DMA, a été programmée physiquement par mon tuteur de stage (actuellement en vacances) pr se déclencher quand la fifo se remplit jusqu'à un certain seuil
    Sigaction associe des signaux systemes et d'après ce que j'avais lu dans le oreilly, il y'a un cloisonnement entre la mémoire utilisateur(celle du systeme) et la mémoire du noyaux donc tous les signaux matériel passe d'abord dans le noyaux pour ensuite aller vers le system.

    DMA ca veux bien dire Direct Memory Access nan ?

    Les canaux DMA (Direct Access Memory) permettent de réaliser des transferts directs de données entre la mémoire vive d'un ordinateur et des périphériques. L'avantage de ce procédé est de ne pas passer par le microprocesseur qui peut ainsi se consacrer à d'autres tâches. L'utilisation de canaux DMA améliore donc les performances d'un ordinateur.
    Si tu ne passes pas par le processeur comment veux tu traiter une interruption ?

    C'est quoi ce périphérique ? c'est monté sur une architecture PC ? Un Chassis VME ?

  13. #13
    Nouveau membre du Club
    Inscrit en
    Juillet 2006
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 55
    Points : 38
    Points
    38
    Par défaut
    je ne passe pas par le processeur pour ce qui est du transfert de données en lui-même (qui se fait DIRECTement)
    mais je passe quand même par le processeur pour lui envoyer une sorte d'interruption spéciale, un signal qui d'appres ma doc s'appelle DREQ (pour DMA Request) , et il me renvoie un signal DACK (pour DMA Acknowledge) ; à partir de là le transfert de données commence et le processeur n'intervient plus

    quant à la carte... je t'avoue que j'ai un peu de mal avec tout ce qui est hardware...

    en fait c apparemment une puce, qui contient processeur et mémoires ( http://developer.axis.com/products/mcm/index.html )

    et cette meme puce se trouve sur une carte ( http://developer.axis.com/products/axis_82/index.html )
    là je commence vraiment à bloquer, chais plus quelle piste explorer

  14. #14
    Membre éprouvé Avatar de gnto
    Homme Profil pro
    Ingénieur système logiciel
    Inscrit en
    Janvier 2006
    Messages
    923
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur système logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2006
    Messages : 923
    Points : 1 210
    Points
    1 210
    Par défaut
    OK, j'avais une mauvaise interprétation du mot "device".

    La c'est une carte avec un linux embarqué.

    The operating system of choice is either Linux 2.4 or Linux 2.6. Both include the CRIS port to execute the OS on the ETRAX 100LX CPU or later.

    The kernel includes ETRAX drivers for:

    * Ethernet
    * Serial ports
    * Parallel ports
    * General Purpose I/O (GPIO)
    * USB Host
    * IDE
    Tu échange des données entre quoi et quoi ?

    ethernet vers série ?
    éthernet vers usb ?

  15. #15
    Nouveau membre du Club
    Inscrit en
    Juillet 2006
    Messages
    55
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 55
    Points : 38
    Points
    38
    Par défaut
    mon transfert de données se fait de la FIFO vers l'une des 2 mémoires dont est muni le processeur

    peu importe ici le traitement qui en est fait par la suite (ethernet, port série, port usb ... )
    le transfert qui m'intéresse ici se fait au sein même de la carte, entre la FIFO et le processeur, sur un bus de données appelé canal DMA, dont la largeur peut être configurée à 8, 16 ou 32 bits
    le rôle total de l'application pourrait se diviser en ces étapes :
    1) Génération continue de données dans la FIFO, par une source externe
    2) Quand la FIFO atteint un certain seuil de remplissage, elle envoie une requête DMA (signal DREQ) au processeur.
    3) Le processeur renvoie un signal DACK, et "autorise" le transfert DMA à démarrer. Pour cela, il est nécessaire d'appeler une fonction rx_interrupt() définie dans mon driver.
    4) Le processeur ne se soucie plus de rien et peut reprendre son activité pendant que le transfert DMA entre la fifo et la mémoire se fait.
    Dans tout ça, tout est OK, tout marche, sauf un seul truc : comment spécifier au processeur :
    "Quand tu reçois le signal DREQ , tu appelles la fonction rx_interrupt() "
    C'est le seul truc que j'arrive pas à faire. Si j'arrive à faire ça, c'est gagné.

  16. #16
    Membre éprouvé Avatar de gnto
    Homme Profil pro
    Ingénieur système logiciel
    Inscrit en
    Janvier 2006
    Messages
    923
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur système logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2006
    Messages : 923
    Points : 1 210
    Points
    1 210
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    static int __init etrax_sync_serial_init(void)
    {
    	ports[0].enabled = 0;
    	ports[1].enabled = 0;
    
    	if (register_chrdev(SYNC_SERIAL_MAJOR,"sync serial", &sync_serial_fops) <0 ) 
    	{
    		printk("unable to get major for synchronous serial port\n");
    		return -EBUSY;
    	}
    
    	/* Deselect synchronous serial ports */
    	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
    	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
    	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, ser3, select);
    	*R_GEN_CONFIG_II = gen_config_ii_shadow;
      
    	/* Initialize Ports */
    #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
    	ports[0].enabled = 1;
    	SETS(port_pb_i2c_shadow, R_PORT_PB_I2C, syncser1, ss1extra); 
    	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync);
    #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
    	ports[0].use_dma = 1;
    	initialize_port(0);
    	if(request_irq(24, tr_interrupt, 0, "synchronous serial 1 dma tr", &ports[0]))
    		 panic("Can't allocate sync serial port 1 IRQ");
    	if(request_irq(25, rx_interrupt, 0, "synchronous serial 1 dma rx", &ports[0]))
    		panic("Can't allocate sync serial port 1 IRQ");
    	RESET_DMA(8); WAIT_DMA(8);
    	RESET_DMA(9); WAIT_DMA(9);
    	*R_DMA_CH8_CLR_INTR = IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) |
    	  IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do); 
    	*R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do) |
    	  IO_STATE(R_DMA_CH9_CLR_INTR, clr_descr, do); 
    	*R_IRQ_MASK2_SET =
    	  IO_STATE(R_IRQ_MASK2_SET, dma8_eop, set) |
    	  IO_STATE(R_IRQ_MASK2_SET, dma8_descr, set) |
              IO_STATE(R_IRQ_MASK2_SET, dma9_descr, set);
    	start_dma_in(&ports[0]);
    #else
    	ports[0].use_dma = 0;
    	initialize_port(0);
    	if (request_irq(8, manual_interrupt, SA_SHIRQ, "synchronous serial manual irq", &ports[0]))
    		panic("Can't allocate sync serial manual irq");
    	*R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, ser1_data, set);	 
    #endif
    #endif

    http://www.nc-orc.lkams.kernel.org/p...ync_serial.c,v
    voila la page ou je l'ai trouvé

    havin' fun

Discussions similaires

  1. Programme d'étude sur le C++ bas niveau
    Par Bousk dans le forum C++
    Réponses: 24
    Dernier message: 21/12/2014, 20h23
  2. Terra : le nouveau langage de programmation bas niveau sort
    Par Cedric Chevalier dans le forum Autres langages
    Réponses: 1
    Dernier message: 24/05/2013, 12h43
  3. C et programmation bas niveau
    Par ledawa dans le forum Windows
    Réponses: 4
    Dernier message: 24/09/2007, 20h45
  4. Programmation bas niveau de la carte vidéo !!
    Par Invité dans le forum Assembleur
    Réponses: 3
    Dernier message: 03/03/2005, 11h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo