Xenomai RTDM.

Slides:



Advertisements
Présentations similaires
Client/Server Socket. Client/Serveur.
Advertisements

1 Réseaux Communication socket sous Windows. 2 Communication socket sous Windows Communication entre 2 applications sur 2 machines distantes Adresse IP.
1 Programmation en C++ C++ de base ● Programme C++ ● Variables, objets, types ● Fonctions ● Namespace ● Tests ● Boucles ● Pointeurs, références.
1 Programmation en C++ C++ de base ● Programme C++ ● Variables, objets, types ● Types et opérations fondamentales ● Tests ● Boucles ● Pointeurs, références.
Module 13 : Implémentation de la protection contre les sinistres.
Mode noyau Appels Systèmes Interruptions Grégory Seront Institut Paul Lambin
Qu’est-ce un serveur de messagerie?
Environnement de développement des BD
Threads et Lightweight Processes
Gestion du temps.
6GEN720 Réseaux d’ordinateurs
Pas de variable globale
Objectifs Maîtriser : Un environnement de travail
Pointeurs et langage C.
Communications via sockets
Qu'est-ce que POSIX? Une librairie en langage C
AO (Architecture des ordinateurs)
Chiffrement de bout en bout
7 – COMMUNICATION INTER PROCESSUS SEGMENTS DE MÉMOIRE PARTAGEE
Ce videoclip produit par l’Ecole Polytechnique Fédérale de Lausanne
L'approche asynchrone.
Commande show standby ccnp_cch ccnp_cch.
Fonctionnement de l'unité centrale
Principes de programmation (suite)
Séminaire EOLE Dijon Octobre 2010
Accès aux fichiers en C.
Chapitre 12 Surveillance des ressources et des performances
Synthèse Socket en C.
OSPF - Commande show ip ospf neighbor.
RIP - Configuration des Extensions.
Comment fonctionne RADIUS?
Ce videoclip produit par l’Ecole Polytechnique Fédérale de Lausanne
Commande show dialer ccnp_cch ccnp_cch.
Gestion des sécurités sur les comptes User Access Control
Module 5 : Gestion des disques.
Communications via sockets
Ce videoclip produit par l’Ecole Polytechnique Fédérale de Lausanne
Système flexible de Workflow pour la plate-forme Motu
QoS - Configuration Fragmentation
Programmation système
Partie 3 : Interface utilisateur
Août 2009.
Programmation en C++ C++ de base
SYSTÈME D’EXPLOITATION I
1 RECURSIVITE PRESENTATION Ch. PAUL ALGORITHMIQUE Présentation de la récursivité.
Certificat en Informatique et Internet D5. Travailler en réseau, communiquer et collaborer Equipe C2I - FSEGS Semestre 2 – Avril 2015 Université de Sfax.
Système d’exploitation
Les protocoles de la couche application Chapitre 7.
Places Send File Receive Messages.
Les classes et les objets
Gestion des sécurités sur les comptes User Access Control
1 PROJET D’INFORMATIQUE les composants de l'ordinateur Gammoudi Rayéne 7 B 2.
BIOS- OS Environnement logiciel PC / Traitement numérique / Contrôle.
Les exceptions Le mécanisme des exceptions est destiné à permettre aux fonctions profondes d'une bibliothèque de notifier la survenue d'une erreur aux.
BUFFER CIRCULAIRE Meryem EL BAKRI. PLAN Introduction Buffer circulaire Fonctionnement.
PLATE FORME DE GESTION ÉLECTRONIQUE DE DOCUMENTS Présenté par: Amine LARIBI.
Système d’exploitation: Principe IFT6800 – E 2008 Pierre Poulin.
Principes de programmation (suite)
Threads et Lightweight Processes
Ordonnancement des processus sous Windows NT
Listes Chaînées.
Notions d'architecture client-serveur. Présentation de l'architecture d'un système client/serveur Des machines clientes contactent un serveur qui leur.
Lecture/Écriture de fichiers (I/O)
Merise le modèle de traitement
COURS ADMINISTRATION DE BASES DE DONNÉES IMPORT/EXPORT Karim LABIDI ISET Ch
TP N°1 : GUI en NetBeans Module R & C Université de Jijel
Contenu Systèmes de test parallèles Multithreading Synchronisation
TP N°4 Développement d’ une application
Support de formation Administrateur Compétences
Les Commandes de base Linux. 1 L’aide sur les commandes Linux ◦ help : obtenir de l’aide pour une commande interne du shell. Elle permet aussi d'afficher.
Transcription de la présentation:

