औद्योगिक रिवर्स इंजीनियरिंग

एक अच्छे उदाहरण पर इलेक्ट्रॉनिक्स के विकास में उधार प्रक्रिया की कहानी।



होममेड स्निफर के लिफ्ट लॉग को रिकॉर्ड करना


एक बार मुझे एक काफी सरल डिवाइस को कॉपी करने की आवश्यकता थी। विनिर्माण कंपनी का अस्तित्व समाप्त हो गया, लेकिन पूरे देश में अभी भी टूटे हुए या उपयोग किए गए उपकरणों के प्रतिस्थापन की मांग थी।


डिवाइस स्वयं बाईं ओर के फोटो में लिफ्ट कॉल बटन है। प्रयोगों के लिए, उन्होंने मुझे दो प्रतियां दीं, जिनमें से एक को पूरी तरह से अस्वीकृत किया जा सकता था।


समग्र कार्य योजना कुछ इस तरह दिखी:


  1. सर्किट बोर्ड का अध्ययन;
  2. स्वयं बोर्ड के तत्व आधार का अध्ययन करना;
  3. उसके बिजली के सर्किट स्केचिंग;
  4. माइक्रोकंट्रोलर से फर्मवेयर फ़ाइल को पढ़ने का प्रयास करें;
  5. Disassembling फर्मवेयर;
  6. ऑपरेशन एल्गोरिथ्म निकालना;
  7. एक नए बोर्ड का विकास;
  8. एक नया फर्मवेयर लिखना।

यदि पैराग्राफ 4 विफल रहता है, तो आगे की योजना अधिक जटिल होती, लेकिन मैं भाग्यशाली था।


हम प्रायोगिक अध्ययन करते हैं



मुख्य माइक्रोकंट्रोलर



लिफ्ट के विद्युत सर्किट का एक टुकड़ा, जिस पर हमारे बोर्ड लाल रंग में परिक्रमा करते हैं


बोर्ड को 1997 के माइक्रोकंट्रोलर, AT89C2051 पर इकट्ठा किया गया है, जो इंटेल MCS-51 आर्किटेक्चर पर आधारित है। 2020 में, वह अपनी 40 वीं वर्षगांठ को एम्बेडेड सिस्टम बाजार में मनाती है।


एक छोटा स्पष्टीकरण: एक माइक्रोकंट्रोलर एक ऐसा माइक्रोकिरिट है जिसमें एक कंप्यूटिंग कोर और बाह्य उपकरणों को नियंत्रित करने के लिए बाह्य उपकरणों का एक सेट होता है। उदाहरण के लिए, एक आधुनिक वॉशिंग मशीन में, माइक्रोकंट्रोलर नियंत्रण बटन, सेंसर, स्क्रीन पर सूचना प्रदर्शित करता है और पंप, हीटर, वाल्व और ड्रम ड्राइव को नियंत्रित करता है। इन कार्यों में से अधिकांश के लिए, इसे मध्यवर्ती उपकरणों की आवश्यकता नहीं होती है, केवल निष्क्रिय इलेक्ट्रॉनिक घटकों का एक सेट।


हम सर्किट बोर्ड को अलग करते हैं

भविष्य में बोर्ड के मूल सर्किट आरेख को स्केच करने से माइक्रोकंट्रोलर के पिनों के उद्देश्य का पता लगाने में मदद मिलेगी, जो फर्मवेयर कोड को पार्स करने के लिए आवश्यक है।


मूल उपकरण एक चीनी कंपनी द्वारा विकसित किया गया था, और इसलिए इसका सर्किट बेहद भ्रमित है और कई अनावश्यक घटकों के साथ है। उदाहरण के लिए, रिले को एक द्विध्रुवी ट्रांजिस्टर, ऑप्टोकॉपलर और क्षेत्र नियंत्रक (उस क्रम में) के ट्रिपल कैस्केड के माध्यम से चालू किया गया था।


चीनी निर्माताओं के साथ काम करने वाले एक परिचित ने मुझे बताया कि चीनी विकास और उत्पादन की लागत बढ़ाने के लिए योजनाओं की समान जटिलताओं में लगे हुए हैं, अगर केवल एक ही लोग ऐसा करते हैं। इसके बाद, मैं उसे विश्वास करने के लिए इच्छुक हूं:



दोनों तरफ चीनी दो-परत बोर्ड पर एक ही जगह। तीन विशाल प्रतिरोधक किसी भी चीज से नहीं जुड़े हैं। मैंने यह भी सुनिश्चित करने के लिए बोर्ड को एक शक्तिशाली टॉर्च के साथ चमकाया।


योजना की नकल की जाती है, रहस्यमय स्थानों को एक मल्टीसम में तैयार किया जाता है, हम फर्मवेयर लेते हैं।


फर्मवेयर को पढ़ने की कोशिश कर रहा है


