
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

Di sini saya menghubungkan kabel putih UART1 (pin PA9) dengan Rx UART2 (pin PA3).
Jika Anda melihat kodenyaconst 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++) { USART_SendData(USARTy, message[i]); GPIO_SetBits(GPIOC, GPIO_Pin_13); 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:

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.