Xenomai RTDM

introduction Real Time Driver Model une des « peaux » de Xenomai issue des développements autour des approches « co- noyau » pour développer un Linux Temps Réel RTLinux RTAI Fusion va au delà des approches « traditionnelles » (POSIX I/O) qui est limitée quand il s'agit de gérer des communications basées sur des échange de messages (e.g. interfaces réseau)

introduction Application Application Optionnel Wrapper Library RTDM Hardware Abstraction Layer Hardware Driver Hardware Driver

modèles de périphériques tous les types de périphériques ne sont pas abordés par RTDM (seulement ceux susceptibles d'entrer dans une application de type temps réel) : périphériques « à protocole » utilisent le modèle des sockets POSIX échange de messages primitives socket(), close(), sendmsg(), recvmsg(), ... identifiés par le protocole le type de socket périphériques « nommés » identifiés par un « nom » (chaîne de caractères) support d'échanges analogue à celui des périphériques caractères open(), close() entrées/sorties orientées stream read(), write(), ioctl() ou seulement ioctl()

pilotes RTDM RTDM permet de gérer des périphériques à l'aide de pilotes qui ne sont pas des « pilotes » au sens classique de Linux, mais qui rendent des services équivalents n'apparaissent pas dans /proc/devices arborescence dédiée /proc/xenomai/rtdm pas de fichier spécial associé dans /dev les pilotes RTDM peuvent avoir un comportement différent selon qu'ils sont appelés d'un contexte « temps réel » ou non RTDM n'est pas fondamentalement lié à Xenomai Xenomai est le support actuel de développement (et le seul environnement qui supporte RTDM) organisation du pilote analogue à celle des pilotes Linux classiques simplifiée (2 classes de périphériques seulement) nous n'aborderons que les périphériques nommés

l'API de RTDM des services élémentaires sont proposés pour augmenter la portabilité des pilotes indépendants de l'OS sous-jacent l'API se divise en 2 grandes parties (groupes de modules) l'API utilisateur, pour les applications faisant appel aux services du pilote les API génériques pour le développement portable des pilotes, avec les services suivants : enregistrement des pilotes horloges et timers gestion des tâches synchronisation gestion des interruptions gestion des signaux non temps réels utilitaires le détail des fonctions de l'API se trouve dans la documentation (http://www.xenomai.org)

enregistrement des pilotes structures utilisées par RTDM pour gérer les pilotes rtdm_device contient les champs spécifiant les propriétés du périphérique susceptible d'être modifié par RTDM pendant l'exécution (ne doit pas être dans une zone mémoire protégée en écriture) champs : device flags : type du périphérique (nommé/protocole) device_name : le nom du périphérique nommé protocol_family/socket_type context_size : taille de la structure associée au périphérique open_rt : handler pour la création ou l'ouverture de périphériques nommés socket_rt/socket_nrt : idem pour les périphériques protocole (dépendant du contexte) ops : handlers pour les opérations (les suffixes _rt et _nrt spécifient le contexte) device_class/device_subclass : catégorie du périphérique plus d'autres éléments de description...

enregistrement des pilotes rtdm_operations donne les handlers qui seront appelés en cas de read, write, ioctl, ou close le contexte (rt ou nrt) est spécifié (sauf pour close où seul nrt est valide) inclus dans rtdm_device (ops) rtdm_dev_context associée à chaque instance du périphérique ouverte gérée par RTDM (création, destruction) passée aux handlers dans les arguments des données peuvent être arbitrairement attachées à cette structure. Leur taille doit être spécifiée dans le champ context_size de la structure de type rtdm_device toutes ces structures sont définies dans <rtdm/rtdm_driver.h>

enregistrement des pilotes int rtdm_dev_register(struct rtdm_device *dev); int rtdm_dev_unregister( struct rtdm_device *dev, unsigned int poll_delay); poll_delay indique le delai (en millisecondes) avec lequel RTDM vérifie si des instances du pilote sont encore ouvertes

API utilisateur l'API utilisateur peut être appelée par des tâches qui s'exécutent dans l'espace noyau (kernel threads) en désuétude des tâches qui s'exécutent dans l'espace utilisateur (threads Xenomai) contrôlés par l'ordonnanceur Xenomai (mode primaire) contrôlés par l'ordonnanceur Linux (mode secondaire) permet d'accéder aux fonctionnalités des pilotes RTDM

périphériques nommés int rt_dev_open(const char *path, int oflag, ...); ouvre un périphérique int rt_dev_close(int fd); ferme le périphérique ssize_t rt_dev_read(int fd, void *buf, size_t nbytes); lit des données sur le périphérique ssize_t rt_dev_write(int fd, void *buf, size_t nbytes); écrit des données sur le périphérique int rt_dev_ioctl(int fd, int request, ...); effectue une opération de contrôle sur le périphérique

périphériques à protocole int rt_dev_socket (int protocol_family, int socket_type, int protocol) crée une socket. ssize_t rt_dev_recvmsg (int fd, struct msghdr *msg, int flags) reçoit un message d'une socket ssize_t rt_dev_recvfrom (int fd, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) reçoit un message d'une socket ssize_t rt_dev_recv (int fd, void *buf, size_t len, int flags) reçoit un message d'une socket. ssize_t rt_dev_sendmsg (int fd, const struct msghdr *msg, int flags) envoie un message à une socket

périphériques à protocole ssize_t rt_dev_sendto (int fd, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen) envoie un message à une socket ssize_t rt_dev_send (int fd, const void *buf, size_t len, int flags) envoie un message à une socket int rt_dev_bind (int fd, const struct sockaddr *my_addr, socklen_t addrlen) lie à une adresse locale int rt_dev_connect (int fd, const struct sockaddr *serv_addr, socklen_t addrlen) connecte à une adresse distante int rt_dev_listen (int fd, int backlog) écoute des demandes de transmission

périphériques à protocole int rt_dev_accept (int fd, struct sockaddr *addr, socklen_t *addrlen) accepte une demande de connection int rt_dev_shutdown (int fd, int how) déconnecte int rt_dev_getsockopt (int fd, int level, int optname, void *optval, socklen_t *optlen) retourne les option de la socket int rt_dev_setsockopt (int fd, int level, int optname, const void *optval, socklen_t optlen) établit les options de la socket. int rt_dev_getsockname (int fd, struct sockaddr *name, socklen_t *namelen) retourne l'adresse de la socket locale int rt_dev_getpeername (int fd, struct sockaddr *name, socklen_t *namelen) retourne l'adresse de la destination

horloges uniquement des fonctions pour lire l'heure courante : nanosecs_abs_t rtdm_clock_read(void); lit l'heure du système nanosecs_abs_t rtdm_clock_read_monotonic(void); lit l'heure monotonique

gestion des tâches gère des tâches entre les niveaux de priorité RTDM_LOWEST_PRIORITY et RTDM_HIGHEST_PRIORITY int rtdm_task_init (rtdm_task_t *task, const char *name, rtdm_task_proc_t task_proc, void *arg, int priority, nanosecs_rel_t period) initialise et démarre une tâche temps réel void rtdm_task_destroy (rtdm_task_t *task) détruit une tâche temps réel. void rtdm_task_set_priority (rtdm_task_t *task, int priority) ajuste la priorité int rtdm_task_set_period (rtdm_task_t *task, nanosecs_rel_t period) ajuste la période int rtdm_task_wait_period (void) attend la période suivante

gestion des tâches int rtdm_task_unblock (rtdm_task_t *task) active une tâche temps réel bloquée rtdm_task_t * rtdm_task_current (void) retourne l'identificateur de la tâche temps réel courante int rtdm_task_sleep (nanosecs_rel_t delay) se met en sommeil pendant le temps spécifié int rtdm_task_sleep_abs ( nanosecs_abs_t wakeup_time, enum rtdm_timer_mode mode) se met en sommeil jusqu'à une date absolue void rtdm_task_join_nrt (rtdm_task_t *task, unsigned int poll_delay) attend la fin d'une tâche temps réel void rtdm_task_busy_sleep (nanosecs_rel_t delay) attente active pendant un laps de temps spécifié

timers rtdm_timer_init(rtdm_timer_t *timer, rtdm_timer_handler_t handler, constant char *name); initialisation le prototype du handler qui sera appelé à l'expiration est void(* rtdm_timer_handler_t) rtdm_timer_t *timer) rtdm_timer_destroy(rtdm_timer_t *timer); destruction rtdm_timer_start(rtdm_timer_t *timer, nanosecs_abs_t expiry, nanosecs_rel_t interval, enum rtdm_timer_mode mode); démarrage rtdm_timer_stop(rtdm_timer_t *timer) arrêt

timers rtdm_timer_start_in_handler(rtdm_timer_t *timer, nanosecs_abs_t expiry, nanosecs_rel_t interval, enum rtdm_timer_mode mode); démarrage d'un timer dans un handler de timer rtdm_timer_stop_in_handler(rtdm_timer_t *timer); arrêt d'un timer dans un handler de timer modes pour le timer : RTDM_TIMERMODE_RELATIVE timer monotonique avec un timeout relatif RTDM_TIMERMODE_ABSOLUTE timer monotonique avec un timeout absolu RTDM_TIMERMODE_REALTIME timer ajustable avec un timeout absolu

synchronisation les mécanismes de synchronisation sont nombreux : sémaphores mutexes événements spinlock avec désactivation de la préemption séquences de gestion des timeouts

synchronisation : sémaphores void rtdm_sem_init (rtdm_sem_t *sem, unsigned long value) initialise un sémaphore void rtdm_sem_destroy (rtdm_sem_t *sem) détruit un sémaphore. int rtdm_sem_down (rtdm_sem_t *sem) décrémente un sémaphore int rtdm_sem_timeddown (rtdm_sem_t *sem, nanosecs_rel_t timeout, rtdm_toseq_t *timeout_seq) décrémente un sémaphore avec timeout. void rtdm_sem_up (rtdm_sem_t *sem) incrémente un sémaphore

synchronisation : mutexes void rtdm_mutex_init (rtdm_mutex_t *mutex) initialise un mutex. void rtdm_mutex_destroy (rtdm_mutex_t *mutex) détruit un mutex. void rtdm_mutex_unlock (rtdm_mutex_t *mutex) libère un mutex. int rtdm_mutex_lock (rtdm_mutex_t *mutex) demande un mutex. int rtdm_mutex_timedlock (rtdm_mutex_t *mutex, nanosecs_rel_t timeout, rtdm_toseq_t *timeout_seq) demande un mutex avec timeout.

synchronisation : événements void rtdm_event_init (rtdm_event_t *event, unsigned long pending) initialise un événement. void rtdm_event_destroy (rtdm_event_t *event) détruit un événement void rtdm_event_pulse (rtdm_event_t *event) signale l'occurence d'un événement à toutes les tâches en attente void rtdm_event_signal (rtdm_event_t *event) signale l'occurence d'un événement int rtdm_event_wait (rtdm_event_t *event) attend l'occurence d'un événement

synchronisation : événements int rtdm_event_timedwait (rtdm_event_t *event, nanosecs_rel_t timeout, rtdm_toseq_t *timeout_seq) attend l'occurence d'un événement avec timeout void rtdm_event_clear (rtdm_event_t *event) efface l'état d'un événement

synchronisation : spinlocks les primitives pour la gestion des spinlocks sont reprises directement de la couche matérielle abstraite hal : #define rtdm_lock_xxx rthal_spin_xxx RTDM_LOCK_UNLOCKED initialisation statique d'un spinlock rtdm_lock_init(lock) initialisation dynamique d'un spinlock rtdm_lock_get(lock) acquisition d'un spinlock dans un contexte non préemptible rtdm_lock_put(lock) libération d'un spinlock sans restauration de la préemption rtdm_lock_get_irqsave(lock, context) acquisition d'un spinlock avec désactivation de la préemption rtdm_lock_put_irqrestore(lock, context) libération d'un spinlock avec restauration de la préemption

synchronisation : spinlocks rtdm_lock_irqsave(context) désactivation locale de la préemption rtdm_lock_irqrestore(context) restauration de l'état de préemption

synchronisation : gestion des timeouts void rtdm_toseq_init (rtdm_toseq_t *timeout_seq, nanosecs_rel_t timeout) initialisation d'une séquence de timeout utilisé pour toutes les fonctions qui font appel à un timeout (attente d'un sémaphore, d'un mutex, d'un événement) évite d'avoir à réinitialiser le mécanisme de timeout quand on utilise l'attente dans une boucle ce mécanisme de réinitialisation peut être plus long que le délai du timeout !

