RT-ThreadでSFUDを使用してQSPIフラッシュをマウントするトレース分析
- QSPIバスの登録プロセス
- この段階では主にrt_device_register関数を通じてQSPIバスを登録している
- 重要なのはrt_spi_bus_register関数で、QSPI1バスを登録している
/*ドライバ層でのQSPIバス登録*/
drv_qspi.c :393 | rt_hw_qspi_bus_init
drv_qspi.c :394 | rt_hw_qspi_bus_init go=> stm32_qspi_register_bus
drv_qspi.c :306 | stm32_qspi_register_bus
drv_qspi.c :311 | stm32_qspi_register_bus go=> rt_qspi_bus_register
dev_qspi_core.c :75 | rt_qspi_bus_register
dev_qspi_core.c :78 | rt_qspi_bus_register go=> rt_spi_bus_register
dev_spi_core.c :34 | rt_spi_bus_register
dev_spi_core.c :37 | rt_spi_bus_register go=> rt_spi_bus_device_init
dev_spi.c :73 | rt_spi_bus_device_init
dev_spi.c :94 | rt_spi_bus_device_init go=> rt_device_register/*最終的にこの関数を呼び出してQSPI1バスを登録*/
device.c :156 | rt_device_find
device.c :157 | rt_device_find qspi1/**/
dev_spi_core.c :43 | rt_spi_bus_register go=> rt_mutex_init
- QSPIデバイスの登録と初期化
- アプリケーションはrt_hw_qspi_device_attach関数を呼び出してQSPIデバイスを登録し、CSピンを初期化(本記事ではハードウェアCSを使用しているため、この処理は実行されていない)
- rt_qspi_configure関数を経由してQSPIを初期化。この関数にはバグがあり、修正済み
- qspi_configureはドライバ移植時に実装が必要な関数の一つで、DMAやNVICの初期化もここで行う
/*アプリケーションがrt_hw_qspi_device_attachを呼び出すことで、QSPI10デバイスを登録し、CSピンを初期化(ハードウェアCSを使用しているため、ここでは実行されていない)*/
port_qflash.c :72 | rt_qspi_flash_init
port_qflash.c :75 | rt_qspi_flash_init go=> rt_hw_qspi_device_attach
drv_qspi.c :327 | rt_hw_qspi_device_attach
drv_qspi.c :335 | rt_hw_qspi_device_attach go=> rt_malloc
drv_qspi.c :351 | rt_hw_qspi_device_attach go=> rt_spi_bus_attach_device_cspin
dev_spi_core.c :90 | rt_spi_bus_attach_device_cspin
dev_spi_core.c :95 | rt_spi_bus_attach_device_cspin go=> rt_device_find
device.c :156 | rt_device_find
device.c :157 | rt_device_find qspi1
dev_spi_core.c :105 | rt_spi_bus_attach_device_cspin go=> rt_spidev_device_init
dev_spi.c :165 | rt_spidev_device_init
dev_spi.c :185 | rt_spidev_device_init go=> rt_device_register/*最終的にこの関数を呼び出してQSPI10デバイスを登録*/
device.c :96 | rt_device_register
device.c :97 | rt_device_register qspi10
device.c :98 | rt_device_register 3(0x00000003) <= flags
device.c :103 | rt_device_register go=> rt_device_find
device.c :156 | rt_device_find
device.c :157 | rt_device_find qspi10/**/
device.c :107 | rt_device_register go=> rt_object_init
dev_spi_core.c :116 | rt_spi_bus_attach_device_cspin go=> rt_memset
/*アプリケーションがrt_sfud_flash_probeを呼び出すことで、rt_qspi_configure関数(バグあり、修正済み)を呼び出す。底层ではqspi_configure関数を呼び出す*/
port_qflash.c :77 | rt_qspi_flash_init go=> rt_sfud_flash_probe
device.c :156 | rt_device_find
device.c :157 | rt_device_find qspi10
dev_qspi_core.c :16 | rt_qspi_configure
dev_qspi_core.c :69 | rt_qspi_configure go=> rt_spi_bus_configure
dev_spi_core.c :139 | rt_spi_bus_configure
dev_spi_core.c :150 | rt_spi_bus_configure go=> device->bus->ops->configure
drv_qspi.c :289 | qspi_configure/*ドライバ層で実装が必要な関数1*/
drv_qspi.c :294 | qspi_configure go=> stm32_qspi_init
drv_qspi.c :38 | stm32_qspi_init/*最終的にstm32_qspi_initを呼び出す。QSPIの初期化はここにすべて実施*/
drv_qspi.c :47 | stm32_qspi_init go=> rt_memset
drv_qspi.c :83 | stm32_qspi_init go=> HAL_QSPI_Init
- 1バイト送信3バイト受信(Flash ID読み取り)
- 1バイト送信3バイト受信、コマンドは0x9FでFlash ID読み取り
- ドライバ移植時に実装が必要な関数はqspixfer
/*1バイト送信3バイト受信、コマンドは0x9FでFlash ID読み取り*/
/*ドライバ側でqspixferを実装必要*/
dev_qspi_core.c :151 | rt_qspi_send_then_recv
dev_qspi_core.c :152 | rt_qspi_send_then_recv 1(0x00000001) <= send_length
dev_qspi_core.c :153 | rt_qspi_send_then_recv 3(0x00000003) <= recv_length
dev_qspi_core.c :225 | rt_qspi_send_then_recv go=> rt_qspi_transfer_message
dev_qspi_core.c :91 | rt_qspi_transfer_message
dev_qspi_core.c :92 | rt_qspi_transfer_message 159(0x0000009f) message->instruction.content
dev_qspi_core.c :93 | rt_qspi_transfer_message 1(0x00000001) message->instruction.qspi_lines
dev_qspi_core.c :94 | rt_qspi_transfer_message 0(0x00000000) message->address.content
dev_qspi_core.c :95 | rt_qspi_transfer_message 0(0x00000000) message->address.size
dev_qspi_core.c :96 | rt_qspi_transfer_message 0(0x00000000) message->address.qspi_lines
dev_qspi_core.c :97 | rt_qspi_transfer_message 0(0x00000000) message->dummy_cycles
dev_qspi_core.c :98 | rt_qspi_transfer_message 1(0x00000001) message->qspi_data_lines
dev_qspi_core.c :135 | rt_qspi_transfer_message go=> rt_spi_bus_xfer
drv_qspi.c :206 | qspixfer
drv_qspi.c :254 | qspixfer go=> qspi_send_cmd
drv_qspi.c :128 | qspi_send_cmd
drv_qspi.c :200 | qspi_send_cmd go=> HAL_QSPI_Command
drv_qspi.c :259 | qspixfer go=> HAL_QSPI_Receive
- 5バイト送信8バイト受信(SFDPパラメータ読み取り)
- 指令0x5AはSFDP指令で、フラッシュのパラメータ(容量、読写指令など)を取得できる
- 本実装ではpollingを使用し、DMAは未サポート。RT-ThreadのQSPI DMAサポートは未完成で、今後実装予定
/*5バイト送信8バイト受信*/
/*注意:0x5AはSFDP指令で、フラッシュのパラメータ(容量、読写指令など)を取得できる*/
dev_qspi_core.c :151 | rt_qspi_send_then_recv
dev_qspi_core.c :152 | rt_qspi_send_then_recv 5(0x00000005) <= send_length
dev_qspi_core.c :153 | rt_qspi_send_then_recv 8(0x00000008) <= recv_length
dev_qspi_core.c :225 | rt_qspi_send_then_recv go=> rt_qspi_transfer_message
dev_qspi_core.c :91 | rt_qspi_transfer_message
dev_qspi_core.c :92 | rt_qspi_transfer_message 90(0x0000005a) message->instruction.content
dev_qspi_core.c :93 | rt_qspi_transfer_message 1(0x00000001) message->instruction.qspi_lines
dev_qspi_core.c :94 | rt_qspi_transfer_message 0(0x00000000) message->address.content/*0アドレスから8バイト読み取り*/
dev_qspi_core.c :95 | rt_qspi_transfer_message 24(0x00000018) message->address.size
dev_qspi_core.c :96 | rt_qspi_transfer_message 1(0x00000001) message->address.qspi_lines
dev_qspi_core.c :97 | rt_qspi_transfer_message 8(0x00000008) message->dummy_cycles
dev_qspi_core.c :98 | rt_qspi_transfer_message 1(0x00000001) message->qspi_data_lines
dev_qspi_core.c :135 | rt_qspi_transfer_message go=> rt_spi_bus_xfer
drv_qspi.c :206 | qspixfer
drv_qspi.c :254 | qspixfer go=> qspi_send_cmd
drv_qspi.c :128 | qspi_send_cmd
drv_qspi.c :200 | qspi_send_cmd go=> HAL_QSPI_Command
drv_qspi.c :259 | qspixfer go=> HAL_QSPI_Receive
/*5バイト送信8バイト受信(アドレス8から読み取り)*/
dev_qspi_core.c :151 | rt_qspi_send_then_recv
dev_qspi_core.c :152 | rt_qspi_send_then_recv 5(0x00000005) <= send_length
dev_qspi_core.c :153 | rt_qspi_send_then_recv 8(0x00000008) <= recv_length
dev_qspi_core.c :225 | rt_qspi_send_then_recv go=> rt_qspi_transfer_message
dev_qspi_core.c :91 | rt_qspi_transfer_message
dev_qspi_core.c :92 | rt_qspi_transfer_message 90(0x0000005a) message->instruction.content
dev_qspi_core.c :93 | rt_qspi_transfer_message 1(0x00000001) message->instruction.qspi_lines
dev_qspi_core.c :94 | rt_qspi_transfer_message 8(0x00000008) message->address.content/*アドレス8から8バイト読み取り*/
dev_qspi_core.c :95 | rt_qspi_transfer_message 24(0x00000018) message->address.size
dev_qspi_core.c :96 | rt_qspi_transfer_message 1(0x00000001) message->address.qspi_lines
dev_qspi_core.c :97 | rt_qspi_transfer_message 8(0x00000008) message->dummy_cycles
dev_qspi_core.c :98 | rt_qspi_transfer_message 1(0x00000001) message->qspi_data_lines
dev_qspi_core.c :135 | rt_qspi_transfer_message go=> rt_spi_bus_xfer
drv_qspi.c :206 | qspixfer
drv_qspi.c :254 | qspixfer go=> qspi_send_cmd
drv_qspi.c :128 | qspi_send_cmd
drv_qspi.c :200 | qspi_send_cmd go=> HAL_QSPI_Command
drv_qspi.c :259 | qspixfer go=> HAL_QSPI_Receive
/*5バイト送信36バイト受信(アドレス128から読み取り)*/
dev_qspi_core.c :151 | rt_qspi_send_then_recv
dev_qspi_core.c :152 | rt_qspi_send_then_recv 5(0x00000005) <= send_length
dev_qspi_core.c :153 | rt_qspi_send_then_recv 36(0x00000024) <= recv_length
dev_qspi_core.c :225 | rt_qspi_send_then_recv go=> rt_qspi_transfer_message
dev_qspi_core.c :91 | rt_qspi_transfer_message
dev_qspi_core.c :92 | rt_qspi_transfer_message 90(0x0000005a) message->instruction.content
dev_qspi_core.c :93 | rt_qspi_transfer_message 1(0x00000001) message->instruction.qspi_lines
dev_qspi_core.c :94 | rt_qspi_transfer_message 128(0x00000080) message->address.content/*アドレス128から36バイト読み取り*/
dev_qspi_core.c :95 | rt_qspi_transfer_message 24(0x00000018) message->address.size
dev_qspi_core.c :96 | rt_qspi_transfer_message 1(0x00000001) message->address.qspi_lines
dev_qspi_core.c :97 | rt_qspi_transfer_message 8(0x00000008) message->dummy_cycles
dev_qspi_core.c :98 | rt_qspi_transfer_message 1(0x00000001) message->qspi_data_lines
dev_qspi_core.c :135 | rt_qspi_transfer_message go=> rt_spi_bus_xfer
drv_qspi.c :206 | qspixfer
drv_qspi.c :254 | qspixfer go=> qspi_send_cmd
drv_qspi.c :128 | qspi_send_cmd
drv_qspi.c :200 | qspi_send_cmd go=> HAL_QSPI_Command
drv_qspi.c :259 | qspixfer go=> HAL_QSPI_Receive
- SPI-Flashのリセット処理
- 0x66と0x99のコマンドシーケンスを実行してFlashをリセット
- 0x66はリセット許可、0x99はリセット実行
/*1バイト送信で0x66コマンドを実行し、リセットを有効化*/
dev_qspi_core.c :241 | rt_qspi_send
dev_qspi_core.c :242 | rt_qspi_send 1(0x00000001) <= length
dev_qspi_core.c :314 | rt_qspi_send go=> rt_qspi_transfer_message
dev_qspi_core.c :91 | rt_qspi_transfer_message
dev_qspi_core.c :92 | rt_qspi_transfer_message 102(0x00000066) message->instruction.content
dev_qspi_core.c :93 | rt_qspi_transfer_message 1(0x00000001) message->instruction.qspi_lines
dev_qspi_core.c :