Rétro-ingénierie industrielle

L'histoire du processus d'emprunt dans le développement de l'électronique sur un bon exemple.



Enregistrement du journal d'ascenseur du renifleur fait maison


Une fois, j'avais besoin de copier un appareil assez simple. L'entreprise de fabrication a cessé d'exister, mais dans tout le pays, il y avait toujours une demande pour le remplacement des appareils cassés ou usagés.


L'appareil lui-même est le bouton d'appel de l'ascenseur sur la photo de gauche. Pour les expériences, ils m'ont donné deux exemplaires, dont l'un pourrait être complètement démonté.


Le plan de travail global ressemblait à ceci:


  1. Étudier le circuit imprimé;
  2. Étudier la base de l'élément de la planche elle-même;
  3. Esquissant son circuit électrique;
  4. Essayez de lire le fichier du micrologiciel à partir du microcontrôleur;
  5. Démontage du firmware;
  6. Extraire l'algorithme d'opération;
  7. Développement d'un nouveau conseil d'administration;
  8. Écriture d'un nouveau firmware.

Si le paragraphe 4 échoue, le plan ultérieur aurait été plus compliqué, mais j'ai eu de la chance.


Nous étudions l'expérimentation



Microcontrôleur principal



Un morceau du circuit électrique de l'ascenseur, sur lequel nos planches sont encerclées en rouge


La carte est assemblée sur un microcontrôleur 1997, l' AT89C2051 , qui est basé sur l'architecture Intel MCS-51 . En 2020, elle fête son 40e anniversaire sur le marché des systèmes embarqués.


Une petite explication: un microcontrôleur est un tel microcircuit qui contient un noyau informatique et un ensemble de périphériques pour contrôler des périphériques externes. Par exemple, dans une machine à laver moderne, le microcontrôleur interroge les boutons de commande, les capteurs, affiche les informations sur l'écran et contrôle les pompes, le chauffage, les vannes et l'entraînement du tambour. Pour la plupart de ces fonctions, il ne nécessite pas d'appareils intermédiaires, seulement un ensemble de composants électroniques passifs.


Nous démontons le circuit imprimé

Le fait d'esquisser le schéma de circuit d'origine de la carte à l'avenir vous aidera à découvrir l'objectif des broches du microcontrôleur, qui est nécessaire pour analyser le code du micrologiciel.


L'appareil d'origine a été développé par une entreprise chinoise, et donc son circuit est extrêmement confus et avec de nombreux composants inutiles. Par exemple, le relais a été activé via une triple cascade d'un transistor bipolaire, d'un optocoupleur et d'un contrôleur de champ (dans cet ordre).


Une connaissance travaillant avec des fabricants chinois m'a dit que les Chinois sont engagés dans des complications similaires de projets visant à augmenter les coûts de développement et de production, si une seule personne le fait. Après cela, j'ai tendance à le croire:



Le même endroit sur le panneau chinois à deux couches des deux côtés. Trois énormes résistances ne sont connectées à rien. J'ai même brillé la planche avec une puissante lampe de poche pour m'en assurer.


Le schéma est copié, les lieux mystérieux sont modélisés dans un multisim , on reprend le firmware.


Essayer de lire le firmware


J'ai eu beaucoup de chance que la protection en lecture n'ait pas été activée sur les deux cartes des contrôleurs, j'ai donc réussi à fusionner les deux options de firmware avec une pornographie similaire:



Photo du blog personnel d' un passionné américain


Démontage du firmware


La prochaine étape, nous devons convertir ce code machine en quelque chose de plus lisible:



Nous prenons l'outil bien connu IDA Pro , qui a déjà notre contrôleur avec tous les registres périphériques, et ouvrons le fichier du firmware HEX:



Traitement des données reçues par la carte en langage assembleur


Après cela, il y a un processus assez fastidieux pour étudier le jeu d'instructions de notre noyau informatique, commenter et décoder le code assembleur.


Les gestionnaires d'interruption eux-mêmes ont été trouvés aux adresses de la table des vecteurs d'interruption; les entrées dans les registres périphériques ont fourni des informations sur la configuration de l'interface de communication. Étape par étape, le code assembleur sans nom est devenu quelque chose qui peut être lu.


Extraction de l'algorithme de travail


Comme j'avais besoin de développer un nouveau périphérique sur une base d'éléments différente, il était nécessaire d'extraire un algorithme du code. Quelque temps plus tard, un tel pseudo-code est né:


void UartISR (void) { counter500ms = 0; //ClearFlag(isrFlags, ISR_FLAG_3); ProcessUart(recievedByte); } void ProcessUart(uint8_t recievedData) { static uint8_t uartPacketsToRxLeft, uartRecievedCmd, uartCurrPacketCRC; static uint8_t i, carryFlag; static uint16_t uartIsrPointer; static uint8_t uartBuffer1[8], uartBuffer2[6]; static uint8_t uartBuffer1Pos, uartBuffer2Pos; // 0 - // 1 - // 2 - // 3 - led state, 0x0F // 4 - // 5 - // 6 - // 7 - // 8 - buttons time static uint8_t dataRegisters[9]; // RAM:0050 uint8_t tmpVal, i; uint8_t dataToSend; if (GetFlag(UartISRFlags, UART_RECIEVED_FLAG)) { ClearFlag(UartISRFlags, UART_RECIEVED_FLAG); if (recieved9thBit) { switch (recievedData) { case 0xC1: uartPacketsToRxLeft = 8; uartRecievedCmd = 1; uartBuffer1Pos = 0; uartBuffer1[uartBuffer1Pos] = recievedData; //uartIsrPointer = 0x0037; //tmpVal_0037 = recievedData; uartCurrPacketCRC = recievedData; UartRxOn(); return; break; case 0xC2: uartPacketsToRxLeft = 3; uartRecievedCmd = 2; 

Le même traitement des données reçues en C


Qui se soucie du protocole de transfert:


Le poste de commande de l'ascenseur communiquait avec les cartes des boutons d'appel via une interface 24 volts en duplex intégral. En mode normal, les cartes boutons écoutaient la ligne, attendant un paquet de données 9 bits. Si l'adresse de notre carte est entrée dans ce paquet (elle a été définie par le commutateur DIP de la carte), la carte est passée en mode de réception 8 bits et tous les paquets suivants ont été ignorés par le reste des cartes dans le matériel.

Le premier après l'adresse était un paquet avec un code de commande de contrôle. Plus précisément, cette planche ne comptait que 3 équipes:
  1. Écriture dans des registres de données. Par exemple, la fréquence et la durée du bouton clignotant lors d'un appel;
  2. Allumer le rétroéclairage des boutons;
  3. Recherchez l'état des boutons (enfoncés ou non).


Le dernier octet était la somme de contrôle, qui est un simple OU exclusif de tous les octets après l'adresse.
Après la somme de contrôle, la carte est à nouveau passée en mode veille pour son adresse.

Développement de nouvelles cartes


Pour l'étape de développement d'un nouveau schéma de câblage et d'une carte de circuit imprimé, je n'ai pas de photos, mais c'était quelque chose comme ceci:


Le câblage et le câblage ont été effectués dans Altium Designer . La fabrication de la carte de circuit imprimé a été commandée à Zelenograd « Resonite ».


Écrire un nouveau firmware


Pendant que notre nouvelle carte est en production, nous allons à l'objet où ces boutons d'appel sont installés et vérifions l'exactitude du protocole de transfert démonté à l'aide du renifleur assemblé sur l'arduino:

Un circuit émetteur qui est électriquement équivalent à l'original. Le récepteur n'est qu'un optocoupleur.


 //UART1 initialize // desired baud rate:19200 // actual baud rate:19231 (0,2%) // char size: 9 bit // parity: Disabled void uart1_init(void) { UCSR1B = 0x00; //disable while setting baud rate UCSR1A = 0x00; UCSR1C = 0x06; UBRR1L = 0x33; //set baud rate lo UBRR1H = 0x00; //set baud rate hi UCSR1B = 0x94; } #pragma interrupt_handler uart1_rx_isr:iv_USART1_RXC void uart1_rx_isr(void) { unsigned char tmp; unsigned int rcv = 0; if (UCSR1B & 0x02) { rcv = 0x100; } rcv |= UDR1; tmp = (rcv >> 4) & 0x0F; if (rcv & 0x100) { tmp |= 0xC0; } else { tmp |= 0x80; } txBuf12 = (rcv & 0x0F); txBuf11 = tmp; txState1 = 0; TX_ON(); msCounter0 = 5000; } 

Parlez de notre renifleur dans ICC AVR


Ensuite, il a fallu agir avec une extrême prudence pour ne rien brûler dans l'ascenseur et l'empêcher de s'arrêter.



Nous montons dans le bouton d'appel. Fils jaunes épais - carte d'alimentation et interface de transmission. Blanc sur le connecteur à 4 broches - connexion du bouton et de son rétro-éclairage.


Nous vérifions que tout fonctionne comme il se doit, réparons les montants et écrivons un nouveau firmware pour notre appareil:


 //ICC-AVR application builder : 11.02.2015 12:25:51 // Target : M328p // Crystal: 16.000Mhz #include <macros.h> #include <iccioavr.h> #include <avrdef.h> #include "types.h" #include "gpio.h" #define TX_OFF() UCSR0B &= 0b11011111; #define TX_ON() UCSR0B |= 0b00100000; #define TX_STATE() (UCSR0B & 0b00100000) #define MAX_TIMEOUT 3000 //#define SNIFFER_MODE 1 //#define MASTER_MODE 1 // #pragma avr_fuse (fuses0, fuses1, fuses2, fuses3, fuses4, fuses5) #pragma avr_fuse (0xFF, 0xD1, 0xFC) #pragma avr_lockbits (0xFC) // AVR signature is always three bytes. Signature0 is always the Atmel // manufacturer code of 0x1E. The other two bytes are device dependent. #pragma avr_signature (0x1E, 0x95, 0x0F) // atmega32 static GPIOx errorLed, rcvLed, butUp, butDn, ledUp, ledDn, butLedUp, butLedDn, ledButUp, ledButDn; static uint8_t msFlag = 0; static uint8_t ledState = 0, buttonsState = 0; static uint16_t rcvLedLitTime = 0, butMaskCalcTime = 0, timeoutTimer = 0; typedef struct { uint16_t buffer[10]; uint8_t dataLength; } UartPacket; static UartPacket txPacket, rxPacket; #ifdef SNIFFER_MODE static uint8_t txBuffer[64], txBufferLength = 0, bufferMutex = 0; #endif static uint8_t GetPacketCRC(UartPacket* packet); static void SendLedState(void); uint8_t GetAddress(void) { return (PINC & 0x3F); } 

Code C pour la nouvelle carte basée sur le microcontrôleur AVR ATmega328P


La simplicité de l'appareil et du firmware peut être estimée par la quantité de code, il ne contient qu'environ 600 lignes en langage C.


Le processus de construction ressemblait à ceci:



Les frais sont différents, mais le principe est le même


Je ne peux pas joindre une photo de l'appareil fini, croyez simplement qu'il est toujours produit et vendu.


Conclusion lyrique


Concernant les boutons de l'ascenseur «haut» et «bas» au sol. J'ai remarqué que beaucoup de gens ne comprennent pas complètement leur objectif et secouent les deux à la fois.



D'ici


L'ascenseur a deux ensembles de boutons: dans la cabine il y a un panneau de commande et à l'étage il y a un panneau d'appel. Vous pouvez déjà deviner à partir du nom que le panneau de commande a une priorité de contrôle plus élevée.


Tous les ascenseurs avec panneaux d'appel avec boutons haut et bas fonctionnent avec l'une des options de l'algorithme d'optimisation du voyage, dont le but est de transporter le nombre maximum de passagers dans le temps minimum et une condition distincte pour le temps d'attente maximum au sol (réglementé par la norme d'État).