मैं बहुत भाग्यशाली था कि नियंत्रक में दोनों बोर्डों पर रीड प्रोटेक्शन को सक्षम नहीं किया गया था, इसलिए मैंने दो फ़र्मवेयर विकल्पों को अच्छी तरह से अश्लील वीडियो के साथ मर्ज कर दिया:



एक अमेरिकी उत्साही के निजी ब्लॉग से फोटो


जुदा करने वाला फर्मवेयर


अगला चरण हमें इस मशीन कोड को कुछ और पठनीय में बदलने की आवश्यकता है:



हम अच्छी तरह से ज्ञात आईडीए प्रो टूल लेते हैं, जिसमें पहले से ही सभी परिधीय रजिस्टरों के साथ हमारा नियंत्रक है, और एचएक्स फर्मवेयर फ़ाइल खोलें:



असेंबली भाषा में बोर्ड द्वारा प्राप्त प्रसंस्करण डेटा


उसके बाद, हमारे कंप्यूटिंग कर्नेल के निर्देश सेट का अध्ययन करने, कोडांतरक कोड को कमेंट करने और डिकोड करने के बजाय एक थकाऊ प्रक्रिया है।


इंटरप्ट हैंडलर स्वयं इंटरप्ट वेक्टर टेबल के पते पर पाए गए थे, परिधीय रजिस्टरों में प्रविष्टियां संचार इंटरफेस के विन्यास के बारे में जानकारी देती थीं। चरण दर चरण, अनाम कोडर कोड कुछ ऐसी चीज़ में बदल गया है जिसे पढ़ा जा सकता है।


काम के एल्गोरिथ्म का निष्कर्षण


चूंकि मुझे एक अलग तत्व आधार पर एक नया उपकरण विकसित करने की आवश्यकता थी, इसलिए कोड से एक एल्गोरिथ्म निकालना आवश्यक था। कुछ समय बाद, इस तरह के एक छद्म कोड का जन्म हुआ:


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; 

सी में प्राप्त डेटा का एक ही प्रसंस्करण


स्थानांतरण प्रोटोकॉल के बारे में कौन परवाह करता है:


एलिवेटर नियंत्रण स्टेशन ने पूर्ण द्वैध 24-वोल्ट इंटरफ़ेस के माध्यम से कॉल बटन बोर्डों के साथ संचार किया। सामान्य मोड में, बटन कार्ड लाइन को सुनता है, 9-बिट डेटा पैकेट की प्रतीक्षा कर रहा है। यदि हमारे बोर्ड का पता इस पैकेट में आता है (यह बोर्ड पर डीआईपी स्विच द्वारा निर्धारित किया गया था), तो बोर्ड 8-बिट रिसेप्शन मोड में बदल गया, और बाद के सभी पैकेटों को हार्डवेयर के बाकी बोर्डों द्वारा नजरअंदाज कर दिया गया।

पते के बाद पहला एक पैकेट था जिसमें एक कंट्रोल कमांड कोड था। विशेष रूप से, इस बोर्ड ने केवल 3 टीमों को लिया:
  1. डेटा रजिस्टरों को लिखना। उदाहरण के लिए, कॉल पर चमकती बटन की आवृत्ति और अवधि;
  2. बटन बैकलाइट चालू करना;
  3. बटनों की स्थिति को दबाएं (दबाया या नहीं)।


अंतिम बाइट चेकसम था, जो पते के बाद सभी बाइट्स का एक साधारण XOR है।
चेकसम के बाद, बोर्ड फिर से अपने पते के लिए स्टैंडबाय मोड में चला गया।

नया बोर्ड विकास


एक नया वायरिंग आरेख और एक मुद्रित सर्किट बोर्ड विकसित करने के चरण के लिए, मेरे पास कोई चित्र नहीं है, लेकिन यह कुछ इस तरह था:


वायरिंग और वायरिंग अल्टियम डिजाइनर में की गई थी । ज़ेलेनोग्राड " रेसोनाइट " में मुद्रित सर्किट बोर्ड के निर्माण का आदेश दिया गया था।


एक नया फर्मवेयर लिखना


जब हमारा नया बोर्ड उत्पादन में है, तो हम उस ऑब्जेक्ट पर जाते हैं जहां इस तरह के कॉल बटन स्थापित होते हैं, और arduino पर इकट्ठे हुए स्निफर का उपयोग करके डिसएम्ब्लेम्ड ट्रांसफर प्रोटोकॉल की शुद्धता की जांच करते हैं:

ट्रांसमीटर सर्किटरी का एक टुकड़ा जो विद्युत मूल के बराबर है। रिसीवर सिर्फ एक ऑप्टोकॉपलर है।


 //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; } 

ICC AVR में हमारे स्निफर के बारे में बात करें


इसके बाद, यह बेहद सावधानी से काम करने के लिए आवश्यक था ताकि लिफ्ट में कुछ भी न जलाएं और इसे रोकने से रोकें।



