背景:これまでは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()