[LINUX] Je souhaite désactiver les interruptions sur le Raspberry Pi (≒ DI / EI)

Contexte

Sur Raspberry Pi, qui est censé être utilisé sous Linux, le programme de l'utilisateur s'exécute naturellement sous le planificateur du système d'exploitation. Par conséquent, il est très difficile d'écrire un programme à durée limitée. En termes simples, je ne suis pas doué pour traiter quelque chose exactement à intervalles réguliers. Dans un tel cas, il s'agit d'une interruption de minuterie ou d'une interrogation d'horloge, mais je pense qu'il existe de nombreux cas où vous souhaitez utiliser ce dernier compte tenu de la faible surcharge et de la simplicité du contexte. À ce moment-là, diverses interruptions interfèrent. J'ai pensé que ce serait bien si je pouvais interdire de simples interruptions temporaires, et j'ai essayé diverses choses, alors j'ai écrit un article. C'est le DI / EI du Z80 qui est familier au vieil homme.

Ce que tu peux faire

J'ai écrit un programme (décrit plus tard) qui interroge «gettimeofday ()» et fonctionne dans un cycle de 100 US. Voici les résultats (cycle mesuré) pour le cas standard et lorsque les interruptions sont désactivées. rpiint.png

comment c'est? C'est évident en un coup d'œil. Si vous désactivez les interruptions, vous pouvez contrôler différents horaires. Par exemple, Télécommande infrarouge. (Remarque: bien sûr, la désactivation des interruptions a de nombreux effets secondaires. Réduisez le temps de désactivation.)

Aperçu de la façon de procéder

Selon le manuel du SoC BCM2835 / 2837 de Raspberry Pi, il semble y avoir «registre de désactivation d'interruption» et «registre d'activation d'interruption», alors frappez-les directement. C'est le familier / dev / mem dans GPIO pour mmap ().

  1. mmap () pour pouvoir accéder directement à l'adresse physique.
  2. Lisez le registre et enregistrez les informations de réglage actuelles.
  3. Ecrivez tous les 1 pour interrompre le registre de désactivation pour désactiver toutes les interruptions.
  4. Effectuez le traitement nécessaire qui est sévère dans le temps.
  5. Écrivez la valeur sauvegardée en 2. dans le registre d'activation d'interruption et ramenez-le à l'état initial.

Et c'est tout. En termes de Z80, 2-3 est "DI" et 5 est "EI".

Exemple de code

Il s'agit du code utilisé pour créer les données du graphique ci-dessus. Veuillez changer la partie de #define PERI_BASE PI? _PERI_BASE en fonction de votre Raspberry Pi.

#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/time.h>

#define BLOCK_SIZE (4 * 1024)
#define PI2_PERI_BASE 0x3f000000
#define PI1_PERI_BASE 0x20000000
#define PERI_BASE PI1_PERI_BASE // Raspberry 0/1 or 2/3

//Temps spécifié(us)Attendez en interrogeant
inline static void waitUs(struct timeval tv_zero, int until_us) {
  struct timeval tv;
  int us;

  while (1) {
    gettimeofday(&tv, NULL);
    us = (tv.tv_sec - tv_zero.tv_sec) * 1000000 + (tv.tv_usec - tv_zero.tv_usec);
    if (us >= until_us) break;
  }
}


int main() {
  int mem_fd;
  char *map;
  int i;
  int us_next;
  struct timeval tv0, tv1;
  int dt[10000];
  int irq1, irq2, irq3;   //Sauvegardons les informations d'interruption(Enfin écrivez à irqen)

  volatile unsigned int *irqen1;
  volatile unsigned int *irqen2;
  volatile unsigned int *irqen3;
  volatile unsigned int *irqdi1;
  volatile unsigned int *irqdi2;
  volatile unsigned int *irqdi3;

  if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC)) < 0) return -1;
  map = (char*) mmap(NULL,
		     BLOCK_SIZE,
		     PROT_READ | PROT_WRITE,
		     MAP_SHARED,
		     mem_fd,
		     PERI_BASE + 0xb000
		     );
  if (map == MAP_FAILED)  return -1;
  irqen1 = (volatile unsigned int *) (map + 0x210);
  irqen2 = (volatile unsigned int *) (map + 0x214);
  irqen3 = (volatile unsigned int *) (map + 0x218);
  irqdi1 = (volatile unsigned int *) (map + 0x21c);
  irqdi2 = (volatile unsigned int *) (map + 0x220);
  irqdi3 = (volatile unsigned int *) (map + 0x224);

  gettimeofday(&tv0, NULL);
  irq1 = *irqen1;
  irq2 = *irqen2;
  irq3 = *irqen3;
  //Désactivez toutes les interruptions sur les 3 lignes suivantes
  *irqdi1 = 0xffffffff;
  *irqdi2 = 0xffffffff;
  *irqdi3 = 0xffffffff;
  
  for (i = 0, us_next = 100; i < 10000; i++, us_next += 100) {
    waitUs(tv0, us_next);
    gettimeofday(&tv1, NULL);
    dt[i] = (tv1.tv_usec - tv0.tv_usec) + (tv1.tv_sec - tv0.tv_sec) * 1000000;
  }
  //Restaurez l'indicateur d'autorisation d'interruption sur les trois lignes suivantes.
  *irqen1 = irq1;
  *irqen2 = irq2;
  *irqen3 = irq3;
  //Affichage des résultats
  for (i = 1; i < 10000; i++) {
    printf("%d\n", dt[i] - dt[i - 1]);
  }
  return 0;
}


