Basculer le menu
Changer de menu des préférences
Basculer le menu personnel
Non connecté(e)
Votre adresse IP sera visible au public si vous faites des modifications.

« Linux uart sunxi armbian » : différence entre les versions

De The Linux Craftsman
Aucun résumé des modifications
Ligne 26 : Ligne 26 :


= Programmation C =
= Programmation C =
Ci-dessous un ''petit'' exemple de programme qui accède au port UART pour lire:
Passons en revue les différentes étapes qui nous permettent d'utiliser le port UART:
* la première étape consiste à ouvrir le port, cela se fait avec la fonction ''open''
<source lang="c">
<source lang="c">
int fd = open(tty, O_RDWR | O_NOCTTY);
</source>
* Une fois le port ouvert on peut écrire avec la fonction ''write'' en utilisant le descripteur de fichier retourné par ''open'':
<source lang="c">
write(fd, message, strlen(message));
</source>
* On peut lire avec la fonction ''read'' en utilisant également le descripteur de fichier ainsi qu'un tampon (tableau de caractères). N'oubliez pas le ''\0'' qu'il faut ajouter si vous voulez manipuler votre tampon !
<source lang="c">
char buf[10] = "";
int len = read(fd, buf, 9);
buf[len] = '\0';
</source>
N'oubliez pas que l'opération de lecture (''read'') est bloquante ! Il faudra donc la mettre dans un thread si vous voulez faire une autre action en même temps.
Ci-dessous un ''petit'' exemple de programme ''serial.c'' qui:
* accède au port série
* démarre un thread pour la lecture de la console (message de l'utilisateur)
* démarre un thread de lecture du port série
<source lang="c">
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
int open_uart(const char * tty)
{
int fd = open(tty, O_RDWR | O_NOCTTY);
if (fd == -1){
    printf("Unable to open %s: %s\n", tty, strerror(errno));
} else {
printf("Opening %s\n", tty);
}
return fd;
}
void * writeSerial(void * arg){
printf("Enter \"exit\" to quit program\n");
int fd = *((int*) arg);
char buffer[80] = "";
// Stocke la longeur du message reçu
int len = 0;
int code = 0;
while(1){
// On lit jusqu'au caractère '\n'
len = scanf("%[^\n]", buffer);
if(len < 0){
perror("Fail reading from console !\n");
code = 1;
break;
}
if(strncmp("exit", buffer, 4) == 0){
break;
}else if(write(fd, buffer, strlen(buffer)) < 0){
perror("Fail writting to UART !\n");
code = 1;
break;
}
// Supprime le caractère '\n'
fgetc(stdin);
}
//Fermeture du port série
close(fd);
// Fermeture du programme
pthread_exit(0);
exit(code);
}
void * readSerial(void * arg){
int fd = *((int*) arg);
// Lecture par bloc de 10 octets
char buf[10] = "";
// Stocke la longeur du message reçu
int len = 0;
// Lecture en boucle, jusqu'à erreur
while(1){
// Lecture des caractères
len = read(fd, buf, 9);
if(len < 0){
// erreur
printf("Fail reading from serial: %s\n", strerror(errno));
break;
}
// Ajout du terminateur de chaîne
buf[len] = '\0';
// Affichage du message
if(len > 0){
printf("%s", buf);
}
}
//Fermeture du port série
close(fd);
// Fermeture du programme
pthread_exit(0);
exit(EXIT_FAILURE);
}


int main(int argc, char * argv[]){
// Récupération des arguments
if(argc < 2){
perror("You must specify an UART to open !\n");
return EXIT_FAILURE;
}
// Ouveture du port série
int fd = open_uart(argv[1]);
if(fd < 0){
return EXIT_FAILURE;
}
// Thread pour la lecture du port série
pthread_t lecture = 0;
// Thread pour écouter le clavier et écrire dans le port série
pthread_t ecriture = 0;
// Démarrage du thread de lecture
pthread_create(&lecture, NULL, readSerial, &fd);
// Démarrage du thread d'écriture
pthread_create(&ecriture, NULL, writeSerial, &fd);
// On attend que l'utilisateur stop le programme en envoyant "exit"
pthread_join(ecriture, NULL);
// On ferme proprement le port série
close(fd);
return EXIT_SUCCESS;
}
</source>
</source>
Une fois compilé:
<pre>
# gcc -o serial.bin serial.c -l pthread
</pre>
On peut lire et écrire sur le port série depuis le CP1202:
[[Fichier:Cp1202 uart opi zero.png|centré]]

Version du 17 octobre 2020 à 21:08

Introduction

Nous allons utiliser le protocole UART sur une platine Sunxi (ARM AllWinner) OrangePi Zero. La connexion se fera entre l'OrangePi et un convertisseur USB / UART CP2102

Montage

Nous allons connecter le CP2102 au port UART1 de l'OrangePi. Il faudra donc raccorder les deux de la sorte:

CP2102  ->  OrangePi
 GND    ->    GND
  RX    ->    TX
  TX    ->    RX

Activation du port UART1

Il faut spécifier au système d'exploitation que nous voulons utiliser les broches 7 et 6 pour le port UART et non pas comme GPIO. Cela se fait en ajoutant les lignes suivantes dans le fichier /boot/armbianEnv.txt. Il faut modifier la directive overlays pour ajouter simplement uart1 :

# Exemple d'ajout en plus des overlays USB et du protocole oneWire:
overlays=usbhost2 usbhost3 w1-gpio uart1

Il ne reste plus qu'à redémarrer le système pour appliquer les modifications.

Programmation C

Passons en revue les différentes étapes qui nous permettent d'utiliser le port UART:

  • la première étape consiste à ouvrir le port, cela se fait avec la fonction open
int fd = open(tty, O_RDWR | O_NOCTTY);
  • Une fois le port ouvert on peut écrire avec la fonction write en utilisant le descripteur de fichier retourné par open:
write(fd, message, strlen(message));
  • On peut lire avec la fonction read en utilisant également le descripteur de fichier ainsi qu'un tampon (tableau de caractères). N'oubliez pas le \0 qu'il faut ajouter si vous voulez manipuler votre tampon !
char buf[10] = "";
int len = read(fd, buf, 9); 
buf[len] = '\0';

N'oubliez pas que l'opération de lecture (read) est bloquante ! Il faudra donc la mettre dans un thread si vous voulez faire une autre action en même temps.

Ci-dessous un petit exemple de programme serial.c qui:

  • accède au port série
  • démarre un thread pour la lecture de la console (message de l'utilisateur)
  • démarre un thread de lecture du port série
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>

int open_uart(const char * tty)
{
	int fd = open(tty, O_RDWR | O_NOCTTY);
	if (fd == -1){
    	printf("Unable to open %s: %s\n", tty, strerror(errno));
	} else {
		printf("Opening %s\n", tty);
	}
	return fd;
}

void * writeSerial(void * arg){
	printf("Enter \"exit\" to quit program\n");
	int fd = *((int*) arg);
	char buffer[80] = "";
	// Stocke la longeur du message reçu
	int len = 0;
	int code = 0;
	while(1){
		// On lit jusqu'au caractère '\n'
		len = scanf("%[^\n]", buffer);
		if(len < 0){
			perror("Fail reading from console !\n");
			code = 1;
			break;
		}
		if(strncmp("exit", buffer, 4) == 0){
			break;
		}else if(write(fd, buffer, strlen(buffer)) < 0){
			perror("Fail writting to UART !\n");
			code = 1;
			break;	
		}
		// Supprime le caractère '\n'
		fgetc(stdin);
	}
	//Fermeture du port série
	close(fd);
	// Fermeture du programme
	pthread_exit(0);
	exit(code);
}

void * readSerial(void * arg){
	int fd = *((int*) arg);
	// Lecture par bloc de 10 octets
	char buf[10] = "";
	// Stocke la longeur du message reçu
	int len = 0;
	// Lecture en boucle, jusqu'à erreur
	while(1){
		// Lecture des caractères
		len = read(fd, buf, 9);
		if(len < 0){
			// erreur
			printf("Fail reading from serial: %s\n", strerror(errno));
			break;
		}
		// Ajout du terminateur de chaîne
		buf[len] = '\0';
		// Affichage du message
		if(len > 0){
			printf("%s", buf);
		}
	}
	//Fermeture du port série
	close(fd);
	// Fermeture du programme
	pthread_exit(0);
	exit(EXIT_FAILURE);
}

int main(int argc, char * argv[]){
	// Récupération des arguments
	if(argc < 2){
		perror("You must specify an UART to open !\n");
		return EXIT_FAILURE;
	}
	// Ouveture du port série
	int fd = open_uart(argv[1]);
	if(fd < 0){
		return EXIT_FAILURE;	
	}
	// Thread pour la lecture du port série
	pthread_t lecture = 0;
	// Thread pour écouter le clavier et écrire dans le port série
	pthread_t ecriture = 0;
	// Démarrage du thread de lecture
	pthread_create(&lecture, NULL, readSerial, &fd);
	// Démarrage du thread d'écriture
	pthread_create(&ecriture, NULL, writeSerial, &fd);
	// On attend que l'utilisateur stop le programme en envoyant "exit"
	pthread_join(ecriture, NULL);
	// On ferme proprement le port série
	close(fd);
	return EXIT_SUCCESS;
}

Une fois compilé:

# gcc -o serial.bin serial.c -l pthread

On peut lire et écrire sur le port série depuis le CP1202: