Développons quelque chose qui se rapproche du TDD

introduction

J'ai étudié pour faire du TDD dans le développement embarqué. Jusqu'à présent, j'ai principalement étudié les applications, donc je vais essayer de créer quelque chose qui ressemble un peu à embarqué (en supposant un Linux embarqué). Puisqu'il s'agit d'un départ fermé, la politique peut changer en cours de route. Vous ne le saurez pas tant que vous ne l'avez pas fait, alors regardez avec des yeux chaleureux.

N'hésitez pas à nous faire part de vos avis et demandes! C'est très encourageant.

Ce que vous essayez de faire

En parlant de intégré, ce serait L Chika! Cependant, je veux rendre plus facile à essayer, donc je vais faire scintiller la LED sur le clavier (comme le verrouillage des majuscules). Il n'utilise pas de bibliothèque haute performance, mais gère en manipulant les fichiers de périphériques.

Si c'est trop facile, c'est trop facile et ce n'est pas pratique, alors je vais penser à réaliser la fonction suivante.

Comme il est intégré, pensez toujours à la portabilité vers un autre matériel.

Environnement de développement

OS Virtual box ubuntu 16.04
compilateur gcc (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609
Outil de création autotools, pkg-config
Bibliothèque libevdev-1.0
Cadre de test googletest/googlemock@62ba5d9
Code produit C or C++(Je suis en train de penser)

Recherche préliminaire

La recherche préliminaire est importante pour tout ce que vous faites. Pour le moment, je vais enquêter sur mon environnement.

Obtenir l'événement clavier

Pour obtenir les événements d'entrée au clavier sous Linux, surveillez le fichier / dev / input / event 〇〇. Les nombres sont saisis dans la partie de 〇〇, mais le numéro du clavier change dans l'ordre reconnu dans l'environnement et au démarrage (il est possible de le réparer avec udev, mais cette fois je le laisserai pour le moment).

Regardez dans / proc / bus / input / devices pour trouver le clavier. Actuellement, event2 (input2) prend en charge les claviers.

cat /proc/bus/input/devices
==Omis en chemin==
I: Bus=0011 Vendor=0001 Product=0001 Version=ab41
N: Name="AT Translated Set 2 keyboard"
P: Phys=isa0060/serio0/input0
S: Sysfs=/devices/platform/i8042/serio0/input/input2
U: Uniq=
H: Handlers=sysrq kbd event2 leds
B: PROP=0
B: EV=120013
B: KEY=402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe
B: MSC=10
B: LED=7
==Omis ci-dessous==

Pour les périphériques d'événement tels que / dev / input, Linux fournit une interface evdev (Linux Input drivers v1.0) interface Faire. La bibliothèque wrapper pour cet evdev est libevdev. Cette fois, nous utiliserons ce libevdev.

LED du clavier

Ensuite, vérifiez la LED sur le clavier. Linux fournit une classe de LED, et lorsque Linux reconnaît la LED, elle sera exportée sous / sys / class / leds dans sysfs. Les voyants Capslock, Numlock et Scrolllock sont reconnus. (Mon clavier n'a pas de LED sur les touches numlock et scrolllock ... recherche requise)

ls /sys/class/leds/
input2::capslock  input2::numlock  input2::scrolllock

Tester la compréhension de la bibliothèque

Puisque nous sommes partis de l'état privilégié d'avoir à la fois le matériel (clavier) et la bibliothèque (libevdev), nous écrirons des tests pour comprendre la bibliothèque cible. En écrivant ce test, vous testerez votre compréhension de la bibliothèque. Il semble très bien que ce que vous comprenez reste un test.

Si cela peut être fait sur la machine hôte, vous avez de la chance.

  1. Il existe de nombreuses situations où la carte cible ne possède que le matériel / la bibliothèque cible.
  2. C'est une histoire courante que même la cible ne bouge pas ou qu'il n'y a rien.

Si c'est 1, vous pouvez continuer tout en construisant docilement. Dans le cas de 2, si vous connaissez l'API, faisons une simulation. Lorsque la vraie chose sort, vous pouvez tester si l'utilisation écrite dans le test est correcte. Si vous ne comprenez pas l'API, vous pouvez imaginer faire une simulation. Créer une maquette sans connaître les détails de l'implémentation a également ses avantages et l'API peut être raisonnablement abstraite.

Tests écrits pour comprendre libevdev

L'introduction est devenue longue, mais jetons un œil au test que j'ai écrit cette fois. Je vais omettre une partie du code. Si vous voulez avoir une vue d'ensemble, cliquez ici [https://github.com/tomoyuki-nakabayashi/TDDforEmbeddedSystem).

Tout d'abord, récupérez les données de contrôle d'evdev à partir du descripteur de fichier. En cas de succès, 0 ou plus sera renvoyé. Initialement, ce test a échoué. Maintenant que nous savons que nous avons besoin des privilèges root, nous allons faire connaître le nom du test (ajouter AsRoot). Vous ne serez plus accro à la même chose à une date ultérieure. Si vous passez soudainement le relais à quelqu'un, vous constaterez que vous ne pouvez pas l'exécuter sans les privilèges root.

TEST_F(EvdevSampleTest, InputEventFileCanOpenAsRoot) {
  struct libevdev *dev = nullptr;
  int fd = open("/dev/input/event2", O_RDONLY|O_NONBLOCK);
  int rc = libevdev_new_from_fd(fd, &dev);

  EXPECT_GE(rc, 0);
}

Puisque les données de contrôle d'evdev ont été acquises, confirmez que EAGAIN est renvoyé lorsqu'il n'y a pas d'entrée. Cela passa d'un seul coup.

TEST_F(EvdevSampleTest, ReturnsEAGAIN) {
  input_event ev {};
  int actual = libevdev_next_event(evdev_, LIBEVDEV_READ_FLAG_NORMAL, &ev);
  EXPECT_EQ(-EAGAIN, actual);
}

Appuyez ensuite sur Entrée et il renverra LIBEVDEV_READ_STATUS_SUCCESS pour tester que vous pouvez obtenir le input_event que vous attendiez. Après avoir exécuté le test, le test s'arrêtera pendant l'exécution de ce test, donc si vous appuyez sur la touche Entrée, le test passera (ce n'est plus un test unitaire, mais je m'en fiche). Au moment où nous atteignons le EXPECT_EQ final, nous avons confirmé que les événements que nous avons acquis sont comme prévu, mais nous ne nous soucions pas du moment.

TEST_F(EvdevSampleTest, CaptureEnterKeyPress) {
  auto expect = create_key_event(KEY_ENTER, KEY_PRESSED);
  input_event actual {};
  while (true) {
    int rc = libevdev_next_event(evdev_, LIBEVDEV_READ_FLAG_NORMAL, &actual);
    if ((rc == LIBEVDEV_READ_STATUS_SUCCESS) && actual == expect) break;
  }

  EXPECT_EQ(expect, actual);
}

Penser en faisant un test

Étant donné qu'il peut être utilisé avec d'autres périphériques d'entrée, il serait bien d'avoir une interface de rappel à usage général. libevdev ne fournit pas de mécanisme de rappel, donc je me demande si je peux créer un mécanisme de rappel à partir de zéro.

Plans futurs

Suivant: Essayez de développer quelque chose de proche de celui intégré avec TDD ~ Résolution de problèmes ~

Recommended Posts

Développons quelque chose qui se rapproche du TDD
Développons quelque chose de proche de intégré avec TDD ~ Revue intermédiaire ~
Essayez de développer quelque chose de proche de l'intégration avec TDD ~ Problème ~
Développons quelque chose de proche de celui intégré avec TDD ~ Design pattern ~
Développons quelque chose de proche de celui intégré avec TDD ~ édition ouverte de fichier ~
Développons quelque chose de proche de celui intégré avec TDD ~ Version de détection d'entrée de clé ~
Développons quelque chose de proche de l'implémentation avec TDD ~ traitement d'initialisation / de terminaison de libevdev ~
Étapes pour développer Django avec VSCode
[Introduction à WordCloud] Jouez avec le scraping ♬
[Introduction à Python] Utilisons foreach avec Python
Développer des applications Windows avec Python 3 + Tkinter (Préparation)
Développons un algorithme d'investissement avec Python 1
Convertir mp4 en mp3 avec ffmpeg (version miniature intégrée)
Comment développer une application de panier avec Django