背景:これまではgdbのxコマンドを使ってSTM32C0のレジスタを手動で参照、設定していた
課題:毎回手動だとアドレスを忘れるし、何が正しかったか分からなくなる
対策:gdbではpythonスクリプトが動かせるので、手作業だったレジスタ操作を自動化できる
結果:自動化した。さらに、for文でUARTの送受信レジスタを読み書きすることで、UARTの送受信プログラムもPythonで書けてしまう
詳細:
以下がUSARTを初期化して、テスト用にASCIIコードをUARTから送信しつづけるプログラム。ハンドアセンブルと叫んでいたのに、これではPythonでマイコン動かしているのではないか?これはチートでは?とも自問自答するが、最終的には全部機械語に置き換えるので、導入段階はPythonに助けてもらう。
# # python script for GDB # import sys import time sys.path.append('.') import gdb from reg_defs import * from mylib import * inferior = gdb.inferiors()[0] def setup_uart_regs(inferior): # disable USART addr = USART_BASE + USART_CR1 val = bytes(reversed((0,0,0,0))) inferior.write_memory(addr, val) # clear and set default protocol addr = USART_BASE + USART_CR1 val = bytes(reversed((0,0,0,0))) inferior.write_memory(addr, val) # clear and set default stop bit addr = USART_BASE + USART_CR2 val = bytes(reversed((0,0,0,0))) inferior.write_memory(addr, val) # set baudrate addr = USART_BASE + USART_BRR val = bytes(reversed((0,0,0,0xd0))) inferior.write_memory(addr, val) # enable FIFO addr = USART_BASE + USART_CR1 val = bytes(reversed((0x20,0,0,0))) inferior.write_memory(addr, val) # enable USART addr = USART_BASE + USART_CR1 val = bytes(reversed((0x20,0,0,0x0d))) inferior.write_memory(addr, val) def send_char(inferior, char): # write addr = USART_BASE + USART_TDR val = bytes(reversed((0,0,0,char))) inferior.write_memory(addr, val) dump_uart_regs(inferior) setup_uart_regs(inferior) dump_uart_regs(inferior) while True: for ch in range(0x20, 0x7f): send_char(inferior, ch) time.sleep(0.5)
USBシリアル経由で送信されたASCIIコードを受信
イケてないけど開発環境
■追記
以下のように、UARTでASCIIコードを受信するコードもPythonで書けてしまう
import sys import time sys.path.append('.') from reg_defs import * from mylib import * inferior = gdb.inferiors()[0] def receive_char(inferior): addr = USART_BASE + USART_RDR size = 4 val = inferior.read_memory(addr, size) return val.tobytes()[0] while True: reg = read_uart_ISR(inferior) if reg[3] & 0b0010_0000: # check RXFNE bit is set char = receive_char(inferior) if char >= 0x20 and char < 0x7f: print(f'{chr(char)}({char:02x})', end=' ') else: print(f'{char:02x}', end=' ') if char == 0x0d: print()