So beenden Sie das Schreiben von Firmware für Mikrocontroller. Wir fangen an zu leben ...


Und wieder finden wir heraus, wie man keine Firmware für Mikrocontroller schreibt. Der vorige Artikel hat viele Emotionen bei Menschen geweckt, und es scheint mir, dass nur wenige Menschen verstanden haben, und vielleicht wurde mir schlecht erklärt, warum all dies begonnen wurde.


Deshalb habe ich ein Beispiel vorbereitet.


Dies ist zwar nur ein optimiertes Beispiel für DMA_Polling aus der Standard Peripherals Library.


Dies ist jedoch der Vorteil dieses Ansatzes, dass Sie alle Entwicklungen aus dem auf dem Mikrocontroller ausgeführten Code verwenden können, einschließlich Bibliotheken des Herstellers MK wie HAL oder Standard Peripherals Library. Und dies sollte für jeden Controller fair sein, der openOCD unterstützt - zumindest STM32, Atmel, PIC32 und andere auf der Liste . Gleichzeitig können wir alle Bibliotheken des Host-PCs sowie die neuen C ++ - Sprachstandards verwenden. Und wenn Sie Wrapper schreiben, können Sie im Allgemeinen jede Sprache verwenden. Aber ich habe hier nicht viel kompliziert. Ich habe mich gerade entschlossen, die grundlegenden Funktionen und Merkmale zu zeigen.


Im Beispiel blinken wir natürlich die LED. Senden Sie außerdem Daten auf UART und einem anderen UART, um sie über DMA zu empfangen. Die Verwendung von DMA bietet einen enormen Bonus. Oft ist es möglich, Interrupts zu entfernen, die wir hier nicht verwenden können, und Abfragen, die aufgrund meines Debuggers sehr langsam sind, aber immer noch weniger Zeit zum Erfassen von Daten auf Schnittstellen benötigen. Und auch schnell generieren. Daher ist es ziemlich einfach, einen programmierbaren Signalgenerator und einen Sniffer verschiedener Schnittstellen herzustellen.


Die Ausrüstung, an der wir testen werden, bleibt ab dem Zeitpunkt des ersten Artikels erhalten


Bild
Hier habe ich die weiße Verkabelung UART1 (PA9-Pin) mit Rx UART2 (PA3-Pin) verbunden.


Wenn Sie sich den Code ansehen
const char * message = "AddressIntercept PinTool UART DMA example"; int main() { sizeMemoryTranslate_t s = 0; memoryTranslate *p = getMemoryMap(&s); pAddrPERIPH = p[0].start_addr; pAddrSRAM = p[1].start_addr; init(); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitTypeDef gpio; gpio.GPIO_Pin = GPIO_Pin_13; gpio.GPIO_Speed = GPIO_Speed_50MHz; gpio.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &gpio); const size_t _SIZE_MESSAGE = strlen(message); printf("sending message "); for (int i = 0; i < _SIZE_MESSAGE; i++) { /* Send one byte from USARTy to USARTz */ USART_SendData(USARTy, message[i]); GPIO_SetBits(GPIOC, GPIO_Pin_13); /* Loop until USARTy DR register is empty */ while (USART_GetFlagStatus(USARTy, USART_FLAG_TXE) == RESET); printf("."); fflush(stdout); GPIO_ResetBits(GPIOC, GPIO_Pin_13); } printf("\n"); printf("qty of sent bytes %d\n", strlen(message)); const uint16_t rec = DMA_GetCurrDataCounter(USARTz_Rx_DMA_Channel); printf("qty of received byte using DMA : %d\n", sizeDMAbuf - rec); printf("read message from buffer DMA : "); const uint8_t *pM = (uint8_t *)pAddrSRAM; for (int r = 0; r < _SIZE_MESSAGE; r++) { printf("%c", pM[r]); fflush(stdout); } printf("\n"); assert(strncmp(message, (const char *)pM, _SIZE_MESSAGE) == 0); printf("Received and sent bytes are equal!\n"); return 0; } 

Sie sehen, dass mit Ausnahme unserer Funktion zum Konvertieren von Adressen und Funktionen aus der Standardbibliothek alles andere aus der SPL von ST übernommen wurde. Grundsätzlich war es möglich, diese aus der HAL-Funktion zu verwenden. Aber ich bin an die gute alte SPL gewöhnt.


Wie man alles zusammenbaut und laufen lässt


Dies ist ein Beispiel für einen PC mit Ubuntu 16.04 64-Bit:


Zuerst müssen Sie Pintool v3.7 herunterladen


Das Entpacken ist praktisch. Sie können entweder die Variable PIN_ROOT definieren, um den PinTool-Client zu erstellen, oder einfach unseren Client in suchen


 pin-3.7-97619-g0d0c92f4f-gcc-linux/source/tools/ 

Ich mache den zweiten Weg


 cd pin-3.7-97619-g0d0c92f4f-gcc-linux/source/tools/ git clone git@github.com:ser-mk/AddressIntercept.git cd AddressIntercept 

Als Nächstes müssen Sie einen 32-Bit-Client erstellen


 make TARGET=ia32 

Die Binärdatei wird hier obj-ia32 / addrIntercept.so sein. 32-Bit ist erforderlich, da in ARM ortex eine solche Adressgröße vorliegt.


Jetzt können Sie das Beispiel selbst sammeln. Ich kopiere es direkt in den Ordner auf den Pintool-Client


 cd pin-3.7-97619-g0d0c92f4f-gcc-linux/source/tools/AddressIntercept Git clone https://github.com/ser-mk/addrIntercept-example-UART-DMA Cd addrIntercept-example-UART-DMA Make 

Und wir bekommen die Binärdatei im Verzeichnis test.elf. Zur Vereinfachung des Experiments werde ich die Datei im Verzeichnis unseres Pintool-Clients AddressIntercept ablegen


Bevor wir alles starten, müssen wir benannte FIFOs erstellen, um mit dem OpenOCD-Client zu kommunizieren


 cd pin-3.7-97619-g0d0c92f4f-gcc-linux/source/tools/AddressIntercept mkfifo in.fifo out.fifo 

in.fifo out.fifo - Standardnamen für unsere Clients. Sie können andere Namen angeben, diese müssen jedoch beim Starten von Clients explizit angegeben werden.


Führen Sie den openOCD-Client aus. In meinem Fall muss er die IP-Adresse des OpenOCD-Servers übergeben. Er lautet 192.168.0.111. Der Port verlässt den Standard 6666, daher gebe ich ihn nicht an.


Also in der richtigen Reihenfolge laufen


 cd pin-3.7-97619-g0d0c92f4f-gcc-linux/source/tools/AddressIntercept python3.5m OCDclient.py -ip 192.168.0.111 & ../../../pin -t obj-ia32/addrIntercept.so -- addrIntercept-example-UART-DMA/test.elf 

Und die Schlussfolgerung sollte so lauten:


Bild


Ich hoffe ein anschauliches Beispiel. Schon ein ziemlicher Proof of Concept, der verwendet werden kann.


Darüber hinaus sollte alles funktionieren, auch unter MacOS und Windows (hier müssen Sie möglicherweise die Arbeit mit dem Namen fifo optimieren oder durch das ersetzen, was sich in den "Fenstern" befindet).


Wenn es interessant ist, können Sie in den folgenden Artikeln über REPL wie im GIF aus dem vorherigen Artikel und andere Möglichkeiten zum Abfangen von Adressen sprechen, ohne die Intel-Plattform einzuschränken.

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


All Articles