Bagaimana cara berhenti menulis firmware untuk mikrokontroler. Kami mulai hidup ...


Dan lagi, kami mencari tahu bagaimana tidak menulis firmware untuk mikrokontroler. Artikel sebelumnya membangkitkan banyak emosi pada orang dan, menurut saya, sedikit orang yang mengerti dan, mungkin, tidak dijelaskan dengan baik kepada saya mengapa semua ini dimulai.


Karena itu, saya menyiapkan contoh .


Meskipun ini hanya contoh tweak DMA_Polling dari Perpustakaan Periferal Standar.


Tetapi ini adalah keuntungan dari pendekatan ini, bahwa Anda dapat menggunakan semua perkembangan dari kode yang dieksekusi pada mikrokontroler, termasuk perpustakaan dari pabrikan MK seperti HAL atau Perpustakaan Periferal Standar. Dan ini harus adil untuk setiap pengontrol yang mendukung openOCD - setidaknya STM32, Atmel, PIC32, dan lainnya dalam daftar . Pada saat yang sama, kita dapat menggunakan semua pustaka dari PC host, serta menggunakan standar bahasa C ++ baru. Dan jika Anda menulis pembungkus, maka secara umum Anda dapat menggunakan bahasa apa pun. Tapi saya tidak banyak terlibat di sini. Saya baru saja memutuskan untuk menunjukkan fungsionalitas dan fitur dasar.


Dalam contoh, tentu saja, kita akan mengedipkan LED. Dan juga mengirim data pada UART dan pada UART lain untuk menerimanya menggunakan DMA. Menggunakan DMA memberikan bonus besar. Seringkali mungkin untuk menghilangkan interupsi yang tidak dapat kita gunakan di sini, dan pemungutan suara, yang, karena debugger saya, sangat lambat, tetapi masih lebih sedikit waktu untuk mengambil data pada antarmuka. Dan juga cepat menghasilkan. Oleh karena itu, sangat sederhana untuk membuat generator sinyal yang dapat diprogram dan sniffer dari berbagai antarmuka.


Peralatan yang akan kami uji tetap dari saat artikel pertama


gambar
Di sini saya menghubungkan kabel putih UART1 (pin PA9) dengan Rx UART2 (pin PA3).


Jika Anda melihat kodenya
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; } 

Anda dapat melihat bahwa, dengan pengecualian fungsi kami mengubah alamat dan fungsi dari pustaka standar, semua yang lain diambil oleh SPL dari ST, pada prinsipnya dimungkinkan untuk digunakan dari fungsi HAL. Tapi saya lebih akrab dengan SPL tua yang bagus.


Cara merakit dan menjalankan semuanya


Ini adalah contoh untuk PC dengan Ubuntu 16.04 64-bit:


Pertama, Anda perlu mengunduh Pintool v3.7


Membongkar itu nyaman, maka Anda dapat menentukan variabel PIN_ROOT untuk membangun klien PinTool atau cukup menemukan klien kami di


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

Saya melakukan cara kedua


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

Selanjutnya, Anda perlu membangun klien 32-bit


 make TARGET=ia32 

Biner akan ada di sini obj-ia32 / addrIntercept.so. Diperlukan 32-bit, karena dalam ARM ortex ukuran alamat seperti itu.


Sekarang Anda dapat mengumpulkan contoh itu sendiri. Saya menyalinnya langsung ke folder ke klien pintool


 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 

Dan kita mendapatkan biner di direktori test.elf. Lebih lanjut untuk kesederhanaan percobaan, saya akan meletakkan file di direktori PintIn client client Pintool kami


Sebelum memulai semuanya, kita perlu membuat FIFO bernama untuk berkomunikasi dengan klien OpenOCD


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

in.fifo out.fifo - nama default untuk klien kami, Anda dapat memberikan nama lain, tetapi kemudian harus ditentukan secara eksplisit saat memulai klien.


Jalankan klien openOCD, dalam kasus saya perlu lulus ip openOCD server ip, itu akan menjadi 192.168.0.111, port akan meninggalkan standar 6666, jadi saya tidak menentukannya.


Jadi, jalankan secara berurutan


 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 

Dan kesimpulannya harus seperti ini:


gambar


Saya berharap contoh ilustratif. Sudah cukup bukti konsep yang bisa digunakan.


Selain itu, semuanya harus bekerja, termasuk di MacOS dan Windows (di sini, Anda mungkin harus mengubah pekerjaan dengan nama fifo atau menggantinya dengan apa yang ada di "windows").


Lebih lanjut, dalam artikel berikut, jika menarik, Anda dapat berbicara tentang REPL seperti pada GIF dari artikel sebelumnya dan cara-cara lain untuk menyadap alamat, tanpa batasan oleh platform Intel.

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


All Articles