Recommended Posts

Je souhaite désactiver les interruptions sur le Raspberry Pi (≒ DI / EI)
Je veux exécuter l'interface graphique Python au démarrage de Raspberry Pi
Je veux utiliser Linux sur mac
Comment installer NumPy sur Raspeye
Je souhaite développer des applications Android sur Android
Remarque: je souhaite faire de la domotique avec Home Assistant + Raspberry Pi + capteur # 1
Je veux faire pyenv + pipenv même sous Windows
Je veux enregistrer les entrées / sorties de fichiers sous Linux
Connectez-vous à MySQL avec Python sur Raspberry Pi
J'ai une question. Impossible de créer des tampons de protocole sur le raspberry pi 3 modelB.
pigpio sur Raspberry pi
Cython sur Raspberry Pi
Je souhaite développer des applications Android sur Android (débogage)
Je veux trouver un package populaire sur PyPi
Je veux AWS Lambda avec Python sur Mac!
Je souhaite utiliser OpenJDK 11 avec Ubuntu Linux 18.04 LTS / 18.10
Sortie sur "LED 7 segments" en utilisant python avec Raspberry Pi 3!
Je veux faire Wake On LAN de manière entièrement automatique
Je souhaite être informé de l'environnement de connexion lorsque RaspberryPi se connecte au réseau
Présentation de PyMySQL à Raspberry pi3
Je veux résoudre SUDOKU
Je souhaite annoncer ma thèse de fin d'études sur IPython Notebook
J'ai essayé d'automatiser [une certaine tâche] à l'aide d'une tarte à la râpe
Introduction de pyenv sur Raspberry Pi
Utilisez NeoPixel avec la tarte aux framboises
Installez OpenCV4 sur Raspberry Pi 3
Installez TensorFlow 1.15.0 sur Raspberry Pi
J'ai envoyé les données de Raspberry Pi à GCP (gratuit)
À propos de l'erreur que j'ai rencontrée en essayant d'utiliser Adafruit_DHT à partir de Python sur Raspberry Pi
Je souhaite utiliser la traduction de raccourcis comme l'application DeepL même sous Linux
J'ai essayé d'automatiser l'arrosage du pot avec Raspberry Pi
J'ai créé un serveur Web avec Razpai pour regarder des anime
Utilisez python sur Raspberry Pi 3 pour éclairer la LED (Hello World)
Comment lire des fichiers musicaux (wav / mp3) sur Raspberry Pi python
Exécutez Polyglot sur Raspberry Pi pour effectuer une analyse morphologique en anglais
Portez FreeRTOS vers Raspberry Pi 4B
Test de la communication UART avec Raspberry Pi
MQTT sur Raspberry Pi et Mac
raspberry pi 4 centos7 installer sur docker
Installez ghoto2 sur Raspberry Pi (Remarque)
Sortie du Raspberry Pi vers la ligne
Essayez d'utiliser ArUco avec Raspberry Pi
Procédure d'installation d'OpenCV sur Raspberry Pi
Je veux gratter des images et les former
Je veux faire ○○ avec les Pandas
Allumer / éteindre le Raspberry pi avec Arduino
Détecter l'état du commutateur avec Raspberry Pi 3
Je veux copier l'annotation de yolo
Installez OpenMedia Vault 5 sur Raspberry Pi 4
Je veux déboguer avec Python
L Chika avec Raspberry Pi C #
[Raspberry Pi] Changement par défaut de Python en Python3
Construisez wxPython sur Ubuntu 20.04 sur Raspberry Pi 4
Je veux tweeter Twitter avec Python, mais j'y suis accro
Utilisez python sur Raspberry Pi 3 pour éclairer la LED avec le contrôle du commutateur!
Je souhaite afficher une image sur Jupyter Notebook à l'aide d'OpenCV (mac)
J'ai essayé de faire un signal avec Raspeye 4 (édition Python)