RT-ThreadでSFUDを使用してQSPIフラッシュをマウントするトレース分析

RT-ThreadでSFUDを使用してQSPIフラッシュをマウントするトレース分析

  1. 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

  1. 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. 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

  1. 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

  1. 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   :

タグ: rt-thread sfud qspi STM32 HAL

8月22日 04:31 投稿