Un tel algorithme implique généralement la sélection des passagers aux étages s'ils voyagent dans la même direction que celle indiquée en appuyant sur le bouton d'appel «haut» ou «bas».


Imaginez une situation où un ascenseur avec des passagers descend et reçoit un appel «descendant» d'un étage inférieur. L'ascenseur s'arrêtera pour ramasser le passager (oui, il y a toujours des comptes pour le chargement de la cabine par le capteur de poids, mais on va le baisser).


L'ascenseur continue de fonctionner et reçoit un appel «ascendant» de l'étage inférieur. Il est logique que l'ascenseur ne s'arrête pas pour prendre un passager, car il ne changera pas le sens de la marche (cela est également réglementé par la norme), mais ramassera un passager pour descendre puis remonter - consommation inutile d'énergie et d'espace dans l'ascenseur.


L'ascenseur continue et reçoit deux appels «de haut en bas» de l'étage inférieur, qui ont été pressés par un passager impatient qui doit monter. Il est logique que l'ascenseur s'arrête à cet étage, mais le passager n'y entrera pas, mais il faudra du temps aux personnes dans la cabine pour ralentir et arrêter l'ascenseur, ouvrir les portes, attendre, fermer les portes et accélérer à la vitesse nominale.


Si l'ascenseur n'a qu'un seul bouton à l'étage, alors dans 99% des cas il fonctionne selon l'algorithme de «descente collective», et s'il y a des ordres dans la cabine, il ne s'arrête qu'en descendant.


Si vous avez des compétences en programmation dans JS, vous pouvez essayer d'implémenter un algorithme de contrôle similaire dans le jeu en ligne Elevator Saga . Il a tous les aspects de l'optimisation des voyages sans entrer dans le hardcore comme le fonctionnement des circuits de sécurité des ascenseurs.



Dans ma chaîne de télégramme, je poste des documents similaires. En ce moment, vous pouvez suivre le développement du prochain appareil.

Source: https://habr.com/ru/post/fr459492/


All Articles