synchronisation : gestion des timeouts exemple int device_service_routine(...) { rtdm_toseq_t timeout_seq; ... rtdm_toseq_init(&timeout_seq, timeout); ... while (received < requested) { ret = rtdm_event_timedwait(&data_available, timeout, &timeout_seq); if (ret < 0) break; // including -ETIMEDOUT // receive some data ... } ... }

gestion des interruptions int rtdm_irq_request (rtdm_irq_t *irq_handle, unsigned int irq_no, rtdm_irq_handler_t handler, unsigned long flags, const char *device_name, void *arg) enregistre un handler d'interruption pour la ligne d'interruption irq_no int rtdm_irq_free (rtdm_irq_t *irq_handle) libère un handler int rtdm_irq_enable (rtdm_irq_t *irq_handle) autorise la ligne d'interruption associée à irq_handle int rtdm_irq_disable (rtdm_irq_t *irq_handle) désactive la ligne d'interruption associée à irq_handle

gestion des signaux non temps réels ces services donnent un moyen pour exécuter un handler donné dans un contexte non temps réel. Le déclenchement du mécanisme peut être effectué dans un environnement temps réel. L'exécution du handler sera retardée jusqu'à la fin des threads temps réels (quand Linux reprend la CPU) int rtdm_nrtsig_init (rtdm_nrtsig_t *nrt_sig, rtdm_nrtsig_handler_t handler, void *arg) enregistre un handler void rtdm_nrtsig_destroy (rtdm_nrtsig_t *nrt_sig) libère le handler void rtdm_nrtsig_pend (rtdm_nrtsig_t *nrt_sig) envoie un signal prototype du handler : void(* rtdm_nrtsig_handler_t)( rtdm_nrtsig_t nrt_sig, void *arg)

utilitaires int rtdm_mmap_to_user (rtdm_user_info_t *user_info, void *src_addr, size_t len, int prot, void **pptr, struct vm_operations_struct *vm_ops, void *vm_private_data) Mappe une zone mémoire noyau dans l'espace utilisateur int rtdm_iomap_to_user (rtdm_user_info_t *user_info, phys_addr_t src_addr, size_t len, int prot, void **pptr, struct vm_operations_struct *vm_ops, void *vm_private_data) Mappe une zone mémoire d'entrée/sortie dans l'espace utilisateur int rtdm_munmap (rtdm_user_info_t *user_info, void *ptr, size_t len) Unmappe une zone mémoire utilisateur void rtdm_printk (const char *format,...) impression « sûre » sur la console à partir de l'espace noyau

utilitaires void * rtdm_malloc (size_t size) alloue une zone mémoire dans un contexte temps réel void rtdm_free (void *ptr) libère la zone mémoire int rtdm_read_user_ok (rtdm_user_info_t *user_info, const void __user *ptr, size_t size) vérifie si un accès en lecture de la zone mémoire est sûr int rtdm_rw_user_ok (rtdm_user_info_t *user_info, const void __user *ptr, size_t size) vérifie si un accès en lecture/écriture de la zone mémoire est sûr int rtdm_copy_from_user(rtdm_user_info_t *user_info, void *dst, const void __user *src, size_t size) copie une zone mémoire utilisateur dans l'espace noyau

utilitaires int rtdm_safe_copy_from_user (rtdm_user_info_t *user_info, void *dst, const void __user *src, size_t size) vérifie si l'accès mémoire est OK en lecture et effectue la copie vers l'espace noyau int rtdm_copy_to_user (rtdm_user_info_t *user_info, void __user *dst, const void *src, size_t size) copie le buffer vers l'espace utilisateur int rtdm_safe_copy_to_user (rtdm_user_info_t *user_info, void __user *dst, const void *src, size_t size) vérifie si l'accès mémoire est OK en lecture/écriture et effectue la copie vers l'espace noyau

utilitaires int rtdm_strncpy_from_user (rtdm_user_info_t *user_info, char *dst, const char __user *src, size_t count) copie une chaîne de caractères de l'espace utilisateur vers l'espace noyau int rtdm_in_rt_context (void) vérifie que la tâche appelante est exécutée dans un contexte temps réel int rtdm_rt_capable (rtdm_user_info_t *user_info) vérifie que la tâche appelante est capable d'être exécutée dans un contexte temps réel

exemples tut01-skeleton-drv.c tut01-skeleton-app.c