हम कॉल बटन में चढ़ते हैं। मोटे पीले तारों - बोर्ड पावर और ट्रांसमिशन इंटरफ़ेस। 4-पिन कनेक्टर पर सफेद - बटन और इसकी बैकलाइट को कनेक्ट करना।


हम जांचते हैं कि सब कुछ उसी तरह काम करता है, जैसे जाम को ठीक करना चाहिए और हमारे डिवाइस के लिए एक नया फर्मवेयर लिखना चाहिए:


 //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); } 

AVR ATmega328P माइक्रोकंट्रोलर पर आधारित नए बोर्ड के लिए सी कोड


डिवाइस और फर्मवेयर की सादगी का अनुमान कोड की मात्रा से लगाया जा सकता है, इसमें C भाषा में केवल 600 लाइनें हैं।


निर्माण की प्रक्रिया इस तरह दिखती है:



शुल्क अलग है, लेकिन सिद्धांत समान है


मैं तैयार डिवाइस की एक तस्वीर संलग्न नहीं कर सकता, बस विश्वास है कि यह अभी भी उत्पादन और बेचा जा रहा है।


गेय निष्कर्ष


फर्श पर लिफ्ट बटन "अप" और "डाउन" के संबंध में। मैंने देखा कि बहुत से लोग अपने उद्देश्य को पूरी तरह से नहीं समझते हैं और एक ही बार में दोनों को हिला देते हैं।



यहाँ से


लिफ्ट में दो सेट बटन होते हैं: कैब में एक ऑर्डर पैनल होता है, और फर्श पर एक कॉल पैनल होता है। आप पहले से ही नाम से अनुमान लगा सकते हैं कि ऑर्डर पैनल में उच्च नियंत्रण प्राथमिकता है।


अप और डाउन बटन वाले कॉल पैनल वाले सभी लिफ्ट कुछ प्रकार के ट्रैवल ऑप्टिमाइज़ेशन एल्गोरिदम के साथ काम करते हैं, जिसका उद्देश्य न्यूनतम समय में अधिकतम यात्रियों की संख्या और मंजिल पर अधिकतम प्रतीक्षा समय (राज्य मानक द्वारा विनियमित) के लिए एक अलग स्थिति है।


इस तरह के एक एल्गोरिथ्म में आमतौर पर फर्श पर यात्रियों का चयन शामिल होता है, यदि वे उसी दिशा में यात्रा कर रहे हैं जैसे कि कॉल बटन "अप" या "बटन" दबाकर इंगित किया गया है।


ऐसी स्थिति की कल्पना करें जहां यात्रियों के साथ एक लिफ्ट नीचे जाती है और नीचे एक मंजिल से "डाउन" कॉल प्राप्त होती है। लिफ्ट यात्री को लेने के लिए बंद हो जाएगा (हाँ, वजन सेंसर द्वारा केबिन को लोड करने के लिए अभी भी लेखांकन है, लेकिन हम कम कर देंगे)।


लिफ्ट नीचे जाती है और नीचे की मंजिल से एक "ऊपर" कॉल प्राप्त करती है। यह तर्कसंगत है कि लिफ्ट किसी यात्री को लेने के लिए नहीं रुकेगी, क्योंकि यह यात्रा की दिशा नहीं बदलेगी (यह भी मानक द्वारा विनियमित है), और नीचे जाने के लिए एक यात्री को उठाएं और फिर लिफ्ट में ऊर्जा और स्थान की बेकार खपत।


लिफ्ट नीचे की मंजिल से दो कॉल "अप और डाउन" प्राप्त करती है, जो कुछ अधीर यात्री द्वारा दबाए गए थे जिन्हें ऊपर जाने की आवश्यकता है। यह तर्कसंगत है कि इस मंजिल पर लिफ्ट बंद हो जाएगी, लेकिन यात्री इसमें प्रवेश नहीं करेगा, लेकिन केबिन में लोगों के समय को धीमा करने और लिफ्ट को बंद करने, दरवाजे खोलने, इंतजार करने, दरवाजे बंद करने और रेटेड गति में तेजी लाने में समय लगेगा।


यदि लिफ्ट में फर्श पर केवल एक बटन है, तो 99% मामलों में यह "सामूहिक डाउन" एल्गोरिथम के अनुसार काम करता है, और यदि केबिन में आदेश हैं, तो नीचे जाने पर ही रुकता है।


यदि आपके पास जेएस में प्रोग्रामिंग कौशल है, तो आप ऑनलाइन गेम एलेवेटर सागा में एक समान नियंत्रण एल्गोरिदम को लागू करने का प्रयास कर सकते हैं। इसमें लिफ्टों के अनुकूलन के सभी पहलू हैं जो कि हार्डकोर में जाने के बिना लिफ्ट सेफ्टी सर्किट के संचालन की तरह है।



अपने टेलीग्राम चैनल में मैं इसी तरह की सामग्री पोस्ट करता हूं। अभी आप अगले डिवाइस के विकास का पालन कर सकते हैं।

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


All Articles