Précédent   Forum des professionnels en informatique > Systèmes > Linux > Système
Système Vos questions autour de l'administration système
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 19/07/2006, 16h35   #1
Candidat au titre de Membre du Club
 
Inscription : juillet 2006
Messages : 55
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 55
Points : 12
Points : 12
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...
abennis est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/07/2006, 19h48   #2
Membre Expert
 
Avatar de gnto
 
Homme
Consultant informatique
Inscription : janvier 2006
Messages : 910
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Consultant informatique
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : janvier 2006
Messages : 910
Points : 1 182
Points : 1 182
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 ?
gnto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/07/2006, 19h56   #3
Membre Expert
 
Avatar de gnto
 
Homme
Consultant informatique
Inscription : janvier 2006
Messages : 910
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Consultant informatique
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : janvier 2006
Messages : 910
Points : 1 182
Points : 1 182
Bon voila ce que j'ai trouvé pour les interruptions ISA je suppose que c'est plus compliqué en DMA.
Code :
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 :
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
gnto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/07/2006, 00h12   #4
Candidat au titre de Membre du Club
 
Inscription : juillet 2006
Messages : 55
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 55
Points : 12
Points : 12
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
abennis est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/07/2006, 11h12   #5
Candidat au titre de Membre du Club
 
Inscription : juillet 2006
Messages : 55
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 55
Points : 12
Points : 12
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 :
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 :
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);
		}
	}
 
}
abennis est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/07/2006, 15h53   #6
Membre Expert
 
Avatar de gnto
 
Homme
Consultant informatique
Inscription : janvier 2006
Messages : 910
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Consultant informatique
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : janvier 2006
Messages : 910
Points : 1 182
Points : 1 182
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
gnto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/07/2006, 15h56   #7
Candidat au titre de Membre du Club
 
Inscription : juillet 2006
Messages : 55
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 55
Points : 12
Points : 12
j'ai que le 2nd Edition
il est consultable sur le net le third edition ? ou alors faut l'acheter ?
abennis est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/07/2006, 15h59   #8
Candidat au titre de Membre du Club
 
Inscription : juillet 2006
Messages : 55
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 55
Points : 12
Points : 12
ah c'est bon, j'ai trouvé
merci
abennis est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/07/2006, 16h12   #9
Membre Expert
 
Avatar de gnto
 
Homme
Consultant informatique
Inscription : janvier 2006
Messages : 910
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Consultant informatique
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : janvier 2006
Messages : 910
Points : 1 182
Points : 1 182
Ta carte c'est bien une carte PCI ?
gnto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/07/2006, 18h26   #10
Rédacteur
 
Avatar de gege2061
 
Inscription : juin 2004
Messages : 5 850
Détails du profil
Informations personnelles :
Âge : 28
Localisation : France, Indre et Loire (Centre)

Informations forums :
Inscription : juin 2004
Messages : 5 850
Points : 8 299
Points : 8 299
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
__________________
gege2061's blog
gege2061 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/07/2006, 14h32   #11
Candidat au titre de Membre du Club
 
Inscription : juillet 2006
Messages : 55
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 55
Points : 12
Points : 12
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
abennis est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/07/2006, 15h29   #12
Membre Expert
 
Avatar de gnto
 
Homme
Consultant informatique
Inscription : janvier 2006
Messages : 910
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Consultant informatique
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : janvier 2006
Messages : 910
Points : 1 182
Points : 1 182
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 ?

Citation:
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 ?
gnto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/07/2006, 15h44   #13
Candidat au titre de Membre du Club
 
Inscription : juillet 2006
Messages : 55
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 55
Points : 12
Points : 12
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
abennis est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/07/2006, 16h07   #14
Membre Expert
 
Avatar de gnto
 
Homme
Consultant informatique
Inscription : janvier 2006
Messages : 910
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Consultant informatique
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : janvier 2006
Messages : 910
Points : 1 182
Points : 1 182
OK, j'avais une mauvaise interprétation du mot "device".

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

Citation:
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 ?
gnto est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/07/2006, 16h35   #15
Candidat au titre de Membre du Club
 
Inscription : juillet 2006
Messages : 55
Détails du profil
Informations forums :
Inscription : juillet 2006
Messages : 55
Points : 12
Points : 12
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é.
abennis est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/07/2006, 16h50   #16
Membre Expert
 
Avatar de gnto
 
Homme
Consultant informatique
Inscription : janvier 2006
Messages : 910
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Consultant informatique
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : janvier 2006
Messages : 910
Points : 1 182
Points : 1 182
Code :
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
gnto est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 11h12.


 
 
 
 
Partenaires

Hébergement Web