diff --git a/rt-thread-version/rt-thread-standard/_sidebar.md b/rt-thread-version/rt-thread-standard/_sidebar.md index 17256182fa88f8600aef9c827e04218cdfc14110..aa0f6f60f7f907a63be4a050b0ead5cf88d41ba9 100644 --- a/rt-thread-version/rt-thread-standard/_sidebar.md +++ b/rt-thread-version/rt-thread-standard/_sidebar.md @@ -207,6 +207,8 @@ - [恩智浦FRDM-MCXA156开发实践指南](/rt-thread-version/rt-thread-standard/tutorial/make-bsp/MCX-A156/恩智浦FRDM-MCXA156实践指南.md) - 兆易创新GD32系列 - [兆易创新GD32F527I-EVAL开发实践指南](/rt-thread-version/rt-thread-standard/tutorial/make-bsp/gd32/兆易创新GD32F527I-EVAL开发实践指南.md) + - 富瀚微系列 + - [富瀚微FH8626V300L开发实践指南](/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/富瀚微FH8626V300L开发实践指南.md) - 官方开发板 - [星火一号](/rt-thread-version/rt-thread-standard/hw-board/spark-1/spark-1.md) diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN017ayJ2N1NmLXmlmoA1_!!1817661612.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN017ayJ2N1NmLXmlmoA1_!!1817661612.png new file mode 100644 index 0000000000000000000000000000000000000000..58c1a19e9ac321878ee84e869767ae8c03076216 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN017ayJ2N1NmLXmlmoA1_!!1817661612.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01DgA3HQ1NmLXmgFHsW_!!1817661612.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01DgA3HQ1NmLXmgFHsW_!!1817661612.png new file mode 100644 index 0000000000000000000000000000000000000000..5e8baa433c1473cb968e71c0e3574428cd1ba5aa Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01DgA3HQ1NmLXmgFHsW_!!1817661612.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01QkWfI31NmLXlmZ9Ko_!!1817661612.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01QkWfI31NmLXlmZ9Ko_!!1817661612.png new file mode 100644 index 0000000000000000000000000000000000000000..da6a4ca5a942126cd93296bafa7ed9ace3b14030 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01QkWfI31NmLXlmZ9Ko_!!1817661612.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01Xuo16b1NmLYIjS4IRcrop,0,0,1279,2558_!!1817661612.jpg b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01Xuo16b1NmLYIjS4IRcrop,0,0,1279,2558_!!1817661612.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d01dbd0afae2ad7ebf560604db96953aeeb4ffc1 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01Xuo16b1NmLYIjS4IRcrop,0,0,1279,2558_!!1817661612.jpg differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01hIw9xM1NmLXlLIu37_!!1817661612.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01hIw9xM1NmLXlLIu37_!!1817661612.png new file mode 100644 index 0000000000000000000000000000000000000000..bb730585391a1bc8d615d1a77d208175ddeb6498 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01hIw9xM1NmLXlLIu37_!!1817661612.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01jFF6B81NmLXnIMhUN_!!1817661612.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01jFF6B81NmLXnIMhUN_!!1817661612.png new file mode 100644 index 0000000000000000000000000000000000000000..07774f8974413a44705118049b3297eaebdedb17 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01jFF6B81NmLXnIMhUN_!!1817661612.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01kSw0wt1NmLXnyfnH9_!!1817661612.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01kSw0wt1NmLXnyfnH9_!!1817661612.png new file mode 100644 index 0000000000000000000000000000000000000000..42058d8da03133588092a31419de8cfc5107b38f Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01kSw0wt1NmLXnyfnH9_!!1817661612.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01vtJ7Fi1NmLXmOmoeA_!!1817661612.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01vtJ7Fi1NmLXmOmoeA_!!1817661612.png new file mode 100644 index 0000000000000000000000000000000000000000..d6847abc0d34dac7379942b8b04c938e60fc373f Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01vtJ7Fi1NmLXmOmoeA_!!1817661612.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01xPZILE1NmLXnIQTCx_!!1817661612.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01xPZILE1NmLXnIQTCx_!!1817661612.png new file mode 100644 index 0000000000000000000000000000000000000000..07c7a2441d075b0b323472b8c672312d239263ed Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/O1CN01xPZILE1NmLXnIQTCx_!!1817661612.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205155037769.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205155037769.png new file mode 100644 index 0000000000000000000000000000000000000000..c74aa0ce73126be2d7a13530545d4d9de454afc6 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205155037769.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205155257034.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205155257034.png new file mode 100644 index 0000000000000000000000000000000000000000..55e3f04423034370714437c85d8e2f3066c2b14a Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205155257034.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205155758476.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205155758476.png new file mode 100644 index 0000000000000000000000000000000000000000..df0652dc88225e1b29bd7d5c837ddd1d568ac1d8 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205155758476.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205160903391.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205160903391.png new file mode 100644 index 0000000000000000000000000000000000000000..6efac379687df5e09e6e0af5a8afea652386e884 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205160903391.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205162223990.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205162223990.png new file mode 100644 index 0000000000000000000000000000000000000000..90172a709f95fe05306a36407839f03ee26573f2 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205162223990.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205162259628.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205162259628.png new file mode 100644 index 0000000000000000000000000000000000000000..ec240314163b7d85c49f91c9c5dc237b1da87f7b Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205162259628.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205162418489.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205162418489.png new file mode 100644 index 0000000000000000000000000000000000000000..24939ba24b7ca81b1d48c1594e9f281b27baa9a5 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205162418489.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205165833376.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205165833376.png new file mode 100644 index 0000000000000000000000000000000000000000..6e9520e455d52bf484732f936edb86eabfd42d3d Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205165833376.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205165931584.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205165931584.png new file mode 100644 index 0000000000000000000000000000000000000000..a27d0466779fcd58ea0c777f2a8f55bfd192d0b7 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205165931584.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205170009227.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205170009227.png new file mode 100644 index 0000000000000000000000000000000000000000..208d5c7dedbf5bcf7c06099dfa46298c1f814df2 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205170009227.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205171346094.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205171346094.png new file mode 100644 index 0000000000000000000000000000000000000000..a5d7c3cdc280bc9cab1870fb91bfda504dd1d243 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205171346094.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205171847725.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205171847725.png new file mode 100644 index 0000000000000000000000000000000000000000..4b013f5bc0c17eaf8faca9aaa3a054c984f6559e Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205171847725.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172033034.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172033034.png new file mode 100644 index 0000000000000000000000000000000000000000..0655f186e6932c1c704e1710e00192279ccdaad6 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172033034.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172122432.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172122432.png new file mode 100644 index 0000000000000000000000000000000000000000..f5dde4dd53e6955d0895e184d8d41fcb9c5fbf8e Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172122432.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172133756.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172133756.png new file mode 100644 index 0000000000000000000000000000000000000000..47b68932d5132f8a4ced06c40ef01757bd26f894 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172133756.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172310038.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172310038.png new file mode 100644 index 0000000000000000000000000000000000000000..186720898581badc3e626a0e225768ab3a4f52d0 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172310038.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172520750.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172520750.png new file mode 100644 index 0000000000000000000000000000000000000000..59c01ee4187b938e96fffc04672f9770e270cf09 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172520750.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172759374.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172759374.png new file mode 100644 index 0000000000000000000000000000000000000000..9c3af2ce7e2cec92e99c9083273e9b0b03587496 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172759374.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172834981.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172834981.png new file mode 100644 index 0000000000000000000000000000000000000000..1b09ba76c9d0e8c0bf567d80e1e5fd3a48207609 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205172834981.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205173258999.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205173258999.png new file mode 100644 index 0000000000000000000000000000000000000000..9650174d90d6ef50ab0a9b65ba15e48003f7db18 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205173258999.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205173619585.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205173619585.png new file mode 100644 index 0000000000000000000000000000000000000000..146cd7566b201d5d09a81ab17247f3bf24f323f0 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205173619585.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205180152259.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205180152259.png new file mode 100644 index 0000000000000000000000000000000000000000..a6b2007812c5fc37c6e3f33bb3f91f82ff16b2b3 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251205180152259.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208092254355.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208092254355.png new file mode 100644 index 0000000000000000000000000000000000000000..03bb5055fd25237758f05943cdb59029f2970f23 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208092254355.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208092425832.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208092425832.png new file mode 100644 index 0000000000000000000000000000000000000000..194316854769be90eb6de3380f3b23feadde5f78 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208092425832.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208093046254.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208093046254.png new file mode 100644 index 0000000000000000000000000000000000000000..10c1dacb6a38f22cf1e38182dcfe1d7fb69ef11f Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208093046254.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208094854260.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208094854260.png new file mode 100644 index 0000000000000000000000000000000000000000..6ef094b3af3724098facd9d5fbb2c903a8c5505a Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208094854260.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208094941531.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208094941531.png new file mode 100644 index 0000000000000000000000000000000000000000..54ec6024a350f7e38788e6af97c40ffa96d38f72 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208094941531.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208100215313.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208100215313.png new file mode 100644 index 0000000000000000000000000000000000000000..e6e87a63f94e043b9717d0bfca6b57b9f3f38475 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208100215313.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208103909381.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208103909381.png new file mode 100644 index 0000000000000000000000000000000000000000..37cea80c1db5e6fa499aa0617dc0964f04fdf0af Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208103909381.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208105138748.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208105138748.png new file mode 100644 index 0000000000000000000000000000000000000000..93f179c1678638d5536ae8a414119043b9df1a30 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208105138748.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208105347276.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208105347276.png new file mode 100644 index 0000000000000000000000000000000000000000..a6a6bc6517752ab45fbe5a1e1a4745b908e768af Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208105347276.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208112256760.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208112256760.png new file mode 100644 index 0000000000000000000000000000000000000000..6cfd3d326758f68031c9664126093f50de1a6d98 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208112256760.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208113115015.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208113115015.png new file mode 100644 index 0000000000000000000000000000000000000000..aaa35e9916da6ad9997e94182ef08051a854ed91 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208113115015.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208114050564.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208114050564.png new file mode 100644 index 0000000000000000000000000000000000000000..59720161da746ad50b776e78faae36d49ada8246 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208114050564.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208114201438.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208114201438.png new file mode 100644 index 0000000000000000000000000000000000000000..3a71280beb99542ec672cd35d39e9d23c12e35ca Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208114201438.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208115405504.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208115405504.png new file mode 100644 index 0000000000000000000000000000000000000000..a44c74731627ce5241a249d18a12275d1f592748 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208115405504.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208115456155.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208115456155.png new file mode 100644 index 0000000000000000000000000000000000000000..7d25e74281fcf82ab855cfd0c543a6e5a7afdabc Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208115456155.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208115753622.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208115753622.png new file mode 100644 index 0000000000000000000000000000000000000000..251e5c3660bfd3740342eb83c1e3c308299b36ca Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208115753622.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208115824560.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208115824560.png new file mode 100644 index 0000000000000000000000000000000000000000..0c323af771ed7a50788ba170222f23778dff322e Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208115824560.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208132210504.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208132210504.png new file mode 100644 index 0000000000000000000000000000000000000000..f60ba7ceafcabbae9ea651a8807a59919aeeac47 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208132210504.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208132247810.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208132247810.png new file mode 100644 index 0000000000000000000000000000000000000000..2f03a8e65bf777cc9b3206a9f464c1462c14ba30 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208132247810.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208132641846.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208132641846.png new file mode 100644 index 0000000000000000000000000000000000000000..432ed9cc4887b39a2e3aa1064455703c3ff685d5 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208132641846.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208132817185.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208132817185.png new file mode 100644 index 0000000000000000000000000000000000000000..155cfcf42c810e49f8c03a6800a6871cf18e4c8f Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251208132817185.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251209163735422.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251209163735422.png new file mode 100644 index 0000000000000000000000000000000000000000..02cddfba657b79a21f30d90189c731887a89edf0 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251209163735422.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251209165147055.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251209165147055.png new file mode 100644 index 0000000000000000000000000000000000000000..63929d476dcc1cdfc1c4f63358070df6d11000ee Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251209165147055.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251209171054101.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251209171054101.png new file mode 100644 index 0000000000000000000000000000000000000000..764f26d3bea860242aebca03e22da81f862bbbc5 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251209171054101.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210142735500.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210142735500.png new file mode 100644 index 0000000000000000000000000000000000000000..7b5daa430592cb5dd666c042b8a36fd70dfb0206 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210142735500.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210142921637.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210142921637.png new file mode 100644 index 0000000000000000000000000000000000000000..7875db48195c07b8e319f990d06f69d0dcc3a6c8 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210142921637.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210143317165.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210143317165.png new file mode 100644 index 0000000000000000000000000000000000000000..ea327cdb83ef6d3751ae3f38c2d2e385c64d4206 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210143317165.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210143417100.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210143417100.png new file mode 100644 index 0000000000000000000000000000000000000000..c5348d5d2cd6cdd7c5f5b35b4b0703482cbd9b46 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210143417100.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210144456410.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210144456410.png new file mode 100644 index 0000000000000000000000000000000000000000..1985c74819b8d2731ab8444cf2015be2ecd63a70 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210144456410.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210144550931.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210144550931.png new file mode 100644 index 0000000000000000000000000000000000000000..9876b43d2ec70e0fc49fcf4eb49cdf9cdabd7875 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210144550931.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210144929590.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210144929590.png new file mode 100644 index 0000000000000000000000000000000000000000..522f2de664428fb4b14ca15bc7bd6d6e8991ad2d Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251210144929590.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211152927056.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211152927056.png new file mode 100644 index 0000000000000000000000000000000000000000..8a9d671fa8b873ea127e93dd5225b91a4ffd72bc Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211152927056.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211152957548.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211152957548.png new file mode 100644 index 0000000000000000000000000000000000000000..1368a1f2d36a0eb1c78f0ec105254841e7013f7f Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211152957548.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211153103483.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211153103483.png new file mode 100644 index 0000000000000000000000000000000000000000..0de00e5a555459470395b4608b6c2ef5c6353580 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211153103483.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211154139537.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211154139537.png new file mode 100644 index 0000000000000000000000000000000000000000..ea5863808f7d8615c3409b822e193ab108ded781 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211154139537.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211154412633.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211154412633.png new file mode 100644 index 0000000000000000000000000000000000000000..dbce7d4ae6632fb56562eb51c3d7c41f483d5029 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211154412633.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211175415724.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211175415724.png new file mode 100644 index 0000000000000000000000000000000000000000..7b6e9b5c9400ba67b1892235b6959dc8a1bf8fa4 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211175415724.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211175441100.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211175441100.png new file mode 100644 index 0000000000000000000000000000000000000000..ae02e70f3fc75f407c907bf49cebd9ebaa67331c Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211175441100.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211180201322.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211180201322.png new file mode 100644 index 0000000000000000000000000000000000000000..03390664554e091447d014c5e9acfe1f903bf19f Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211180201322.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211180228172.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211180228172.png new file mode 100644 index 0000000000000000000000000000000000000000..6027d30f98176162a39d0a30b5ae069922e447b3 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211180228172.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211181607385.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211181607385.png new file mode 100644 index 0000000000000000000000000000000000000000..88ba22ebfb67beb7bae267c2f2f90fbda341af01 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251211181607385.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212095400354.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212095400354.png new file mode 100644 index 0000000000000000000000000000000000000000..667b7edd2a207233d92122d19a43d6a3340cd7c7 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212095400354.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212095543906.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212095543906.png new file mode 100644 index 0000000000000000000000000000000000000000..026782e42169e48498ee25eb472fe4019ff9526b Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212095543906.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212100003450.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212100003450.png new file mode 100644 index 0000000000000000000000000000000000000000..c38bdd49ccac606657b9ac3f89ec56cb481bf560 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212100003450.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212100058102.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212100058102.png new file mode 100644 index 0000000000000000000000000000000000000000..8517b77c9eae7736471db2982be1604e77511d1c Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212100058102.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212100126768.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212100126768.png new file mode 100644 index 0000000000000000000000000000000000000000..0385febd210ca90c0b395cac4c7f7caf76a29e0f Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212100126768.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212100155457.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212100155457.png new file mode 100644 index 0000000000000000000000000000000000000000..c963532be4416de23b341a9b21c378fe890b7804 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212100155457.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112622681.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112622681.png new file mode 100644 index 0000000000000000000000000000000000000000..7749720e4a463be27b765b86a00d4a5c76b5b57a Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112622681.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112653959.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112653959.png new file mode 100644 index 0000000000000000000000000000000000000000..2f33610c47b1a99f491d02908f8601c032e435d9 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112653959.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112744422.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112744422.png new file mode 100644 index 0000000000000000000000000000000000000000..098c8358bda01b1bc07b8553de0bcfd81bf68203 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112744422.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112826061.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112826061.png new file mode 100644 index 0000000000000000000000000000000000000000..94067a9729bbbb5d26ce52a5a20ff30f722fc49c Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112826061.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112835618.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112835618.png new file mode 100644 index 0000000000000000000000000000000000000000..6450267ab9ec2cd07a5445e15c7fcfdb3474c788 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112835618.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112953714.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112953714.png new file mode 100644 index 0000000000000000000000000000000000000000..6fa4fd230bdd10a71262e4e330e88744ed20e7a5 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212112953714.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113423571.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113423571.png new file mode 100644 index 0000000000000000000000000000000000000000..caa8e1cb13d2283e7045baf0fb661c8a8a79b969 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113423571.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113551339.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113551339.png new file mode 100644 index 0000000000000000000000000000000000000000..e0568a73f5eca78b9bcc80efbc27c43f9dc84f79 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113551339.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113802419.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113802419.png new file mode 100644 index 0000000000000000000000000000000000000000..95d4fb4ac8886415ec9bf76b493f1129672cfca7 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113802419.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113813746.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113813746.png new file mode 100644 index 0000000000000000000000000000000000000000..095e5acace732d8e2c3653601ab4da61fcdebd99 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113813746.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113848588.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113848588.png new file mode 100644 index 0000000000000000000000000000000000000000..aeecd7da0a3cafab84502ea836c34618afd83dd0 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212113848588.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160010400.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160010400.png new file mode 100644 index 0000000000000000000000000000000000000000..6bafd294e064ab939104f6f67842d2299dd9a65f Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160010400.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160132174.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160132174.png new file mode 100644 index 0000000000000000000000000000000000000000..0ee37ccf65952f91a3fd2b046ed9edbc30af2a1d Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160132174.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160136775.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160136775.png new file mode 100644 index 0000000000000000000000000000000000000000..5af9abd43ad2f643386f45e3d83d48e6181dce26 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160136775.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160157546.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160157546.png new file mode 100644 index 0000000000000000000000000000000000000000..9a14d335760bf5e1ed04eb8bdff0b79c46dc696b Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160157546.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160201187.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160201187.png new file mode 100644 index 0000000000000000000000000000000000000000..68594ad47b0a707e1b3435f4c49f6f2624f791fb Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160201187.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160428286.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160428286.png new file mode 100644 index 0000000000000000000000000000000000000000..f087c6914a96a19e53b9490713aef1c1201ef559 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160428286.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160502857.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160502857.png new file mode 100644 index 0000000000000000000000000000000000000000..4ce10e050a16a8275cc9c35919f83f6b684f911e Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160502857.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160751591.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160751591.png new file mode 100644 index 0000000000000000000000000000000000000000..2f424153380e38e8712ce75861a7521e1d08d50f Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160751591.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160821405.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160821405.png new file mode 100644 index 0000000000000000000000000000000000000000..7a4b88dc45dca9b12ba2c35b666df863dbdf46aa Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212160821405.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161122329.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161122329.png new file mode 100644 index 0000000000000000000000000000000000000000..2c82b27dc9afb3b2dcd3bc5fa77f575ab36365fe Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161122329.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161152653.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161152653.png new file mode 100644 index 0000000000000000000000000000000000000000..2d81ec499cd3360bf7262ffb2bf371d0250dd89f Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161152653.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161205916.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161205916.png new file mode 100644 index 0000000000000000000000000000000000000000..f344a32ea3e0881ead227d1652d74e436bab10bd Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161205916.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161326877.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161326877.png new file mode 100644 index 0000000000000000000000000000000000000000..8884e205eb0e80005c1d7cf4bf3e28a7f8cef02f Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161326877.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161459035.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161459035.png new file mode 100644 index 0000000000000000000000000000000000000000..c633a300b7d7ed1b20b0578ff6744fcebc337284 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161459035.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161510973.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161510973.png new file mode 100644 index 0000000000000000000000000000000000000000..6a8da73772bbe10459ab5cd83cbfc17c0fe70583 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161510973.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161518845.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161518845.png new file mode 100644 index 0000000000000000000000000000000000000000..022a56596110e3cae951a128f04ad9654f3f5187 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161518845.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161537286.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161537286.png new file mode 100644 index 0000000000000000000000000000000000000000..3869a9e8fb827622d5fc5292aaf273fba9849dcc Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161537286.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161545438.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161545438.png new file mode 100644 index 0000000000000000000000000000000000000000..c6e4a26ede878f8aea13174d090bb1196049b304 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161545438.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161556526.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161556526.png new file mode 100644 index 0000000000000000000000000000000000000000..50f052f6de3a247dbb7e8e1baa6d4f7737823096 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161556526.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161603853.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161603853.png new file mode 100644 index 0000000000000000000000000000000000000000..ad560f5d404c1d97c36e14db6c44cd4a4af6dbe5 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161603853.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161620444.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161620444.png new file mode 100644 index 0000000000000000000000000000000000000000..d8b769f588eaefb888cf265b28ede41ad49a3887 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161620444.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161626325.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161626325.png new file mode 100644 index 0000000000000000000000000000000000000000..5df7608bcbd14f845a9c859e65caaba451c45765 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161626325.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161659575.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161659575.png new file mode 100644 index 0000000000000000000000000000000000000000..3054a3e0e5ba045b9251dda2096326e2bfbea8f4 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161659575.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161736013.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161736013.png new file mode 100644 index 0000000000000000000000000000000000000000..8debb657d5a658919554eefc33d6d664a1e55c83 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161736013.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161754708.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161754708.png new file mode 100644 index 0000000000000000000000000000000000000000..08b529b93fdafa36bee32237452b365848aebe09 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161754708.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161802309.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161802309.png new file mode 100644 index 0000000000000000000000000000000000000000..bdb3c30a3fc518f7bf08df2dbb00923c073c97c4 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161802309.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161906870.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161906870.png new file mode 100644 index 0000000000000000000000000000000000000000..af40b5cc91cdc01eda4cea898aee7852d1d69db6 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212161906870.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162015669.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162015669.png new file mode 100644 index 0000000000000000000000000000000000000000..89f232d8c43c782241b11d0a25438a1b7af5ad2d Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162015669.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162402648.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162402648.png new file mode 100644 index 0000000000000000000000000000000000000000..b2eb16a019677f95694c952b4e9bf82207583544 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162402648.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162407485.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162407485.png new file mode 100644 index 0000000000000000000000000000000000000000..33801324235327d9cff5000d872dd46151a35091 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162407485.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162514086.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162514086.png new file mode 100644 index 0000000000000000000000000000000000000000..f6942bb2fb1d37503da8e6a2547a0d0b1773a053 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162514086.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162529270.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162529270.png new file mode 100644 index 0000000000000000000000000000000000000000..6560b101a06eab6d9f7cd01f6d66f4b179d17c31 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162529270.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162534477.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162534477.png new file mode 100644 index 0000000000000000000000000000000000000000..d08d4e682adb9f22ac7b50a22b60346ee23bd182 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162534477.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162537349.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162537349.png new file mode 100644 index 0000000000000000000000000000000000000000..e6df4fd307d185a3a1bb90d81e9f381667e201ba Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162537349.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162608398.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162608398.png new file mode 100644 index 0000000000000000000000000000000000000000..903da3b6d139b8e725f9bebc99ec9bfcf260589b Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162608398.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162620219.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162620219.png new file mode 100644 index 0000000000000000000000000000000000000000..207788af1775cef30ea6a7d32a1e4996b665a022 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162620219.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162622921.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162622921.png new file mode 100644 index 0000000000000000000000000000000000000000..9e7132139e4f1e225df2416faf98e0f62da9a750 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162622921.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162710073.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162710073.png new file mode 100644 index 0000000000000000000000000000000000000000..c3a7481a923d9adc4597a0ca1cf55e72a0a7c2ef Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162710073.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162730048.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162730048.png new file mode 100644 index 0000000000000000000000000000000000000000..ca6d42010a013ec61dbbddb15194e2c2d94c5bc3 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162730048.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162858438.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162858438.png new file mode 100644 index 0000000000000000000000000000000000000000..12196ff752fb4ffebffa2cdd7fc56ddc88b3420a Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162858438.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162905965.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162905965.png new file mode 100644 index 0000000000000000000000000000000000000000..ae3d6687dfacf4e15e0a573b47290783ac42b5b1 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162905965.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162918525.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162918525.png new file mode 100644 index 0000000000000000000000000000000000000000..ade28edf86109fc29bebf7d3d98bc5854cf53771 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212162918525.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163018588.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163018588.png new file mode 100644 index 0000000000000000000000000000000000000000..440f9c1cae2796ec4361e8536411e1f8ea27ea60 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163018588.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163050565.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163050565.png new file mode 100644 index 0000000000000000000000000000000000000000..b401f225baa30a55f163ca67791a3bfbeec5f51c Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163050565.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163139620.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163139620.png new file mode 100644 index 0000000000000000000000000000000000000000..54c22bf63e28155d4a79374220b458d6564fb9a2 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163139620.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163146427.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163146427.png new file mode 100644 index 0000000000000000000000000000000000000000..f04d0decedecfb532a22771eb9f2ab284be78609 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163146427.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163153727.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163153727.png new file mode 100644 index 0000000000000000000000000000000000000000..1a4845d01fad46ddca52ac44911113f3c2fafb27 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163153727.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163243997.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163243997.png new file mode 100644 index 0000000000000000000000000000000000000000..f6942bb2fb1d37503da8e6a2547a0d0b1773a053 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163243997.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163300535.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163300535.png new file mode 100644 index 0000000000000000000000000000000000000000..98b4ef801f6874f32172da17de3bab1f70e6ac66 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163300535.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163410944.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163410944.png new file mode 100644 index 0000000000000000000000000000000000000000..323d2f2f11636165f437a09710a3e3eb64324ec9 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163410944.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163446280.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163446280.png new file mode 100644 index 0000000000000000000000000000000000000000..1601ddc15bbc4593f320e3cee3ac1e4e1b59a818 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163446280.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163457762.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163457762.png new file mode 100644 index 0000000000000000000000000000000000000000..0ce88035c9e5bd97be2b9368a3f8b7d12723c13b Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212163457762.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212164611125.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212164611125.png new file mode 100644 index 0000000000000000000000000000000000000000..b22957395e94ac9c0a0e00dbbec473294678ce9d Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212164611125.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212164623182.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212164623182.png new file mode 100644 index 0000000000000000000000000000000000000000..450a4d64497bf785d37e587254fcf4461472956b Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212164623182.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212164941997.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212164941997.png new file mode 100644 index 0000000000000000000000000000000000000000..fe8f9c37badffd5261a01da3a0e9b916548bd130 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212164941997.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165151970.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165151970.png new file mode 100644 index 0000000000000000000000000000000000000000..1a4845d01fad46ddca52ac44911113f3c2fafb27 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165151970.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165204532.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165204532.png new file mode 100644 index 0000000000000000000000000000000000000000..ac20b1e0b113acf25ed0ec4902cad3a57751fe87 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165204532.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165447200.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165447200.png new file mode 100644 index 0000000000000000000000000000000000000000..a61e55e4382cdeff51a14cca204e02719217b617 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165447200.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165525437.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165525437.png new file mode 100644 index 0000000000000000000000000000000000000000..afaa610d9d970bebc423c72375c9457d9a69cbea Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165525437.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165530276.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165530276.png new file mode 100644 index 0000000000000000000000000000000000000000..284053bef40d693be1ed4291a3709d1cf189e73f Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165530276.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165535628.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165535628.png new file mode 100644 index 0000000000000000000000000000000000000000..9168fb73d4731f330ce29f1041275a8ff4ef9425 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165535628.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165538820.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165538820.png new file mode 100644 index 0000000000000000000000000000000000000000..a040a359c02e3a6171581fba6abacf1920311487 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165538820.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165545957.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165545957.png new file mode 100644 index 0000000000000000000000000000000000000000..50f052f6de3a247dbb7e8e1baa6d4f7737823096 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165545957.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165600556.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165600556.png new file mode 100644 index 0000000000000000000000000000000000000000..ad560f5d404c1d97c36e14db6c44cd4a4af6dbe5 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165600556.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165615348.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165615348.png new file mode 100644 index 0000000000000000000000000000000000000000..31a3db07f205e7c0f4532aefea8da163d0f0aebe Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165615348.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165749902.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165749902.png new file mode 100644 index 0000000000000000000000000000000000000000..fac9668a73ffb4acd5fd409035f92dffa477c698 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165749902.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165808941.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165808941.png new file mode 100644 index 0000000000000000000000000000000000000000..e711d74627994693dac4e507e13d08ab6bd063ed Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165808941.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165833789.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165833789.png new file mode 100644 index 0000000000000000000000000000000000000000..fac9668a73ffb4acd5fd409035f92dffa477c698 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165833789.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165836973.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165836973.png new file mode 100644 index 0000000000000000000000000000000000000000..a1c27b1663a212f018911dcc120d624804b9ed42 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165836973.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165840316.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165840316.png new file mode 100644 index 0000000000000000000000000000000000000000..6a7ecc4d80d8e1641817970635c57f5c070b99a0 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165840316.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165843110.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165843110.png new file mode 100644 index 0000000000000000000000000000000000000000..b0ee50d865a7c07199fbb644ddb7adc322079503 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165843110.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165905257.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165905257.png new file mode 100644 index 0000000000000000000000000000000000000000..e711d74627994693dac4e507e13d08ab6bd063ed Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251212165905257.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215100207813.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215100207813.png new file mode 100644 index 0000000000000000000000000000000000000000..b7657986cad18522ca0415e2861cd5803d8c14f8 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215100207813.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215100216382.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215100216382.png new file mode 100644 index 0000000000000000000000000000000000000000..674a95a29374d0fe462f6fa5f6474cc0839c1b01 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215100216382.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101353923.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101353923.png new file mode 100644 index 0000000000000000000000000000000000000000..5e2ee27a8ca96f77f404413f631068dedd57542b Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101353923.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101410857.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101410857.png new file mode 100644 index 0000000000000000000000000000000000000000..e12bb1856a12fdb9b8dd74304ea74a86d6626538 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101410857.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101420450.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101420450.png new file mode 100644 index 0000000000000000000000000000000000000000..9ab2ac871409a5350cd9da6e54ac90d8e172a7d2 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101420450.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101633222.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101633222.png new file mode 100644 index 0000000000000000000000000000000000000000..01d5bce446cb5ff4f0041663f89dbbd84c7e6a19 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101633222.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101804370.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101804370.png new file mode 100644 index 0000000000000000000000000000000000000000..dcf9f3d549c592cd15fd767b3f68c13e0c46e9e6 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101804370.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101831843.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101831843.png new file mode 100644 index 0000000000000000000000000000000000000000..bf0c3aede6095172c573961cfd9c3d3de7bb8ccd Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101831843.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101845234.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101845234.png new file mode 100644 index 0000000000000000000000000000000000000000..3066c2c968c0b3091dd1e8d2d6be1d2719be75b9 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101845234.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101855106.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101855106.png new file mode 100644 index 0000000000000000000000000000000000000000..793210e3151488a79afb0d36a0c3284b96c052ef Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215101855106.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215103254350.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215103254350.png new file mode 100644 index 0000000000000000000000000000000000000000..470ac9d93405ce70c09b1d4f228702ed0be74c54 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215103254350.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215103758113.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215103758113.png new file mode 100644 index 0000000000000000000000000000000000000000..629bbac53cd0df2fa3f33221cf676e4330112b88 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215103758113.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215103827695.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215103827695.png new file mode 100644 index 0000000000000000000000000000000000000000..86d3c1063e57564c185a87bbd67d7d256531ac5a Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215103827695.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215104211581.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215104211581.png new file mode 100644 index 0000000000000000000000000000000000000000..1d2ec8918d5b0b5763ee78416b856816bc07040b Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215104211581.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215104447514.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215104447514.png new file mode 100644 index 0000000000000000000000000000000000000000..343cd512b31248c74075c452b6c3e67c407d0704 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215104447514.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215104524912.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215104524912.png new file mode 100644 index 0000000000000000000000000000000000000000..0271f424def4b46216c27182041d83e4da318193 Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215104524912.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215104811951.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215104811951.png new file mode 100644 index 0000000000000000000000000000000000000000..47afdbe17012635eccc17b9645231e1a465ea69e Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215104811951.png differ diff --git a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215144255184.png b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215144255184.png new file mode 100644 index 0000000000000000000000000000000000000000..e02db6a6972352e7e1e481f924e9f530451ca1ec Binary files /dev/null and b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/figures/image-20251215144255184.png differ diff --git "a/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/\345\257\214\347\200\232\345\276\256FH8626V300L\345\274\200\345\217\221\345\256\236\350\267\265\346\214\207\345\215\227.md" "b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/\345\257\214\347\200\232\345\276\256FH8626V300L\345\274\200\345\217\221\345\256\236\350\267\265\346\214\207\345\215\227.md" new file mode 100644 index 0000000000000000000000000000000000000000..da713eadd53923f0faf3c9ecd123ba09bc396325 --- /dev/null +++ "b/rt-thread-version/rt-thread-standard/tutorial/make-bsp/fullhan/\345\257\214\347\200\232\345\276\256FH8626V300L\345\274\200\345\217\221\345\256\236\350\267\265\346\214\207\345\215\227.md" @@ -0,0 +1,7075 @@ +# 富瀚微FH8626V300L开发实践指南 + +| **目录** | **作者** | +| ------------------------------------- | ---------------------- | +| **零、实践指南说明** | **RT-Thread & 富瀚微** | +| **一、FH8626V300L上的GPIO实践** | **RT-Thread & 富瀚微** | +| **二、FH8626V300L上的UART实践** | **RT-Thread & 富瀚微** | +| **三、FH8626V300L上的PWM实践** | **RT-Thread & 富瀚微** | +| **四、FH8626V300L上的SADC实践** | **RT-Thread & 富瀚微** | +| **五、FH8626V300L上的SPI实践** | **RT-Thread & 富瀚微** | +| **六、FH8626V300L上的WDT实践** | **RT-Thread & 富瀚微** | +| **七、FH8626V300L上的SDIO实践** | **RT-Thread & 富瀚微** | +| **八、FH8626V300L上的ETH实践** | **RT-Thread & 富瀚微** | +| **九、FH8626V300L上的AUDIO实践** | **RT-Thread & 富瀚微** | +| **十、FH8626V300L上的AES实践** | **RT-Thread & 富瀚微** | +| **十一、FH8626V300L上的USB_HID实践** | **RT-Thread & 富瀚微** | +| **十二、FH8626V300L上的USB_VCOM实践** | **RT-Thread & 富瀚微** | +| **十三、常电双路摄像头应用方案** | **RT-Thread & 富瀚微** | +| **十四、双路人形检测方案** | **RT-Thread & 富瀚微** | +| **十五、低功耗AOV双路智能方案** | **RT-Thread & 富瀚微** | +| **FAQ** | **RT-Thread & 富瀚微** | + +# 零、实践指南说明 + +## 1. 硬件介绍 + +1. **开发板描述**:H8626V300L 是一款面向智能高清网络摄像机应用的高性能 SoC 芯片,该芯片集成了高性能双路1080P@15FPS新一代3D降噪ISP图像处理模块和H.264视频压缩编码模块,集成高能效比的0.5T算力人工智能处理引擎,具备优异的图像处理能力、极高的编码质量和智能处理能力。同时芯片内部集成了512MbitDDR2存储器,采用双核异构(700MHz+450MHz), 支持MJPEG/JPEG baseline 2x(2304x1296@10fps+640x480@10fps) 编码。该方案具有高效节能、低照度高清晰度的能力。不仅拥有领先的AOV低功耗技术,其双路视频处理与显示能力也为复杂应用场景提供了强大支持。 + +![img](figures/O1CN01Xuo16b1NmLYIjS4IRcrop,0,0,1279,2558_!!1817661612.jpg) + +2. **开发板外观如下图所示**: + +![image-20251215144255184](figures/image-20251215144255184.png) + +3. 该开发板常用**板载资源**如下 + +- MCU 型号:FH8626V300L +- 主频:主核 700 MHz、副核 480MHz +- Flash:7.5MB Flash(含2MB零等待Code-Flash) +- SRAM:1MB SRAM(全空间ECC校验) +- 外设支持:ADC、多通道 SPI/I2C/UART/PWM、I2S、USB、SDIO、DMA、RTC、ETH 等 + +![img](figures/O1CN01hIw9xM1NmLXlLIu37_!!1817661612.png) + +## 2. 应用方案 + +![img](figures/O1CN01xPZILE1NmLXnIQTCx_!!1817661612.png) + +![img](figures/O1CN01vtJ7Fi1NmLXmOmoeA_!!1817661612.png) + +![img](figures/O1CN01QkWfI31NmLXlmZ9Ko_!!1817661612.png) + +![img](figures/O1CN017ayJ2N1NmLXmlmoA1_!!1817661612.png) + +![img](figures/O1CN01kSw0wt1NmLXnyfnH9_!!1817661612.png) + +![img](figures/O1CN01DgA3HQ1NmLXmgFHsW_!!1817661612.png) + +![img](figures/O1CN01jFF6B81NmLXnIMhUN_!!1817661612.png) + +**我有疑问:**[**RT-Thread 官方论坛**](https://gitee.com/link?target=https%3A%2F%2Fclub.rt-thread.org) + +# 一、FH8626V300L上的GPIO实践 + +## 1. 前置准备 + +### 1.1 硬件准备 + +**包含**:串口线、FH8626V300L开发板、电源线、网线。(本章用不到 Sensor 摄像头板) + +![image-20251205171346094](figures/image-20251205171346094.png) + +### 1.2 软件准备 + +**进入 SDK 的 rt-thread 目录** + +![image-20251205155037769](figures/image-20251205155037769.png) + +**应用初始配置** + +在终端中输入如下命令进行初始配置: + +```bash +make fh8626v300_defconfig +``` + +![image-20251205155257034](figures/image-20251205155257034.png) + +**使能GPIO外设** + +在终端中输入如下命令使用图形化界面配置工程 + +```bash +make menuconfig +``` + +进入 Drivers 配置项。 + +![image-20251205162223990](figures/image-20251205162223990.png) + +使能 GPIO。 + +![image-20251208105347276](figures/image-20251208105347276.png) + +选择 app demo 为 bsp_demo。 + +![image-20251205165833376](figures/image-20251205165833376.png) + +保存配置。 + +![image-20251205162418489](figures/image-20251205162418489.png) + +**进入 bsp_demo 目录** + +在终端中输入如下命令使用 VSCode 打开目前所在的目录 + +```bash +code . +``` + +bsp_demo 目录结构如下图所示: + +![image-20251205155758476](figures/image-20251205155758476.png) + +## 2. 查看原理图 + +开发板原理图路径为 `FH8626V300_RT_V1.0.0_20250627/docs_tools/hardware/board/FH8626V300L_QFN80_APP_BOARD_V1.pdf` 。 + +在原理图中找到 GPIO3 的引脚如下图: + +![image-20251208114050564](figures/image-20251208114050564.png) + +在开发板上的位置如下: + +![image-20251208114201438](figures/image-20251208114201438.png) + +将 JP28 座子上的跳线帽取下,杜邦线连接到 2 号引脚上。 + +## 3. 配置 PinMux + +**PIN 引脚复用需要注意不能冲突,否则会导致复用不生效。** + +PIN 引脚复用可查看 PinMux 表格或 fh8626v300_iopad.h 文件。 + +* PinMux 表格:`FH8626V300_RT_V1.0.0_20250627/docs_tools/hardware/board/FH8626V300L_PIN_MUX.xlsm` + +* fh8626v300_iopad.h 文件:`FH8626V300_RT_V1.0.0_20250627/rt-thread/platform/fh8626v300/fh8626v300_iopad.h` + +修改 `FH8626V300_RT_V1.0.0_20250627/rt-thread/platform/fh8626v300/app_board/appboard_iopad.h` 文件,在 `*fh_pinctrl_selected_devices[]`数组中添加 "GPIO3"。 + +```c +#ifndef __APP_IOPAD_H__ +#define __APP_IOPAD_H__ + +char *fh_pinctrl_selected_devices[] = { + /* CONFIG_PINCTRL_SELECT */ + "SADC_IN0", "SADC_IN1", "SPI0_4BIT", + "PWM6", "UART0", "UART1", "GPIO28", "GPIO40", + "GPIO49", "GPIO62", "GPIO63", "MIPI", "GPIO3", +#ifdef WIFI_USING_SDIOWIFI +#if (WIFI_SDIO == 0) +"SD0_WIFI", "GPIO25" +#else +"SD0_NO_WP" +#endif +#else +"SD0_NO_WP" +#endif +}; + +char *fh_pinctrl_selected_aon_devices[] = { + /* CONFIG_PINCTRL_SELECT */ + "I2C0", "SENSOR0_VS", "SENSOR1_VS", "SENSOR_CLK", + "GPIO14", + + "GPIO6", "GPIO7", "GPIO8", "GPIO9" +}; + +#endif +``` + +## 4. 修改 bsp_demo + +打开 `bsp_demo/startup/application.c` 文件,删除 `user_main()` 中的代码,修改测试方式为手动执行。 + +```c +#include +#include +#include + +#include "rttshell.h" + +extern void sadc_demo_init(void); +extern int sdcard_demo_init(void); +extern int aes_demo_init(void); +extern int pwm_demo_init(void); +extern int gpio_demo_init(void); +extern int uart_demo_init(void); +extern int i2c_demo_init(void); +extern int rtc_demo_init(void); + +void user_main(void) +{ +} + +static void bsp_demo_usage(void) +{ + printf("Usage:\n"); + printf(" bsp_demo -e: run aes demo\n"); + printf(" bsp_demo -t: run rtc demo\n"); + printf(" bsp_demo -i: run i2c demo\n"); + printf(" bsp_demo -a: run sadc demo\n"); + printf(" bsp_demo -p: run pwm demo\n"); + printf(" bsp_demo -g: run gpio demo\n"); + printf(" bsp_demo -u: run uart demo\n"); + printf(" bsp_demo -c: run sdcard demo\n"); +} + +static void bsp_demo(int argc, char *argv[]) +{ + if (argc < 2) + { + bsp_demo_usage(); + return; + } + if (strcmp(argv[1], "-e") == 0) + { + aes_demo_init(); + } + else if (strcmp(argv[1], "-u") == 0) + { + uart_demo_init(); + } + else if (strcmp(argv[1], "-g") == 0) + { + gpio_demo_init(); + } + else if (strcmp(argv[1], "-p") == 0) + { + pwm_demo_init(); + } + else if (strcmp(argv[1], "-c") == 0) + { + sdcard_demo_init(); + } + else if (strcmp(argv[1], "-a") == 0) + { + sadc_demo_init(); + } + else if (strcmp(argv[1], "-t") == 0) + { + rtc_demo_init(); + } + else if (strcmp(argv[1], "-i") == 0) + { + i2c_demo_init(); + } + else + { + bsp_demo_usage(); + } +} +SHELL_CMD_EXPORT(bsp_demo, bsp demo) +``` + +## 5. 修改 GPIO 代码 + +修改 `bsp_demo/gpio/gpio_demo.c` 。 + +```c +#include +#include +#include +#include +#include +#include + +#include "gpio.h" + +/* + * function: gpio trig led blink + * gpio_num: which gpio to light + * + * 功能:让指定的 GPIO 引脚周期性翻转,从而实现 LED 闪烁效果。 + * 参数:gpio_num —— 要控制的 GPIO 引脚编号。 + */ +static int gpio_blink(unsigned int gpio_num) +{ + int status; + int toggle = 0; + + /* 设置当前线程名称,方便调试 */ + prctl(PR_SET_NAME, "gpio_blink"); + /* 打印当前测试的 GPIO 信息 */ + printf("[gpio_demo] Testing gpio %d for %s\n", gpio_num, "output"); + /* 请求控制该 GPIO */ + status = gpio_request(gpio_num); + if (status < 0) + { + printf("[gpio_demo] ERROR can not open GPIO %d\n", gpio_num); + return status; + } + + /* 设置 GPIO 为输出方向,并默认输出低电平(0) */ + gpio_direction_output(gpio_num, 0); + /* 获取当前 GPIO 电平,作为初始状态 */ + toggle = gpio_get_value(gpio_num); + /* 无限循环:持续翻转 GPIO 电平,实现闪烁效果 */ + while (1) + { + /* 翻转电平 */ + toggle = !(toggle); + /* 设置新的 GPIO 电平 */ + gpio_set_value(gpio_num, toggle); + /* 延时 100ms */ + usleep(100000); + /* 读取实际 GPIO 值,确认是否设置成功 */ + if (gpio_get_value(gpio_num) != toggle) + { + return -1; + } + } + return 0; +} + +/* + * gpio_blink_main + * 线程入口函数,内部只闪烁 GPIO3 + */ +static void *gpio_blink_main(void *parameter) +{ + gpio_blink(3); + return NULL; +} + +/* + * gpio_demo_init + * 初始化 GPIO Demo: + * - 创建一个独立线程去闪烁 GPIO3 + */ +int gpio_demo_init(void) +{ + int ret; + pthread_t threadBlink; + pthread_attr_t Battr; + + /* 初始化线程属性结构体 */ + pthread_attr_init(&Battr); + /* 设置线程为分离状态(detached)*/ + pthread_attr_setdetachstate(&Battr, PTHREAD_CREATE_DETACHED); + /* 设置线程栈大小 */ + pthread_attr_setstacksize(&Battr, 10 * 1024); + /* 创建线程,运行 gpio_blink_main */ + ret = pthread_create(&threadBlink, &Battr, gpio_blink_main, NULL); + if(ret) + { + printf("[gpio_demo] Error: Create gpio_blink_main thread failed!\n"); + return -1; + } + + return 0; +} +``` + +## 6. 编译代码 + +输入如下命令开始编译代码: + +```bash +make clean;make +``` + +![image-20251205165931584](figures/image-20251205165931584.png) + +编译结果如下图: + +在 `bsp_demo/out/bin/` 中生成了 bsp_demo.bin 固件。 + +![image-20251205170009227](figures/image-20251205170009227.png) + +## 7. 烧录固件 + +将编译生成的 bsp_demo.bin 固件复制到共享文件夹中。 + +### 7.1 进入 uboot + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +**Hit any key to stop autoboot** + +![image-20251205171847725](figures/image-20251205171847725.png) + +### 7.2 查看设备 IP + +输入下述命令查看当前的信息 + +```bahs +pri +``` + +输出内容如下: + +![image-20251205172033034](figures/image-20251205172033034.png) + +输入下述命令进行IP配置: + +```bash +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +```bash +saveenv +``` + +配置电脑IP地址: + +![image-20251205172122432](figures/image-20251205172122432.png) + +开启 tftp: + +![image-20251205172133756](figures/image-20251205172133756.png) + +### 7.3 烧录主处理器固件 + +加载应用固件,出现下述内容则表示加载成功: + +```bash +tftp 10000000 bsp_demo.bin +``` + +![image-20251205172520750](figures/image-20251205172520750.png) + +然后输入下述命令进行准备: + +```bash +go 10000000 +``` + +**停顿一下,敲enter键,出现:msh />,再去执行后续操作:** + +![image-20251205172310038](figures/image-20251205172310038.png) + +## 8. 测试 GPIO + +在 shell 中输入 `pinctrl -l` 命令可以查看引脚复用情况: + +![image-20251208112256760](figures/image-20251208112256760.png) + +输入 `bsp_demo -g` 开始 gpio 测试: + +![image-20251208113115015](figures/image-20251208113115015.png) + +# 二、FH8626V300L上的UART实践 + +## 1. 前置准备 + +### 1.1 硬件准备 + +**包含**:串口线、FH8626V300L开发板、电源线、网线。(本章用不到 Sensor 摄像头板) + +![image-20251205171346094](figures/image-20251205171346094.png) + +### 1.2 软件准备 + +**进入 SDK 的 rt-thread 目录** + +![image-20251205155037769](figures/image-20251205155037769.png) + +**应用初始配置** + +在终端中输入如下命令进行初始配置: + +```bash +make fh8626v300_defconfig +``` + +![image-20251205155257034](figures/image-20251205155257034.png) + +**使能 UART1 外设** + +在终端中输入如下命令使用图形化界面配置工程 + +```bash +make menuconfig +``` + +进入 Drivers 配置项。 + +![image-20251205162223990](figures/image-20251205162223990.png) + +进入 Choose uart device 配置项。 + +![image-20251208115405504](figures/image-20251208115405504.png) + +使能 UART1。 + +![image-20251208115456155](figures/image-20251208115456155.png) + +选择 app demo 为 bsp_demo。 + +![image-20251205165833376](figures/image-20251205165833376.png) + +保存配置。 + +![image-20251205162418489](figures/image-20251205162418489.png) + +**进入 bsp_demo 目录** + +在终端中输入如下命令使用 VSCode 打开目前所在的目录 + +```bash +code . +``` + +bsp_demo 目录结构如下图所示: + +![image-20251205155758476](figures/image-20251205155758476.png) + +## 2. 查看原理图 + +开发板原理图路径为 `FH8626V300_RT_V1.0.0_20250627/docs_tools/hardware/board/FH8626V300L_QFN80_APP_BOARD_V1.pdf` 。 + +在原理图中找到 UART1 的引脚如下图: + +![image-20251208115753622](figures/image-20251208115753622.png) + +在开发板上的位置如下: + +![image-20251208115824560](figures/image-20251208115824560.png) + +## 3. 配置 PinMux + +**PIN 引脚复用需要注意不能冲突,否则会导致复用不生效。** + +PIN 引脚复用可查看 PinMux 表格或 fh8626v300_iopad.h 文件。 + +* PinMux 表格:`FH8626V300_RT_V1.0.0_20250627/docs_tools/hardware/board/FH8626V300L_PIN_MUX.xlsm` + +* fh8626v300_iopad.h 文件:`FH8626V300_RT_V1.0.0_20250627/rt-thread/platform/fh8626v300/fh8626v300_iopad.h` + +修改 `FH8626V300_RT_V1.0.0_20250627/rt-thread/platform/fh8626v300/app_board/appboard_iopad.h` 文件,在 `*fh_pinctrl_selected_devices[]`数组中添加 "UART1"。 + +```c +#ifndef __APP_IOPAD_H__ +#define __APP_IOPAD_H__ + +char *fh_pinctrl_selected_devices[] = { + /* CONFIG_PINCTRL_SELECT */ + "SADC_IN0", "SADC_IN1", "SPI0_4BIT", + "PWM6", "UART0", "UART1", "GPIO28", "GPIO40", + "GPIO49", "GPIO62", "GPIO63", "MIPI", +#ifdef WIFI_USING_SDIOWIFI +#if (WIFI_SDIO == 0) +"SD0_WIFI", "GPIO25" +#else +"SD0_NO_WP" +#endif +#else +"SD0_NO_WP" +#endif +}; + +char *fh_pinctrl_selected_aon_devices[] = { + /* CONFIG_PINCTRL_SELECT */ + "I2C0", "SENSOR0_VS", "SENSOR1_VS", "SENSOR_CLK", + "GPIO14", + + "GPIO6", "GPIO7", "GPIO8", "GPIO9" +}; + +#endif +``` + +## 4. 修改 bsp_demo + +打开 `bsp_demo/startup/application.c` 文件,删除 `user_main()` 中的代码,修改测试方式为手动执行。 + +```c +#include +#include +#include + +#include "rttshell.h" + +extern void sadc_demo_init(void); +extern int sdcard_demo_init(void); +extern int aes_demo_init(void); +extern int pwm_demo_init(void); +extern int gpio_demo_init(void); +extern int uart_demo_init(void); +extern int i2c_demo_init(void); +extern int rtc_demo_init(void); + +void user_main(void) +{ +} + +static void bsp_demo_usage(void) +{ + printf("Usage:\n"); + printf(" bsp_demo -e: run aes demo\n"); + printf(" bsp_demo -t: run rtc demo\n"); + printf(" bsp_demo -i: run i2c demo\n"); + printf(" bsp_demo -a: run sadc demo\n"); + printf(" bsp_demo -p: run pwm demo\n"); + printf(" bsp_demo -g: run gpio demo\n"); + printf(" bsp_demo -u: run uart demo\n"); + printf(" bsp_demo -c: run sdcard demo\n"); +} + +static void bsp_demo(int argc, char *argv[]) +{ + if (argc < 2) + { + bsp_demo_usage(); + return; + } + if (strcmp(argv[1], "-e") == 0) + { + aes_demo_init(); + } + else if (strcmp(argv[1], "-u") == 0) + { + uart_demo_init(); + } + else if (strcmp(argv[1], "-g") == 0) + { + gpio_demo_init(); + } + else if (strcmp(argv[1], "-p") == 0) + { + pwm_demo_init(); + } + else if (strcmp(argv[1], "-c") == 0) + { + sdcard_demo_init(); + } + else if (strcmp(argv[1], "-a") == 0) + { + sadc_demo_init(); + } + else if (strcmp(argv[1], "-t") == 0) + { + rtc_demo_init(); + } + else if (strcmp(argv[1], "-i") == 0) + { + i2c_demo_init(); + } + else + { + bsp_demo_usage(); + } +} +SHELL_CMD_EXPORT(bsp_demo, bsp demo) +``` + +## 5. 修改 UART 代码 + +修改 `bsp_demo/uart/uart_demo.c` 。 + +```c +#include +#include +#include +#include +#include +#include + +static int uart_fd = -1; + +/** + * @brief UART 读写函数 + * + * 连续执行 50 次: + * 1. 从 UART 设备读 1 字节到 buf + * 2. 打印读取的数据 + * 3. 再把这个字节写回 UART(回显) + */ +void uart_func(void) +{ + int i = 50; + char buf = 0x31; // 初始内容为字符 '1' + + while(i--) + { + /* 从 UART 设备读取 1 字节 */ + read(uart_fd, &buf, 1); + /* 打印读取的数据(以十六进制形式 */ + printf("[uart_demo] buf:%x\n", buf); + /* 将读取到的数据再写回 UART(回显功能)*/ + write(uart_fd, &buf, 1); + } +} + +/** + * @brief UART demo 线程主函数 + * + * 设置当前线程名字为 "uart demo",然后执行 uart_func() + */ +void *uart_demo_main(void *param) +{ + prctl(PR_SET_NAME, "uart demo"); // 设置线程名称 + + uart_func(); + + return NULL; +} + +/** + * @brief UART demo 初始化函数 + * + * 主要功能: + * 1. 初始化 pthread 属性(分离模式、栈大小 10 KB) + * 2. 打开 UART1 设备 + * 3. 创建一个独立线程运行 uart_demo_main() + */ +int uart_demo_init(void) +{ + int ret = 0; + + pthread_t threadUart; + pthread_attr_t attr; + + /* 初始化线程属性 */ + pthread_attr_init(&attr); + /* 设置线程为分离状态,线程结束后自动释放资源 */ + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + /* 设置线程栈大小 */ + pthread_attr_setstacksize(&attr, 10 * 1024); + /* 打开 UART1 设备,读写模式 */ + uart_fd = open("/dev/uart1", O_RDWR); + if(uart_fd < 0) + { + printf("[uart_demo] open uart1 failed\n"); + + return -1; + } + /* 创建 UART demo 线程 */ + ret = pthread_create(&threadUart, &attr, uart_demo_main, NULL); + if(ret) + { + printf("[uart_demo] Error: Create uart_demo_main thread failed!\n"); + return -1; + } + + return 0; +} +``` + +## 6. 编译代码 + +输入如下命令开始编译代码: + +```bash +make clean;make +``` + +![image-20251205165931584](figures/image-20251205165931584.png) + +编译结果如下图: + +在 `bsp_demo/out/bin/` 中生成了 bsp_demo.bin 固件。 + +![image-20251205170009227](figures/image-20251205170009227.png) + +## 7. 烧录固件 + +将编译生成的 bsp_demo.bin 固件复制到共享文件夹中。 + +### 7.1 进入 uboot + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +**Hit any key to stop autoboot** + +![image-20251205171847725](figures/image-20251205171847725.png) + +### 7.2 查看设备 IP + +输入下述命令查看当前的信息 + +```bahs +pri +``` + +输出内容如下: + +![image-20251205172033034](figures/image-20251205172033034.png) + +输入下述命令进行IP配置: + +```bash +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +```bash +saveenv +``` + +配置电脑IP地址: + +![image-20251205172122432](figures/image-20251205172122432.png) + +开启 tftp: + +![image-20251205172133756](figures/image-20251205172133756.png) + +### 7.3 烧录主处理器固件 + +加载应用固件,出现下述内容则表示加载成功: + +```bash +tftp 10000000 bsp_demo.bin +``` + +![image-20251205172520750](figures/image-20251205172520750.png) + +然后输入下述命令进行准备: + +```bash +go 10000000 +``` + +**停顿一下,敲enter键,出现:msh />,再去执行后续操作:** + +![image-20251205172310038](figures/image-20251205172310038.png) + +## 8. 测试 UART + +在 shell 中输入 `ls /dev` 命令查看启用的外设: + +![image-20251208132210504](figures/image-20251208132210504.png) + +在 shell 中输入 `pinctrl -l` 命令可以查看引脚复用情况: + +![image-20251208132247810](figures/image-20251208132247810.png) + +输入 `bsp_demo -u` 开始 uart 测试: + +使用串口助手打开连接 uart1 的串口,发送 "abc123"。 + +![image-20251208132817185](figures/image-20251208132817185.png) + +开发板端的 shell 终端会打印出接收到的字符的十六进制值。 + +![image-20251208132641846](figures/image-20251208132641846.png) + +# 三、FH8626V300L上的PWM实践 + +## 1. 前置准备 + +### 1.1 硬件准备 + +**包含**:串口线、FH8626V300L开发板、电源线、网线。(本章用不到 Sensor 摄像头板) + +![image-20251205171346094](figures/image-20251205171346094.png) + +### 1.2 软件准备 + +**进入 SDK 的 rt-thread 目录** + +![image-20251205155037769](figures/image-20251205155037769.png) + +**应用初始配置** + +在终端中输入如下命令进行初始配置: + +```bash +make fh8626v300_defconfig +``` + +![image-20251205155257034](figures/image-20251205155257034.png) + +**使能PWM外设** + +在终端中输入如下命令使用图形化界面配置工程 + +```bash +make menuconfig +``` + +进入 Drivers 配置项。 + +![image-20251205162223990](figures/image-20251205162223990.png) + +使能 PWM。 + +![image-20251205162259628](figures/image-20251205162259628.png) + +选择 app demo 为 bsp_demo。 + +![image-20251205165833376](figures/image-20251205165833376.png) + +保存配置。 + +![image-20251205162418489](figures/image-20251205162418489.png) + +**进入 bsp_demo 目录** + +在终端中输入如下命令使用 VSCode 打开目前所在的目录 + +```bash +code . +``` + +bsp_demo 目录结构如下图所示: + +![image-20251205155758476](figures/image-20251205155758476.png) + +## 2. 查看原理图 + +开发板原理图路径为 `FH8626V300_RT_V1.0.0_20250627/docs_tools/hardware/board/FH8626V300L_QFN80_APP_BOARD_V1.pdf` 。 + +在原理图中找到 PWM6 的引脚如下图: + +![image-20251205160903391](figures/image-20251205160903391.png) + +在开发板上的位置如下: + +![image-20251205180152259](figures/image-20251205180152259.png) + +将 JP16 座子上的跳线帽取下,杜邦线连接到 2 号引脚上。 + +## 3. 配置 PinMux + +**PIN 引脚复用需要注意不能冲突,否则会导致复用不生效。** + +PIN 引脚复用可查看 PinMux 表格或 fh8626v300_iopad.h 文件。 + +* PinMux 表格:`FH8626V300_RT_V1.0.0_20250627/docs_tools/hardware/board/FH8626V300L_PIN_MUX.xlsm` + +* fh8626v300_iopad.h 文件:`FH8626V300_RT_V1.0.0_20250627/rt-thread/platform/fh8626v300/fh8626v300_iopad.h` + +修改 `FH8626V300_RT_V1.0.0_20250627/rt-thread/platform/fh8626v300/app_board/appboard_iopad.h` 文件,在 `*fh_pinctrl_selected_devices[]`数组中删除 "STM0" 和 "STM1",并添加 "PWM6"。 + +```c +#ifndef __APP_IOPAD_H__ +#define __APP_IOPAD_H__ + +char *fh_pinctrl_selected_devices[] = { + /* CONFIG_PINCTRL_SELECT */ + "SADC_IN0", "SADC_IN1", "SPI0_4BIT", + "PWM6", "UART0", "UART1", "GPIO28", "GPIO40", + "GPIO49", "GPIO62", "GPIO63", "MIPI", +#ifdef WIFI_USING_SDIOWIFI +#if (WIFI_SDIO == 0) +"SD0_WIFI", "GPIO25" +#else +"SD0_NO_WP" +#endif +#else +"SD0_NO_WP" +#endif +}; + +char *fh_pinctrl_selected_aon_devices[] = { + /* CONFIG_PINCTRL_SELECT */ + "I2C0", "SENSOR0_VS", "SENSOR1_VS", "SENSOR_CLK", + "GPIO14", + + "GPIO6", "GPIO7", "GPIO8", "GPIO9" +}; + +#endif +``` + +## 4. 修改 bsp_demo + +打开 `bsp_demo/startup/application.c` 文件,删除 `user_main()` 中的代码,修改测试方式为手动执行。 + +```c +#include +#include +#include + +#include "rttshell.h" + +extern void sadc_demo_init(void); +extern int sdcard_demo_init(void); +extern int aes_demo_init(void); +extern int pwm_demo_init(void); +extern int gpio_demo_init(void); +extern int uart_demo_init(void); +extern int i2c_demo_init(void); +extern int rtc_demo_init(void); + +void user_main(void) +{ +} + +static void bsp_demo_usage(void) +{ + printf("Usage:\n"); + printf(" bsp_demo -e: run aes demo\n"); + printf(" bsp_demo -t: run rtc demo\n"); + printf(" bsp_demo -i: run i2c demo\n"); + printf(" bsp_demo -a: run sadc demo\n"); + printf(" bsp_demo -p: run pwm demo\n"); + printf(" bsp_demo -g: run gpio demo\n"); + printf(" bsp_demo -u: run uart demo\n"); + printf(" bsp_demo -c: run sdcard demo\n"); +} + +static void bsp_demo(int argc, char *argv[]) +{ + if (argc < 2) + { + bsp_demo_usage(); + return; + } + if (strcmp(argv[1], "-e") == 0) + { + aes_demo_init(); + } + else if (strcmp(argv[1], "-u") == 0) + { + uart_demo_init(); + } + else if (strcmp(argv[1], "-g") == 0) + { + gpio_demo_init(); + } + else if (strcmp(argv[1], "-p") == 0) + { + pwm_demo_init(); + } + else if (strcmp(argv[1], "-c") == 0) + { + sdcard_demo_init(); + } + else if (strcmp(argv[1], "-a") == 0) + { + sadc_demo_init(); + } + else if (strcmp(argv[1], "-t") == 0) + { + rtc_demo_init(); + } + else if (strcmp(argv[1], "-i") == 0) + { + i2c_demo_init(); + } + else + { + bsp_demo_usage(); + } +} +SHELL_CMD_EXPORT(bsp_demo, bsp demo) +``` + +## 5. 修改 PWM 代码 + +修改 `bsp_demo/pwm/pwm_demo.c` 。 + +```c +#include +#include +#include +#include +#include +#include +#include + +#include "pwm.h" + +static int pwm_fd; // PWM 设备文件描述符 +static int int_all_count = 0; // 已输出的总周期数,用于统计 finish_once 回调次数 +static struct fh_pwm_chip_data pwm; // PWM 配置结构体实例 + +/* + * 完成一个周期后的回调函数 + * 每完成一个 PWM 周期,底层驱动会调用此函数 + */ +void pwm_finish_once(struct fh_pwm_chip_data *pwm) +{ + int_all_count++; // 每输出一个周期自增计数 +} + +/* + * 完成所有周期后的回调函数 + * 当完成设定的 pulse_num 个周期时调用 + */ +void pwm_finish_all(struct fh_pwm_chip_data *pwm) +{ + printf("[pwm_demo] pwm%d outputs all the %d pulses.\n", pwm->id, int_all_count); +} + +/* + * 配置 PWM 参数并启动 PWM 输出 + */ +int pwm_func(int pwm_fd) +{ + pwm.id = 6; // PWM 通道 ID + pwm.config.period_ns = 10000000; // PWM 周期 = 10ms + pwm.config.duty_ns = 5000000; // 高电平时间 = 5ms(50% 占空比) + pwm.config.percent = 0; // 使用 duty_ns 而非 percent 方式配置占空比 + pwm.config.delay_ns = 0; // PWM 使能后延迟 0ns 开始输出 + pwm.config.phase_ns = 0; // 起始相位 + pwm.config.pulses = FH_PWM_PULSE_LIMIT; // 设置为输出有限数量的脉冲 + pwm.config.pulse_num = 200; // 输出 200 个周期后停止 + pwm.config.finish_all = 1; // 完成全部周期后触发中断 + pwm.config.finish_once = 1; // 每完成一个周期触发中断 + pwm.finishall_callback = pwm_finish_all; // 全部完成回调 + pwm.finishonce_callback = pwm_finish_once; // 单周期完成回调 + + ioctl(pwm_fd, DISABLE_PWM, &pwm); // 禁止 PWM(确保配置生效前关闭) + ioctl(pwm_fd, SET_PWM_CONFIG, &pwm); // 设置 PWM 参数 + ioctl(pwm_fd, ENABLE_PWM, &pwm); // 使能 PWM 开始输出 + + sleep(1); + ioctl(pwm_fd, GET_PWM_CONFIG, &pwm); // 读取 PWM 当前配置(用于调试) + + return 0; +} + +/* + * 线程入口函数,打开 PWM 设备并开始测试 + */ +void *pwm_demo_main(void *para) +{ + prctl(PR_SET_NAME, "pwm demo"); // 设置线程名称 + printf("[pwm_demo] pwm demo start:\n"); + + pwm_fd = open("/dev/pwm", O_RDWR); // 打开 PWM 设备 + if (pwm_fd == -1) + { + printf("[pwm_demo] open pwm failed\n"); + return NULL; + } + pwm_func(pwm_fd); // 配置并启动 PWM + + return NULL; +} + +/* + * PWM demo 初始化,创建线程运行 PWM 测试 + */ +int pwm_demo_init(void) +{ + int ret; + pthread_t pwm_thread; + pthread_attr_t attr; + + pthread_attr_init(&attr); // 初始化线程属性 + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 设置为分离线程 + pthread_attr_setstacksize(&attr, 10 * 1024); // 设置线程栈大小 + + // 创建 pwm_demo_main 线程 + ret = pthread_create(&pwm_thread, &attr, pwm_demo_main, NULL); + if(ret) + { + printf("[pwm_demo] Error: Create pwm_demo_main thread failed!\n"); + return -1; + } + + printf("[pwm_demo] start int_all_count:%d\n", int_all_count); + sleep(5); + printf("[pwm_demo] end int_all_count:%d\n", int_all_count); + + return 0; +} +``` + +## 6. 编译代码 + +输入如下命令开始编译代码: + +```bash +make clean;make +``` + +![image-20251205165931584](figures/image-20251205165931584.png) + +编译结果如下图: + +在 `bsp_demo/out/bin/` 中生成了 bsp_demo.bin 固件。 + +![image-20251205170009227](figures/image-20251205170009227.png) + +## 7. 烧录固件 + +将编译生成的 bsp_demo.bin 固件复制到共享文件夹中。 + +### 7.1 进入 uboot + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +**Hit any key to stop autoboot** + +![image-20251205171847725](figures/image-20251205171847725.png) + +### 7.2 查看设备 IP + +输入下述命令查看当前的信息 + +```bahs +pri +``` + +输出内容如下: + +![image-20251205172033034](figures/image-20251205172033034.png) + +输入下述命令进行IP配置: + +```bash +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +```bash +saveenv +``` + +配置电脑IP地址: + +![image-20251205172122432](figures/image-20251205172122432.png) + +开启 tftp: + +![image-20251205172133756](figures/image-20251205172133756.png) + +### 7.3 烧录主处理器固件 + +加载应用固件,出现下述内容则表示加载成功: + +```bash +tftp 10000000 bsp_demo.bin +``` + +![image-20251205172520750](figures/image-20251205172520750.png) + +然后输入下述命令进行准备: + +```bash +go 10000000 +``` + +**停顿一下,敲enter键,出现:msh />,再去执行后续操作:** + +![image-20251205172310038](figures/image-20251205172310038.png) + +## 8. 测试 PWM + +在 shell 中输入 `ls /dev` 命令查看启用的外设: + +![image-20251205172834981](figures/image-20251205172834981.png) + +在 shell 中输入 `pinctrl -l` 命令可以查看引脚复用情况: + +![image-20251205172759374](figures/image-20251205172759374.png) + +输入 `bsp_demo -p` 开始 pwm 测试: + +![image-20251205173258999](figures/image-20251205173258999.png) + +![image-20251205173619585](figures/image-20251205173619585.png) + +# 四、FH8626V300L上的SADC实践 + +## 1. 前置准备 + +### 1.1 硬件准备 + +**包含**:串口线、FH8626V300L开发板、电源线、网线。(本章用不到 Sensor 摄像头板) + +![image-20251205171346094](figures/image-20251205171346094.png) + +### 1.2 软件准备 + +**进入 SDK 的 rt-thread 目录** + +![image-20251205155037769](figures/image-20251205155037769.png) + +**应用初始配置** + +在终端中输入如下命令进行初始配置: + +```bash +make fh8626v300_defconfig +``` + +![image-20251205155257034](figures/image-20251205155257034.png) + +**使能SADC外设** + +在终端中输入如下命令使用图形化界面配置工程 + +```bash +make menuconfig +``` + +进入 Drivers 配置项。 + +![image-20251205162223990](figures/image-20251205162223990.png) + +使能 SADC。 + +![image-20251208092254355](figures/image-20251208092254355.png) + +选择 app demo 为 bsp_demo。 + +![image-20251205165833376](figures/image-20251205165833376.png) + +保存配置。 + +![image-20251205162418489](figures/image-20251205162418489.png) + +**进入 bsp_demo 目录** + +在终端中输入如下命令使用 VSCode 打开目前所在的目录 + +```bash +code . +``` + +bsp_demo 目录结构如下图所示: + +![image-20251205155758476](figures/image-20251205155758476.png) + +## 2. 查看原理图 + +开发板原理图路径为 `FH8626V300_RT_V1.0.0_20250627/docs_tools/hardware/board/FH8626V300L_QFN80_APP_BOARD_V1.pdf` 。 + +在原理图中找到 SADC_IN0 的引脚如下图: + +![image-20251208092425832](figures/image-20251208092425832.png) + +SADC_IN0 连接了 CDS1 和 CDS2(通过跳线帽切换)。原理图中显示 CDS1 上连接了一个光敏电阻(D19),因此我们使用跳线帽将 SADC_IN0 与 CDS1 连接(JP75)。 + +在开发板上的位置如下: + +![image-20251208093046254](figures/image-20251208093046254.png) + +## 3. 配置 PinMux + +**PIN 引脚复用需要注意不能冲突,否则会导致复用不生效。** + +PIN 引脚复用可查看 PinMux 表格或 fh8626v300_iopad.h 文件。 + +* PinMux 表格:`FH8626V300_RT_V1.0.0_20250627/docs_tools/hardware/board/FH8626V300L_PIN_MUX.xlsm` + +* fh8626v300_iopad.h 文件:`FH8626V300_RT_V1.0.0_20250627/rt-thread/platform/fh8626v300/fh8626v300_iopad.h` + +修改 `FH8626V300_RT_V1.0.0_20250627/rt-thread/platform/fh8626v300/app_board/appboard_iopad.h` 文件,在 `*fh_pinctrl_selected_devices[]`数组中添加 "SADC_IN1"。 + +```c +#ifndef __APP_IOPAD_H__ +#define __APP_IOPAD_H__ + +char *fh_pinctrl_selected_devices[] = { + /* CONFIG_PINCTRL_SELECT */ + "SADC_IN0", "SADC_IN1", "SPI0_4BIT", + "PWM6", "UART0", "UART1", "GPIO28", "GPIO40", + "GPIO49", "GPIO62", "GPIO63", "MIPI", +#ifdef WIFI_USING_SDIOWIFI +#if (WIFI_SDIO == 0) +"SD0_WIFI", "GPIO25" +#else +"SD0_NO_WP" +#endif +#else +"SD0_NO_WP" +#endif +}; + +char *fh_pinctrl_selected_aon_devices[] = { + /* CONFIG_PINCTRL_SELECT */ + "I2C0", "SENSOR0_VS", "SENSOR1_VS", "SENSOR_CLK", + "GPIO14", + + "GPIO6", "GPIO7", "GPIO8", "GPIO9" +}; + +#endif +``` + +## 4. 修改 bsp_demo + +打开 `bsp_demo/startup/application.c` 文件,删除 `user_main()` 中的代码,修改测试方式为手动执行。 + +```c +#include +#include +#include + +#include "rttshell.h" + +extern void sadc_demo_init(void); +extern int sdcard_demo_init(void); +extern int aes_demo_init(void); +extern int pwm_demo_init(void); +extern int gpio_demo_init(void); +extern int uart_demo_init(void); +extern int i2c_demo_init(void); +extern int rtc_demo_init(void); + +void user_main(void) +{ +} + +static void bsp_demo_usage(void) +{ + printf("Usage:\n"); + printf(" bsp_demo -e: run aes demo\n"); + printf(" bsp_demo -t: run rtc demo\n"); + printf(" bsp_demo -i: run i2c demo\n"); + printf(" bsp_demo -a: run sadc demo\n"); + printf(" bsp_demo -p: run pwm demo\n"); + printf(" bsp_demo -g: run gpio demo\n"); + printf(" bsp_demo -u: run uart demo\n"); + printf(" bsp_demo -c: run sdcard demo\n"); +} + +static void bsp_demo(int argc, char *argv[]) +{ + if (argc < 2) + { + bsp_demo_usage(); + return; + } + if (strcmp(argv[1], "-e") == 0) + { + aes_demo_init(); + } + else if (strcmp(argv[1], "-u") == 0) + { + uart_demo_init(); + } + else if (strcmp(argv[1], "-g") == 0) + { + gpio_demo_init(); + } + else if (strcmp(argv[1], "-p") == 0) + { + pwm_demo_init(); + } + else if (strcmp(argv[1], "-c") == 0) + { + sdcard_demo_init(); + } + else if (strcmp(argv[1], "-a") == 0) + { + sadc_demo_init(); + } + else if (strcmp(argv[1], "-t") == 0) + { + rtc_demo_init(); + } + else if (strcmp(argv[1], "-i") == 0) + { + i2c_demo_init(); + } + else + { + bsp_demo_usage(); + } +} +SHELL_CMD_EXPORT(bsp_demo, bsp demo) +``` + +## 5. 修改 SADC 代码 + +修改 `bsp_demo/sadc/sadc_demo.c` 。 + +```c +#include +#include +#include +#include +#include +#include +#include +#include +#include "sadc.h" + +/* sadc_demo_main + * 该线程循环读取 SADC(模拟数字转换器)数据,包括原始数字值和电压值 + */ +void *sadc_demo_main(void *param) +{ + unsigned int fd; /* SADC 设备文件描述符 */ + unsigned int raw_data; /* 用于存储原始 ADC 数字值 */ + SADC_INFO info; /* 用于 ioctl 的数据结构 */ + + /* 初始化结构体信息 */ + info.channel = 0; /* 指定读取 SADC 的通道 0 */ + info.sadc_data = 0; /* 初始化数据 */ + + /* 设置当前线程在系统中的名称,方便调试查看 */ + prctl(PR_SET_NAME, "sadc demo"); + /* 打开 SADC 设备节点,路径为 /dev/sadc */ + fd = open( "/dev/sadc", O_RDWR, 0); + + if (!fd) + { + printf("[sadc_demo] cann't open the sadc dev\n"); + goto __exit; /* 跳转到资源释放位置 */ + } + + /* 循环读取 ADC 值 */ + while (1) + { + /* 读取原始数字量(未转换电压)*/ + ioctl(fd, SADC_CMD_READ_RAW_DATA, &info); + raw_data = info.sadc_data; + /* 读取转换后的电压(单位 mV)*/ + ioctl(fd, SADC_CMD_READ_VOLT, &info); + /* 打印通道号、数字量、电压值 */ + printf("[sadc_demo] channel:%x digt data:%x volt:%d mv\n", info.channel,raw_data, info.sadc_data); + + sleep(1); + } + +__exit: + /* 关闭设备文件 */ + close(fd); + return NULL; +} + +/* 初始化并创建 SADC 测试线程 */ +void sadc_demo_init(void) +{ + pthread_attr_t attr; /* 线程属性 */ + pthread_t thrd; /* 线程句柄 */ + struct sched_param param; /* 线程调度参数 */ + + /* 初始化线程属性 */ + pthread_attr_init(&attr); + /* 设置线程为分离态,退出后自动回收资源 */ + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + /* 设置线程栈大小 */ + pthread_attr_setstacksize(&attr, 10240); + /* 设置线程优先级 */ + param.sched_priority = 80; + pthread_attr_setschedparam(&attr, ¶m); + /* 创建线程 */ + if (pthread_create(&thrd, &attr, sadc_demo_main, NULL) != 0) + { + printf("[sadc_demo] Error: Create sadc demo thread failed!\n"); + } +} +``` + +## 6. 编译代码 + +输入如下命令开始编译代码: + +```bash +make clean;make +``` + +![image-20251205165931584](figures/image-20251205165931584.png) + +编译结果如下图: + +在 `bsp_demo/out/bin/` 中生成了 bsp_demo.bin 固件。 + +![image-20251205170009227](figures/image-20251205170009227.png) + +## 7. 烧录固件 + +将编译生成的 bsp_demo.bin 固件复制到共享文件夹中。 + +### 7.1 进入 uboot + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +**Hit any key to stop autoboot** + +![image-20251205171847725](figures/image-20251205171847725.png) + +### 7.2 查看设备 IP + +输入下述命令查看当前的信息 + +```bahs +pri +``` + +输出内容如下: + +![image-20251205172033034](figures/image-20251205172033034.png) + +输入下述命令进行IP配置: + +```bash +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +```bash +saveenv +``` + +配置电脑IP地址: + +![image-20251205172122432](figures/image-20251205172122432.png) + +开启 tftp: + +![image-20251205172133756](figures/image-20251205172133756.png) + +### 7.3 烧录主处理器固件 + +加载应用固件,出现下述内容则表示加载成功: + +```bash +tftp 10000000 bsp_demo.bin +``` + +![image-20251205172520750](figures/image-20251205172520750.png) + +然后输入下述命令进行准备: + +```bash +go 10000000 +``` + +**停顿一下,敲enter键,出现:msh />,再去执行后续操作:** + +![image-20251205172310038](figures/image-20251205172310038.png) + +## 8. 测试 SADC + +在 shell 中输入 `ls /dev` 命令查看启用的外设: + +![image-20251208094854260](figures/image-20251208094854260.png) + +在 shell 中输入 `pinctrl -l` 命令可以查看引脚复用情况: + +![image-20251208094941531](figures/image-20251208094941531.png) + +输入 `bsp_demo -a` 开始 sadc 测试: + +![image-20251208100215313](figures/image-20251208100215313.png) + +# 五、FH8626V300L上的SPI实践 + +## 1. 前置准备 + +### 1.1 硬件准备 + +**包含**:串口线、FH8626V300L开发板、电源线、网线。(本章用不到 Sensor 摄像头板) + +![image-20251205171346094](figures/image-20251205171346094.png) + +### 1.2 软件准备 + +**进入 SDK 的 rt-thread 目录** + +![image-20251205155037769](figures/image-20251205155037769.png) + +**应用初始配置** + +在终端中输入如下命令进行初始配置: + +```bash +make fh8626v300_defconfig +``` + +![image-20251205155257034](figures/image-20251205155257034.png) + +**使能SPI外设** + +在终端中输入如下命令使用图形化界面配置工程 + +```bash +make menuconfig +``` + +进入 Drivers 配置项。 + +![image-20251205162223990](figures/image-20251205162223990.png) + +使能 spi。 + +![image-20251210142735500](figures/image-20251210142735500.png) + +选择 app demo 为 bsp_demo。 + +![image-20251205165833376](figures/image-20251205165833376.png) + +保存配置。 + +![image-20251205162418489](figures/image-20251205162418489.png) + +**进入 bsp_demo 目录** + +在终端中输入如下命令使用 VSCode 打开目前所在的目录 + +```bash +code . +``` + +bsp_demo 目录结构如下图所示: + +![image-20251205155758476](figures/image-20251205155758476.png) + +## 2. 配置 PinMux + +**PIN 引脚复用需要注意不能冲突,否则会导致复用不生效。** + +PIN 引脚复用可查看 PinMux 表格或 fh8626v300_iopad.h 文件。 + +* PinMux 表格:`FH8626V300_RT_V1.0.0_20250627/docs_tools/hardware/board/FH8626V300L_PIN_MUX.xlsm` + +* fh8626v300_iopad.h 文件:`FH8626V300_RT_V1.0.0_20250627/rt-thread/platform/fh8626v300/fh8626v300_iopad.h` + +在 PinMux 表格中可以看到,GPIO0~GPIO3 可以复用为 SSI1。 + +![image-20251210142921637](figures/image-20251210142921637.png) + +修改 `FH8626V300_RT_V1.0.0_20250627/rt-thread/platform/fh8626v300/app_board/appboard_iopad.h` 文件,在 `*fh_pinctrl_selected_devices[]`数组中删除 "STM0" 和 "STM1",并添加 "SPI1" 和 "GPIO1"。 + +```c +#ifndef __APP_IOPAD_H__ +#define __APP_IOPAD_H__ + +char *fh_pinctrl_selected_devices[] = { + /* CONFIG_PINCTRL_SELECT */ + "SADC_IN0", "SADC_IN1", "SPI0_4BIT", "SPI1", + "GPIO1", "UART0", "UART1", "GPIO28", "GPIO40", + "GPIO49", "GPIO62", "GPIO63", "MIPI", +#ifdef WIFI_USING_SDIOWIFI +#if (WIFI_SDIO == 0) +"SD0_WIFI", "GPIO25" +#else +"SD0_NO_WP" +#endif +#else +"SD0_NO_WP" +#endif +}; + +char *fh_pinctrl_selected_aon_devices[] = { + /* CONFIG_PINCTRL_SELECT */ + "I2C0", "SENSOR0_VS", "SENSOR1_VS", "SENSOR_CLK", + "GPIO14", + + "GPIO6", "GPIO7", "GPIO8", "GPIO9" +}; + +#endif +``` + +## 3. 查看原理图 + +开发板原理图路径为 `FH8626V300_RT_V1.0.0_20250627/docs_tools/hardware/board/FH8626V300L_QFN80_APP_BOARD_V1.pdf` 。 + +在原理图中找到 GPIO0~GPIO3 的引脚如下图: + +![image-20251210143317165](figures/image-20251210143317165.png) + +在开发板上的位置如下: + +![image-20251210143417100](figures/image-20251210143417100.png) + +将 JP16、JP20、JP25、JP28 座子上的跳线帽取下,使用跳线帽或者杜邦线连接 GPIO2 和 GPIO3。 + +## 4. 修改 bsp_demo + +打开 `bsp_demo/startup/application.c` 文件,删除 `user_main()` 中的代码,修改测试方式为手动执行,同时添加 spi 测试代码。 + +```c +#include +#include +#include + +#include "rttshell.h" + +extern void sadc_demo_init(void); +extern int sdcard_demo_init(void); +extern int aes_demo_init(void); +extern int pwm_demo_init(void); +extern int gpio_demo_init(void); +extern int uart_demo_init(void); +extern int i2c_demo_init(void); +extern int rtc_demo_init(void); +extern int spi_demo_init(void); + +void user_main(void) +{ +} + +static void bsp_demo_usage(void) +{ + printf("Usage:\n"); + printf(" bsp_demo -e: run aes demo\n"); + printf(" bsp_demo -t: run rtc demo\n"); + printf(" bsp_demo -i: run i2c demo\n"); + printf(" bsp_demo -a: run sadc demo\n"); + printf(" bsp_demo -p: run pwm demo\n"); + printf(" bsp_demo -g: run gpio demo\n"); + printf(" bsp_demo -u: run uart demo\n"); + printf(" bsp_demo -c: run sdcard demo\n"); + printf(" bsp_demo -s: run spi demo\n"); +} + +static void bsp_demo(int argc, char *argv[]) +{ + if (argc < 2) + { + bsp_demo_usage(); + return; + } + if (strcmp(argv[1], "-e") == 0) + { + aes_demo_init(); + } + else if (strcmp(argv[1], "-u") == 0) + { + uart_demo_init(); + } + else if (strcmp(argv[1], "-g") == 0) + { + gpio_demo_init(); + } + else if (strcmp(argv[1], "-p") == 0) + { + pwm_demo_init(); + } + else if (strcmp(argv[1], "-c") == 0) + { + sdcard_demo_init(); + } + else if (strcmp(argv[1], "-a") == 0) + { + sadc_demo_init(); + } + else if (strcmp(argv[1], "-t") == 0) + { + rtc_demo_init(); + } + else if (strcmp(argv[1], "-i") == 0) + { + i2c_demo_init(); + } + else if (strcmp(argv[1], "-s") == 0) + { + spi_demo_init(); + } + else + { + bsp_demo_usage(); + } +} +SHELL_CMD_EXPORT(bsp_demo, bsp demo) +``` + +## 5. 编写 SPI 代码 + +创建 `bsp_demo/spi` 目录并在该目录下新建 `spi_demo.c` 文件。 + +```c +#include +#include + +#define DBG_TAG "demo.spi" +#define DBG_LVL DBG_LOG +#include "rtdbg.h" + +#define SPI_DEVICE_NAME "ssi1_0" +#define TEXT_NUMBER_SIZE 1024 // 发送与接收的 buffer 大小 + +/* + * SPI 示例初始化函数 + * 功能:从 RT-Thread 的 SPI 设备框架中获取 SPI 设备,配置 SPI, + * 然后进行 1KB 数据收发与校验。 + */ +int spi_demo_init(void) +{ + /* 定义发送与接收缓存(静态分配)*/ + static uint8_t sendbuf[TEXT_NUMBER_SIZE] = {0}; + static uint8_t readbuf[TEXT_NUMBER_SIZE] = {0}; + + /* 初始化发送数据:sendbuf[i] = i */ + for (int i = 0; i < sizeof(readbuf); i++) + { + sendbuf[i] = i; + } + /* SPI 设备指针 */ + static struct rt_spi_device *spi_dev = RT_NULL; + /* SPI 配置结构体 */ + struct rt_spi_configuration cfg; + + /* 查找 SPI 设备(设备通常在 BSP 初始化阶段注册)*/ + spi_dev = (struct rt_spi_device *)rt_device_find(SPI_DEVICE_NAME); + if (RT_NULL == spi_dev) + { + LOG_E("spi sample run failed! can't find %s device!", SPI_DEVICE_NAME); + return -RT_ERROR; + } + + /* 配置 SPI 参数 */ + cfg.data_width = 8; // 数据位宽 8 bit + cfg.mode = RT_SPI_MASTER // 主机模式 + | RT_SPI_MODE_0 // SPI Mode 0 (CPOL=0, CPHA=0) + | RT_SPI_MSB // MSB first + | RT_SPI_NO_CS; // 不由 SPI 框架控制 CS(CS 外部控制) + cfg.max_hz = 50 * 1000 * 1000; // 最大时钟 50MHz + /* 应用 SPI 配置 */ + rt_spi_configure(spi_dev, &cfg); + + /* 打印发送数据 */ + LOG_D("%s send:", SPI_DEVICE_NAME); + for (int i = 0; i < sizeof(sendbuf); i++) + { + rt_kprintf("%02x ", sendbuf[i]); + } + /* SPI 全双工传输:发送 sendbuf,同时接收 readbuf */ + rt_spi_transfer(spi_dev, sendbuf, readbuf, sizeof(sendbuf)); + + rt_kprintf("\n\n"); + LOG_D("%s rcv:", SPI_DEVICE_NAME); + /* 校验接收到的数据 */ + for (int i = 0; i < sizeof(readbuf); i++) + { + if (readbuf[i] != sendbuf[i]) // 只要有 byte 不一致则失败 + { + LOG_E("SPI test fail!!!"); + break; + } + else + rt_kprintf("%02x ", readbuf[i]); + } + + rt_kprintf("\n\n"); + LOG_D("SPI test end"); + + return RT_EOK; +} +``` + +## 6. 修改 Makefile + +修改 Makefile 文件,将 RT-Thread 内核与驱动加入编译。 + +```makefile +include $(SDKROOT)/build/config.mk + +SAMPNAME := $(shell basename `pwd`) + +SAMP_SRCS := $(wildcard aes/*.c) +SAMP_SRCS += $(wildcard spi/*.c) +SAMP_SRCS += $(wildcard i2c/*.c) +SAMP_SRCS += $(wildcard rtc/*.c) +SAMP_SRCS += $(wildcard sadc/*.c) +SAMP_SRCS += $(wildcard sdio/*.c) +SAMP_SRCS += $(wildcard startup/*.c) +SAMP_SRCS += $(wildcard pwm/*.c) +SAMP_SRCS += $(wildcard gpio/*.c) +SAMP_SRCS += $(wildcard uart/*.c) +SAMP_SRCS += $(wildcard wdt/*.c) + +LOCAL_CFLAGS += $(INCFLAGS) + +include $(SDKROOT)/build/apps.mk +``` + +## 7. 编译代码 + +输入如下命令开始编译代码: + +```bash +make clean;make +``` + +![image-20251205165931584](figures/image-20251205165931584.png) + +编译结果如下图: + +在 `bsp_demo/out/bin/` 中生成了 bsp_demo.bin 固件。 + +![image-20251205170009227](figures/image-20251205170009227.png) + +## 8. 烧录固件 + +将编译生成的 bsp_demo.bin 固件复制到共享文件夹中。 + +### 8.1 进入 uboot + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +**Hit any key to stop autoboot** + +![image-20251205171847725](figures/image-20251205171847725.png) + +### 8.2 查看设备 IP + +输入下述命令查看当前的信息 + +```bahs +pri +``` + +输出内容如下: + +![image-20251205172033034](figures/image-20251205172033034.png) + +输入下述命令进行IP配置: + +```bash +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +```bash +saveenv +``` + +配置电脑IP地址: + +![image-20251205172122432](figures/image-20251205172122432.png) + +开启 tftp: + +![image-20251205172133756](figures/image-20251205172133756.png) + +### 8.3 烧录主处理器固件 + +加载应用固件,出现下述内容则表示加载成功: + +```bash +tftp 10000000 bsp_demo.bin +``` + +![image-20251205172520750](figures/image-20251205172520750.png) + +然后输入下述命令进行准备: + +```bash +go 10000000 +``` + +**停顿一下,敲enter键,出现:msh />,再去执行后续操作:** + +![image-20251205172310038](figures/image-20251205172310038.png) + +## 9. 测试 SPI + +在 shell 中输入 `ls /dev` 命令查看启用的外设: + +![image-20251210144456410](figures/image-20251210144456410.png) + +在 shell 中输入 `pinctrl -l` 命令可以查看引脚复用情况: + +![image-20251210144550931](figures/image-20251210144550931.png) + +输入 `bsp_demo -s` 开始 spi 测试: + +![image-20251210144929590](figures/image-20251210144929590.png) + +# 六、FH8626V300L上的WDT实践 + +## 1. 前置准备 + +### 1.1 硬件准备 + +**包含**:串口线、FH8626V300L开发板、电源线、网线。(本章用不到 Sensor 摄像头板) + +![image-20251205171346094](figures/image-20251205171346094.png) + +### 1.2 软件准备 + +**进入 SDK 的 rt-thread 目录** + +![image-20251205155037769](figures/image-20251205155037769.png) + +**应用初始配置** + +在终端中输入如下命令进行初始配置: + +```bash +make fh8626v300_defconfig +``` + +![image-20251205155257034](figures/image-20251205155257034.png) + +**使能 WDT 外设** + +在终端中输入如下命令使用图形化界面配置工程 + +```bash +make menuconfig +``` + +![image-20251205162223990](figures/image-20251205162223990.png) + +使能 wdt。 + +![image-20251209163735422](figures/image-20251209163735422.png) + +选择 app demo 为 bsp_demo。 + +![image-20251205165833376](figures/image-20251205165833376.png) + +保存配置。 + +![image-20251205162418489](figures/image-20251205162418489.png) + +**进入 bsp_demo 目录** + +在终端中输入如下命令使用 VSCode 打开目前所在的目录 + +```bash +code . +``` + +bsp_demo 目录结构如下图所示: + +![image-20251205155758476](figures/image-20251205155758476.png) + +## 2. 修改 bsp_demo + +打开 `bsp_demo/startup/application.c` 文件,删除 `user_main()` 中的代码,修改测试方式为手动执行,添加 wdt_demo 的测试代码。 + +```c +#include +#include +#include + +#include "rttshell.h" + +extern void sadc_demo_init(void); +extern int sdcard_demo_init(void); +extern int aes_demo_init(void); +extern int pwm_demo_init(void); +extern int gpio_demo_init(void); +extern int uart_demo_init(void); +extern int i2c_demo_init(void); +extern int rtc_demo_init(void); +extern int wdt_demo_init(void); + +void user_main(void) +{ +} + +static void bsp_demo_usage(void) +{ + printf("Usage:\n"); + printf(" bsp_demo -e: run aes demo\n"); + printf(" bsp_demo -t: run rtc demo\n"); + printf(" bsp_demo -i: run i2c demo\n"); + printf(" bsp_demo -a: run sadc demo\n"); + printf(" bsp_demo -p: run pwm demo\n"); + printf(" bsp_demo -g: run gpio demo\n"); + printf(" bsp_demo -u: run uart demo\n"); + printf(" bsp_demo -c: run sdcard demo\n"); + printf(" bsp_demo -w: run wdt demo\n"); +} + +static void bsp_demo(int argc, char *argv[]) +{ + if (argc < 2) + { + bsp_demo_usage(); + return; + } + if (strcmp(argv[1], "-e") == 0) + { + aes_demo_init(); + } + else if (strcmp(argv[1], "-u") == 0) + { + uart_demo_init(); + } + else if (strcmp(argv[1], "-g") == 0) + { + gpio_demo_init(); + } + else if (strcmp(argv[1], "-p") == 0) + { + pwm_demo_init(); + } + else if (strcmp(argv[1], "-c") == 0) + { + sdcard_demo_init(); + } + else if (strcmp(argv[1], "-a") == 0) + { + sadc_demo_init(); + } + else if (strcmp(argv[1], "-t") == 0) + { + rtc_demo_init(); + } + else if (strcmp(argv[1], "-i") == 0) + { + i2c_demo_init(); + } + else if (strcmp(argv[1], "-w") == 0) + { + wdt_demo_init(); + } + else + { + bsp_demo_usage(); + } +} +SHELL_CMD_EXPORT(bsp_demo, bsp demo) +``` + +## 3. 添加 WDT 代码 + +新建 `bsp_demo/wdt` 目录并在该目录下新建 `wdt_demo.c` 。 + +```c +#include +#include +#include +#include +#include +#include +#include +#include "wdt.h" + +/* + * Watchdog 示例线程 + * 在线程中喂狗 10 次,测试停止喂狗后是否会自动重启 + */ +void *wdt_demo_main(void *para) +{ + int wdt_fd; + int wdt_timeout = 2; // 看门狗超时时间(单位:秒) + + prctl(PR_SET_NAME, "wdt demo"); // 设置线程名称 + printf("[wdt_demo] wdt demo start:\n"); + + /* 打开 WDT 设备节点,返回设备句柄 */ + wdt_fd = open("/dev/fh_wdt0", O_RDWR); + if (wdt_fd == -1) + { + printf("[wdt_demo] open wdt failed\n"); + return NULL; // 打开失败,退出线程 + } + + /* 设置看门狗超时时间为 wdt_timeout 秒 */ + ioctl(wdt_fd, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &wdt_timeout); + wdt_timeout = 0; + /* 读取看门狗超时时间 */ + ioctl(wdt_fd, RT_DEVICE_CTRL_WDT_GET_TIMEOUT, &wdt_timeout); + printf("[wdt_demo] get wdt timeout: %d sec\n", wdt_timeout); + /* 启动看门狗 */ + ioctl(wdt_fd, RT_DEVICE_CTRL_WDT_START); + /* 连续喂狗 10 次,每次间隔 1 秒 */ + for (int i = 0; i < 10; i++) + { + /* 喂狗,避免超时复位 */ + ioctl(wdt_fd, RT_DEVICE_CTRL_WDT_KEEPALIVE); + printf("[wdt_demo] feed dog %d\n", i); + sleep(1); + } + + return NULL; +} + +/* + * 创建并启动 WDT 示例线程 + */ +int wdt_demo_init(void) +{ + int ret; + pthread_t wdt_thread; + pthread_attr_t attr; + + /* 初始化线程属性结构体 */ + pthread_attr_init(&attr); + /* 设置线程为分离态,结束后自动回收资源 */ + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + /* 设置线程栈大小 */ + pthread_attr_setstacksize(&attr, 10 * 1024); + + /* 创建 wdt_demo_main 线程 */ + ret = pthread_create(&wdt_thread, &attr, wdt_demo_main, NULL); + if(ret) + { + printf("[wdt_demo] Error: Create wdt_demo_main thread failed!\n"); + return -1; + } + + return 0; +} +``` + +##4. 将 wdt_demo 加入编译 + +修改 `app/bsp_demo/Makefile` 文件。 + +```makefile +include $(SDKROOT)/build/config.mk + +SAMPNAME := $(shell basename `pwd`) + +SAMP_SRCS := $(wildcard aes/*.c) +SAMP_SRCS += $(wildcard spi/*.c) +SAMP_SRCS += $(wildcard i2c/*.c) +SAMP_SRCS += $(wildcard rtc/*.c) +SAMP_SRCS += $(wildcard sadc/*.c) +SAMP_SRCS += $(wildcard sdio/*.c) +SAMP_SRCS += $(wildcard startup/*.c) +SAMP_SRCS += $(wildcard pwm/*.c) +SAMP_SRCS += $(wildcard gpio/*.c) +SAMP_SRCS += $(wildcard uart/*.c) +SAMP_SRCS += $(wildcard wdt/*.c) + +include $(SDKROOT)/build/apps.mk +``` + +## 5. 编译代码 + +输入如下命令开始编译代码: + +```bash +make clean;make +``` + +![image-20251205165931584](figures/image-20251205165931584.png) + +编译结果如下图: + +在 `bsp_demo/out/bin/` 中生成了 bsp_demo.bin 固件。 + +![image-20251205170009227](figures/image-20251205170009227.png) + +## 6. 烧录固件 + +将编译生成的 bsp_demo.bin 固件复制到共享文件夹中。 + +### 6.1 进入 uboot + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +**Hit any key to stop autoboot** + +![image-20251205171847725](figures/image-20251205171847725.png) + +### 6.2 查看设备 IP + +输入下述命令查看当前的信息 + +```bahs +pri +``` + +输出内容如下: + +![image-20251205172033034](figures/image-20251205172033034.png) + +输入下述命令进行IP配置: + +```bash +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +```bash +saveenv +``` + +配置电脑IP地址: + +![image-20251205172122432](figures/image-20251205172122432.png) + +开启 tftp: + +![image-20251205172133756](figures/image-20251205172133756.png) + +### 6.3 烧录主处理器固件 + +加载应用固件,出现下述内容则表示加载成功: + +```bash +tftp 10000000 bsp_demo.bin +``` + +![image-20251205172520750](figures/image-20251205172520750.png) + +然后输入下述命令进行准备: + +```bash +go 10000000 +``` + +**停顿一下,敲enter键,出现:msh />,再去执行后续操作:** + +![image-20251205172310038](figures/image-20251205172310038.png) + +## 7. 测试 WDT + +在 shell 中输入 `ls /dev` 命令查看启用的外设: + +![image-20251209165147055](figures/image-20251209165147055.png) + +输入 `bsp_demo -w` 开始 wdt 测试: + +![image-20251209171054101](figures/image-20251209171054101.png) + +# 七、FH8626V300L上的SDIO实践 + +## 1. 前置准备 + +### 1.1 硬件准备 + +**包含**:串口线、FH8626V300L开发板、电源线、网线。(本章用不到 Sensor 摄像头板) + +![image-20251205171346094](figures/image-20251205171346094.png) + +### 1.2 软件准备 + +**进入 SDK 的 rt-thread 目录** + +![image-20251205155037769](figures/image-20251205155037769.png) + +**应用初始配置** + +在终端中输入如下命令进行初始配置: + +```bash +make fh8626v300_defconfig +``` + +![image-20251205155257034](figures/image-20251205155257034.png) + +**使能SD卡外设** + +在终端中输入如下命令使用图形化界面配置工程 + +```bash +make menuconfig +``` + +进入 Drivers 配置项。 + +![image-20251205162223990](figures/image-20251205162223990.png) + +使能 mmc。 + +![image-20251212095400354](figures/image-20251212095400354.png) + +选择 app demo 为 bsp_demo。 + +![image-20251205165833376](figures/image-20251205165833376.png) + +保存配置。 + +![image-20251205162418489](figures/image-20251205162418489.png) + +**进入 bsp_demo 目录** + +在终端中输入如下命令使用 VSCode 打开目前所在的目录 + +```bash +code . +``` + +bsp_demo 目录结构如下图所示: + +![image-20251205155758476](figures/image-20251205155758476.png) + +## 2. 查看原理图 + +开发板原理图路径为 `FH8626V300_RT_V1.0.0_20250627/docs_tools/hardware/board/FH8626V300L_QFN80_APP_BOARD_V1.pdf` 。 + +![image-20251212095543906](figures/image-20251212095543906.png) + +## 3. 配置 PinMux + +**PIN 引脚复用需要注意不能冲突,否则会导致复用不生效。** + +PIN 引脚复用可查看 PinMux 表格或 fh8626v300_iopad.h 文件。 + +* PinMux 表格:`FH8626V300_RT_V1.0.0_20250627/docs_tools/hardware/board/FH8626V300L_PIN_MUX.xlsm` + +* fh8626v300_iopad.h 文件:`FH8626V300_RT_V1.0.0_20250627/rt-thread/platform/fh8626v300/fh8626v300_iopad.h` + + `FH8626V300_RT_V1.0.0_20250627/rt-thread/platform/fh8626v300/app_board/appboard_iopad.h` 文件内容如下: + +```c +#ifndef __APP_IOPAD_H__ +#define __APP_IOPAD_H__ + +char *fh_pinctrl_selected_devices[] = { + /* CONFIG_PINCTRL_SELECT */ + "SADC_IN0", "SADC_IN1", "SPI0_4BIT", + "PWM6", "UART0", "UART1", "GPIO28", "GPIO40", + "GPIO49", "GPIO62", "GPIO63", "MIPI", +#ifdef WIFI_USING_SDIOWIFI +#if (WIFI_SDIO == 0) +"SD0_WIFI", "GPIO25" +#else +"SD0_NO_WP" +#endif +#else +"SD0_NO_WP" +#endif +}; + +char *fh_pinctrl_selected_aon_devices[] = { + /* CONFIG_PINCTRL_SELECT */ + "I2C0", "SENSOR0_VS", "SENSOR1_VS", "SENSOR_CLK", + "GPIO14", + + "GPIO6", "GPIO7", "GPIO8", "GPIO9" +}; + +#endif +``` + +## 4. 修改 bsp_demo + +打开 `bsp_demo/startup/application.c` 文件,删除 `user_main()` 中的代码,修改测试方式为手动执行。 + +```c +#include +#include +#include + +#include "rttshell.h" + +extern void sadc_demo_init(void); +extern int sdcard_demo_init(void); +extern int aes_demo_init(void); +extern int pwm_demo_init(void); +extern int gpio_demo_init(void); +extern int uart_demo_init(void); +extern int i2c_demo_init(void); +extern int rtc_demo_init(void); + +void user_main(void) +{ +} + +static void bsp_demo_usage(void) +{ + printf("Usage:\n"); + printf(" bsp_demo -e: run aes demo\n"); + printf(" bsp_demo -t: run rtc demo\n"); + printf(" bsp_demo -i: run i2c demo\n"); + printf(" bsp_demo -a: run sadc demo\n"); + printf(" bsp_demo -p: run pwm demo\n"); + printf(" bsp_demo -g: run gpio demo\n"); + printf(" bsp_demo -u: run uart demo\n"); + printf(" bsp_demo -c: run sdcard demo\n"); +} + +static void bsp_demo(int argc, char *argv[]) +{ + if (argc < 2) + { + bsp_demo_usage(); + return; + } + if (strcmp(argv[1], "-e") == 0) + { + aes_demo_init(); + } + else if (strcmp(argv[1], "-u") == 0) + { + uart_demo_init(); + } + else if (strcmp(argv[1], "-g") == 0) + { + gpio_demo_init(); + } + else if (strcmp(argv[1], "-p") == 0) + { + pwm_demo_init(); + } + else if (strcmp(argv[1], "-c") == 0) + { + sdcard_demo_init(); + } + else if (strcmp(argv[1], "-a") == 0) + { + sadc_demo_init(); + } + else if (strcmp(argv[1], "-t") == 0) + { + rtc_demo_init(); + } + else if (strcmp(argv[1], "-i") == 0) + { + i2c_demo_init(); + } + else + { + bsp_demo_usage(); + } +} +SHELL_CMD_EXPORT(bsp_demo, bsp demo) +``` + +## 5. SDIO 代码 + + `bsp_demo/sdio/sdio_demo.c` 内容如下: + +```c +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-05-06 songyh first version + */ + +#include +#include +#include +#include // gettimeofday() +#include +#include +#include +#include +#include +#define TEST_FILE "/mnt/test.dat" +#define CHUNK_SIZE (32*1024) +#define TEST_LOOP_CNT 1024 + +/** @fn double get_interval(IN const struct timeval start_time, IN const struct timeval end_time); +* @brief 获取两个timeval类型start_time和end_time的间隔,以微妙为单位返回相差的绝对值 +* @ (两个输入参数颠倒后也能正常计算) +* @param start_time 开始timeval值(跟timeval 可以颠倒) +* @param end_time 结束timeval值(跟timeval 可以颠倒) +* @return 间隔值 :成功 +*/ + +double get_interval(const struct timeval *start_time, const struct timeval *end_time) +{ + double delay_time = 0.0; // 存放临时时间间隔值 + + if (end_time->tv_sec >= start_time->tv_sec) + { + delay_time = (end_time->tv_sec - start_time->tv_sec)*1000000; + delay_time += end_time->tv_usec - start_time->tv_usec; + + // 防止在输入值颠倒的情况下,而两个时间值的秒相同,则需要取绝对值 + delay_time = (delay_time < 0) ? (0 - delay_time): (delay_time); + } + else + { + delay_time = (start_time->tv_sec - end_time->tv_sec)*1000000; + delay_time += start_time->tv_usec - end_time->tv_usec; + } + + return delay_time; +} +void *sdcard_demo_proc(void *param) +{ + int fd; + int index, length; + int round; + struct timeval tv_begin,tv_end; // 用于存放读取的开始时间以及截至时间 + double read_speed; + double write_speed; + char *write_buf; + char *read_buf; + int stop_test = 0; + double time_spend = 0.0; + + prctl(PR_SET_NAME, "sdcard_demo"); + write_buf = malloc(CHUNK_SIZE); + if (write_buf == NULL) + { + printf("[sdcard_demo] malloc write buffer failed\n"); + return NULL; + } + read_buf = malloc(CHUNK_SIZE); + if (read_buf == NULL) + { + printf("[sdcard_demo] malloc read buffer failed\n"); + free(write_buf); + return NULL; + } + + round = 1; + + while (round < 3) + { + fd = open(TEST_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0); + if (fd < 0) + { + printf("[sdcard_demo] open file for write failed\n"); + sleep(1); + continue; + } + + for (index = 0; index < CHUNK_SIZE; index++) + write_buf[index] = index % 0xFF; + + gettimeofday(&tv_begin, NULL); + for (index = 0; index < TEST_LOOP_CNT; index++) + { + length = write(fd, write_buf, CHUNK_SIZE); + if (length != CHUNK_SIZE) + { + printf("[sdcard_demo] write data failed\n"); + close(fd); + stop_test = 1; + break; + } + } + if (stop_test) + break; + gettimeofday(&tv_end, NULL); + time_spend = get_interval(&tv_begin, &tv_end); + if (time_spend != 0) + { + write_speed = CHUNK_SIZE*TEST_LOOP_CNT / time_spend; + printf("[sdcard_demo] Write speed: %.2f(MB/S)\n", write_speed); + } + close(fd); + + fd = open(TEST_FILE, O_RDONLY, 0); + if (fd < 0) + { + printf("[sdcard_demo] open file for read failed\n"); + break; + } + + gettimeofday(&tv_begin, NULL); + for (index = 0; index < TEST_LOOP_CNT; index++) + { + length = read(fd, read_buf, CHUNK_SIZE); + if (length != CHUNK_SIZE) + { + printf("[sdcard_demo] read file failed\n"); + close(fd); + stop_test = 1; + break; + } + } + if (stop_test) + break; + gettimeofday(&tv_end, NULL);; + for (index = 0; index < CHUNK_SIZE; index++) + { + if (read_buf[index] != write_buf[index]) + { + printf("[sdcard_demo] data check failed, read_buf[%d]0x%x != write_buf[%d]0x%x\n", index, read_buf[index], index, write_buf[index]); + close(fd); + stop_test = 1; + break; + } + } + if (stop_test) + break; + time_spend = get_interval(&tv_begin, &tv_end); + if (time_spend != 0) + { + read_speed = CHUNK_SIZE*TEST_LOOP_CNT / time_spend; + printf("[sdcard_demo] Read speed: %.2f(MB/S)", read_speed); + } + + printf("[sdcard_demo] test round %d \n\n", round++); + close(fd); + } + + free(write_buf); + free(read_buf); + return NULL; +} + +void sdcard_demo_init(void) +{ + pthread_attr_t attr; + pthread_t thrd; + struct sched_param param; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, 10240); + + param.sched_priority = 80; + pthread_attr_setschedparam(&attr, ¶m); + + if (pthread_create(&thrd, &attr, sdcard_demo_proc, NULL) != 0) + { + printf("[sdcard_demo] Create sdcard_demo thread failed!\n"); + } +} + +``` + +## 6. 编译代码 + +输入如下命令开始编译代码: + +```bash +make clean;make +``` + +![image-20251205165931584](figures/image-20251205165931584.png) + +编译结果如下图: + +在 `bsp_demo/out/bin/` 中生成了 bsp_demo.bin 固件。 + +![image-20251205170009227](figures/image-20251205170009227.png) + +## 7. 烧录固件 + +将编译生成的 bsp_demo.bin 固件复制到共享文件夹中。 + +### 7.1 进入 uboot + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +**Hit any key to stop autoboot** + +![image-20251205171847725](figures/image-20251205171847725.png) + +### 7.2 查看设备 IP + +输入下述命令查看当前的信息 + +```bahs +pri +``` + +输出内容如下: + +![image-20251205172033034](figures/image-20251205172033034.png) + +输入下述命令进行IP配置: + +```bash +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +```bash +saveenv +``` + +配置电脑IP地址: + +![image-20251205172122432](figures/image-20251205172122432.png) + +开启 tftp: + +![image-20251205172133756](figures/image-20251205172133756.png) + +### 7.3 烧录主处理器固件 + +加载应用固件,出现下述内容则表示加载成功: + +```bash +tftp 10000000 bsp_demo.bin +``` + +![image-20251205172520750](figures/image-20251205172520750.png) + +然后输入下述命令进行准备: + +```bash +go 10000000 +``` + +**停顿一下,敲enter键,出现:msh />,再去执行后续操作:** + +![image-20251205172310038](figures/image-20251205172310038.png) + +## 8. 测试 SDIO + +自动挂载 SD 卡: + +![image-20251212100003450](figures/image-20251212100003450.png) + +在 shell 中输入 `ls /dev` 命令查看启用的外设: + +![image-20251212100058102](figures/image-20251212100058102.png) + +在 shell 中输入 `pinctrl -l` 命令可以查看引脚复用情况: + +![image-20251212100126768](figures/image-20251212100126768.png) + +输入 `bsp_demo -c` 开始 sdio 测试: + +![image-20251212100155457](figures/image-20251212100155457.png) + +# 八、FH8626V300L上的ETH实践 + +## 1. 前置准备 + +### 1.1 硬件准备 + +**包含**:串口线、FH8626V300L开发板、电源线、网线。(本章用不到 Sensor 摄像头板) + +![image-20251205171346094](figures/image-20251205171346094.png) + +### 1.2 软件准备 + +**进入 SDK 的 rt-thread 目录** + +![image-20251205155037769](figures/image-20251205155037769.png) + +**应用初始配置** + +在终端中输入如下命令进行初始配置: + +```bash +make fh8626v300_defconfig +``` + +![image-20251205155257034](figures/image-20251205155257034.png) + +**使能ETH外设** + +在终端中输入如下命令使用图形化界面配置工程 + +```bash +make menuconfig +``` + +进入 Drivers 配置项。 + +![image-20251205162223990](figures/image-20251205162223990.png) + +使能 gmac。 + +![image-20251215103254350](figures/image-20251215103254350.png) + +选择 app demo 为 bsp_demo。 + +![image-20251205165833376](figures/image-20251205165833376.png) + +保存配置。 + +![image-20251205162418489](figures/image-20251205162418489.png) + +## 2. 编译代码 + +输入如下命令开始编译代码: + +```bash +make clean;make +``` + +![image-20251205165931584](figures/image-20251205165931584.png) + +编译结果如下图: + +在 `bsp_demo/out/bin/` 中生成了 bsp_demo.bin 固件。 + +![image-20251205170009227](figures/image-20251205170009227.png) + +## 3. 烧录固件 + +将编译生成的 bsp_demo.bin 固件复制到共享文件夹中。 + +### 3.1 进入 uboot + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +**Hit any key to stop autoboot** + +![image-20251205171847725](figures/image-20251205171847725.png) + +### 3.2 查看设备 IP + +输入下述命令查看当前的信息 + +```bahs +pri +``` + +输出内容如下: + +![image-20251205172033034](figures/image-20251205172033034.png) + +输入下述命令进行IP配置: + +```bash +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +```bash +saveenv +``` + +配置电脑IP地址: + +![image-20251205172122432](figures/image-20251205172122432.png) + +开启 tftp: + +![image-20251205172133756](figures/image-20251205172133756.png) + +### 3.3 烧录主处理器固件 + +加载应用固件,出现下述内容则表示加载成功: + +```bash +tftp 10000000 bsp_demo.bin +``` + +![image-20251205172520750](figures/image-20251205172520750.png) + +然后输入下述命令进行准备: + +```bash +go 10000000 +``` + +**停顿一下,敲enter键,出现:msh />,再去执行后续操作:** + +![image-20251205172310038](figures/image-20251205172310038.png) + +## 4. 测试 ETH + +自动检测 ETH 连接状态: + +![image-20251215103758113](figures/image-20251215103758113.png) + +在 shell 中输入 `ls /dev` 命令查看启用的外设: + +![image-20251215103827695](figures/image-20251215103827695.png) + +在 shell 中输入 `ifconfig e0 192.168.70.100 netmask 255.255.255.0` 配置开发板 IP: + +![image-20251215104211581](figures/image-20251215104211581.png) + +关闭电脑防火墙: + +![image-20251215104811951](figures/image-20251215104811951.png) + +输入 `ping 192.168.70.50` 开始 ping 测试: + +![image-20251215104447514](figures/image-20251215104447514.png) + +PC主机 ping 开发板: + +![image-20251215104524912](figures/image-20251215104524912.png) + +# 九、FH8626V300L上的Audio实践 + +## 1. 前置准备 + +### 1.1 硬件准备 + +**包含**:串口线、FH8626V300L开发板、电源线、网线。(本章用不到 Sensor 摄像头板) + +![image-20251205171346094](figures/image-20251205171346094.png) + +### 1.2 软件准备 + +**进入 SDK 的 rt-thread 目录** + +![image-20251205155037769](figures/image-20251205155037769.png) + +**应用初始配置** + +在终端中输入如下命令进行初始配置: + +```bash +make fh8626v300_defconfig +``` + +![image-20251205155257034](figures/image-20251205155257034.png) + +**使能Audio外设** + +在终端中输入如下命令使用图形化界面配置工程 + +```bash +make menuconfig +``` + +进入 Drivers 配置项。 + +![image-20251205162223990](figures/image-20251205162223990.png) + +使能 audio。 + +![image-20251212112622681](figures/image-20251212112622681.png) + +选择 app demo 为 audio_demo。 + +![image-20251212112653959](figures/image-20251212112653959.png) + +保存配置。 + +![image-20251205162418489](figures/image-20251205162418489.png) + +**进入 audio_demo 目录** + +在终端中输入如下命令使用 VSCode 打开目前所在的目录 + +```bash +code . +``` + +audio_demo 目录结构如下图所示: + +![image-20251212112744422](figures/image-20251212112744422.png) + +## 2. 查看原理图 + +开发板原理图路径为 `FH8626V300_RT_V1.0.0_20250627/docs_tools/hardware/board/FH8626V300L_QFN80_APP_BOARD_V1.pdf` 。 + +在原理图中找到 Audio 的引脚如下图: + +![image-20251212112826061](figures/image-20251212112826061.png) + +![image-20251212112835618](figures/image-20251212112835618.png) + +在开发板上的位置如下: + +![image-20251212112953714](figures/image-20251212112953714.png) + +## 3. 配置 PinMux + +**PIN 引脚复用需要注意不能冲突,否则会导致复用不生效。** + +PIN 引脚复用可查看 PinMux 表格或 fh8626v300_iopad.h 文件。 + +* PinMux 表格:`FH8626V300_RT_V1.0.0_20250627/docs_tools/hardware/board/FH8626V300L_PIN_MUX.xlsm` + +* fh8626v300_iopad.h 文件:`FH8626V300_RT_V1.0.0_20250627/rt-thread/platform/fh8626v300/fh8626v300_iopad.h` + +修改 `FH8626V300_RT_V1.0.0_20250627/rt-thread/platform/fh8626v300/app_board/appboard_iopad.h` 文件,在 `*fh_pinctrl_selected_aon_devices[]`数组中将 "GPIO7" 改成 "AON_PWM1"。 + +```c +#ifndef __APP_IOPAD_H__ +#define __APP_IOPAD_H__ + +char *fh_pinctrl_selected_devices[] = { + /* CONFIG_PINCTRL_SELECT */ + "SADC_IN0", "SADC_IN1", "SPI0_4BIT", "SPI1", + "GPIO1", "UART0", "UART1", "GPIO28", "GPIO40", + "GPIO49", "GPIO62", "GPIO63", "MIPI", +#ifdef WIFI_USING_SDIOWIFI +#if (WIFI_SDIO == 0) +"SD0_WIFI", "GPIO25" +#else +"SD0_NO_WP" +#endif +#else +"SD0_NO_WP" +#endif +}; + +char *fh_pinctrl_selected_aon_devices[] = { + /* CONFIG_PINCTRL_SELECT */ + "I2C0", "SENSOR0_VS", "SENSOR1_VS", "SENSOR_CLK", + "GPIO14", + + "GPIO6", "AON_PWM1", "GPIO8", "GPIO9" +}; + +#endif +``` + +## 4. audio_demo + +`audio_demo/src/audio_api_demo.c` 内容如下: + +```c +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dsp/fh_audio_mpi.h" + +#define CHECK_RET(expr) \ + do \ + { \ + ret = expr; \ + if (ret) \ + { \ + printf("%s:%d failed %08x: "#expr"\n", __func__, __LINE__, ret); \ + goto Exit; \ + } \ + else \ + { \ + printf("done: "#expr"\n"); \ + } \ + }while (0) + +static int g_running = 0; +static int g_stat_tim; +static int g_stat_samples; +static int g_exit_flag = 0; + +static int config_AI_alg_parameter(int enable_hpf, int enable_nr, int enable_agc, int enable_doa, int enable_aec) +{ + int ret; + FH_AC_SesParam alg; + + ret = FH_AC_AI_MIX_Get_Algo_Param(&alg, sizeof(alg)); + if (ret) + { + printf("FH_AC_AI_MIX_Get_Algo_Param: error, ret=%d!\n", ret); + return -1; + } + + alg.hpf_flag = enable_hpf; + alg.anc_flag = enable_nr; + alg.agc_flag = enable_agc; + alg.doa_flag = enable_doa; + alg.aec_flag = enable_aec; + + ret = FH_AC_AI_MIX_Set_Algo_Param(&alg, sizeof(alg)); + if (ret) + { + printf("FH_AC_AI_MIX_Set_Algo_Param: error, ret=%d!\n", ret); + return -1; + } + + return 0; +} + +static int config_AO_alg_parameter(int enable_hpf, int enable_nr, int enable_agc) +{ + int ret; + FH_AC_SesParam alg; + + ret = FH_AC_AO_Get_Algo_Param(&alg, sizeof(alg)); + if (ret) + { + printf("FH_AC_AO_Get_Algo_Param: error, ret=%d!\n", ret); + return -1; + } + + alg.hpf_flag = enable_hpf; + alg.anc_flag = enable_nr; + alg.agc_flag = enable_agc; + + ret = FH_AC_AO_Set_Algo_Param(&alg, sizeof(alg)); + if (ret) + { + printf("FH_AC_AO_Set_Algo_Param: error, ret=%d!\n", ret); + return -1; + } + + return 0; +} + +static void statistic_start(void) +{ + g_stat_samples = 0; + g_stat_tim = time(0); +} + +static void statistic(int samples) +{ + int now; + int diff; + + g_stat_samples += samples; + now = time(0); + diff = now - g_stat_tim; + if (diff >= 5) + { + printf("Sample rate:%d\n", g_stat_samples / diff); + g_stat_samples = 0; + g_stat_tim = now; + } +} + +static int channel_num(int mask) +{ + int i; + int num = 0; + + for (i=0; i<32; i++) + { + if (mask & (1 << i)) + { + num++; + } + } + + return num; +} + +static void save_ai_data(char *filename, FH_AC_AI_Frame_S *frame) +{ + int i; + char path[256]; + char *data; + static int total; + static int fd_initialized = 0; + static int fd[FH_AI_CHANNEL_NUM+2]; + + if (!filename || total >= 12*1024*1024) /*don't save too large file.*/ + return; + + if (!fd_initialized) + { + for (i=0; ifar; + } + else if (i == FH_AI_CHANNEL_NUM + 1) + { + sprintf(path, "%s_mix.pcm", filename); + data = frame->mix; + } + else + { + sprintf(path, "%s_ch%d.pcm", filename, i); + data = frame->ch_data[i]; + } + + if (!data) + continue; + + if (fd[i] < 0) + { + fd[i] = open(path, O_RDWR | O_TRUNC | O_CREAT); + if (fd[i] < 0) + { + printf("Create file %s failed!\n", path); + return; + } + fchmod(fd[i], 0644); + } + + if (frame->ch_data_len != write(fd[i], data, frame->ch_data_len)) + { + printf("write file %s failed!\n", path); + } + } + + total += frame->ch_data_len; +} + +static int read_from_file(char *file_name, char *data, int len) +{ + int ret; + static int fd = -1; + + if (fd < 0) + { + fd = open(file_name, O_RDONLY); + if (fd < 0) + { + printf("Error: cann't open file %s!\n", file_name); + return -1; + } + } + + while (len > 0) + { + ret = read(fd, data, len); + if (ret <= 0 || ret > len || (ret & 1) != 0) + { + lseek(fd, 0, SEEK_SET); + printf("Seek playback file...\n"); + continue; + } + + data += ret; + len -= ret; + } + + return 0; +} + +static void *audio_run(void *arg) +{ + int test_ai = 1; /*开启AI测试*/ + int test_ao = 1; /*开启AO测试*/ + int enable_hpf = 1; // 高通滤波 + int enable_nr = 1; // 降噪 + int enable_agc = 1; // 自动增益 + int enable_aec = 0; // 回声消除 + int enable_doa = 0; // 声源定位 + + int sample_rate = 16000; + int period_size = 1024; + int channel_mask = 1; /*default enable mic0*/ + int mix_mask = 0; + int ain_select = FH_AC_MIC_IN; + int micin_vol = 2; + int ain_vol = 28; + int aout_vol = 3; + char *record_file = NULL; + char *playback_file = NULL; + + FH_UINT32 version1; + FH_UINT32 version2; + FH_UINT32 support_chmask; + FH_AC_CONFIG ac_config; + FH_AC_MIX_CONFIG mix_config; + FH_AC_AI_Frame_S ai_frame; + FH_AC_AO_FRAME_S ao_frame; + char playback_buffer[period_size*2]; + int ai_enabled = 0; + int ao_enabled = 0; + int ret; + + if (!test_ai && !test_ao) + { + printf("Error: please specify test AI and or AO!\n"); + goto Exit; + } + + if (test_ao && !(playback_file || test_ai)) + { + printf("Error: please specify playback file!\n"); + goto Exit; + } + + printf("[INFO]: sample_rate=%d\n", sample_rate); + + CHECK_RET(FH_AC_Init()); + + CHECK_RET(FH_AC_Get_Algo_Version(&version1, &version2)); + printf("[INFO]: Alg version(%d.%d.%d),%08x-%d\n", version2>>24,(version2>>16)&0xff,(version2>>8)&0xff, version2, version1); + + CHECK_RET(FH_AC_AI_Get_Feature_ChannelMask(&support_chmask)); + printf("[INFO]: supported AI channel_mask=%08x.\n", support_chmask); + + statistic_start(); + + /***********************Config AI***********************************/ + if (test_ai) + { + if ((channel_mask & support_chmask) != channel_mask || !channel_mask) + { + channel_mask = support_chmask; + printf("[INFO]: Auto change channel_mask to %08x!\n", channel_mask); + } + +#ifndef CONFIG_ARCH_MC632X + ac_config.codec_sel = FH_AC_CODEC_INTERNAL; +#endif + ac_config.io_type = ain_select; + ac_config.sample_rate = sample_rate; + ac_config.bit_width = 16; + ac_config.enc_type = FH_PT_LPCM; + ac_config.period_size = period_size; + ac_config.channel_mask = channel_mask; + ac_config.frame_num = 0; /*default 0,mean use max buffer.*/ + ac_config.reserved = 0; + + CHECK_RET(FH_AC_Set_Config(&ac_config)); + + if (!mix_mask) + mix_mask = channel_mask; + + if (channel_num(mix_mask) > 1) + enable_doa = 1; + + mix_config.mix_enable = 1; + mix_config.mix_channel_mask = mix_mask; + mix_config.reserved = 0; + CHECK_RET(FH_AC_AI_MIX_Set_Config(&mix_config)); + CHECK_RET(FH_AC_AI_CH_SetAnologVol(0x0f, micin_vol, ain_vol)); + CHECK_RET(config_AI_alg_parameter(enable_hpf, enable_nr, enable_agc, enable_doa, enable_aec)); + } + + /***********************Config AO***********************************/ + if (test_ao) + { +#ifndef CONFIG_ARCH_MC632X + ac_config.codec_sel = FH_AC_CODEC_INTERNAL; +#endif + ac_config.io_type = FH_AC_LINE_OUT; + ac_config.sample_rate = sample_rate; + ac_config.bit_width = 16; + ac_config.enc_type = FH_PT_LPCM; + ac_config.period_size = period_size; + ac_config.channel_mask = 0x01; /*for AO, only one channel is supported*/ + ac_config.frame_num = 0; /*default 0,mean use max buffer*/ + ac_config.reserved = 0; + + CHECK_RET(FH_AC_Set_Config(&ac_config)); + CHECK_RET(FH_AC_AO_SetAnologVol(aout_vol)); + CHECK_RET(config_AO_alg_parameter(0, 0, 0)); + } + + /***********************Enable AI/AO*********************************/ + if (test_ai && test_ao) + { + CHECK_RET(FH_AC_AI_AO_SYNC_Enable()); + ai_enabled = 1; + ao_enabled = 1; + printf("[INFO]: start capturing and playing audio data...\n"); + } + else + { + if (test_ai) + { + CHECK_RET(FH_AC_AI_Enable()); + ai_enabled = 1; + printf("[INFO]: start capturing audio data...\n"); + } + if (test_ao) + { + CHECK_RET(FH_AC_AO_Enable()); + ao_enabled = 1; + printf("[INFO]: start playing audio data...\n"); + } + } + + while (!g_exit_flag) + { + if (test_ai) + { + ret = FH_AC_AI_GetFrame(&ai_frame); + if (ret == 0) + { + if (ai_frame.ch_data_len != period_size * 2 || !ai_frame.mix) + { + printf("Error: FH_AC_AI_GetFrame,len=%d,mix=%p,it should not happen!!!\n", ai_frame.ch_data_len, ai_frame.mix); + continue; + } + + statistic(ai_frame.ch_data_len/2); + memcpy(playback_buffer, ai_frame.mix, ai_frame.ch_data_len); + save_ai_data(record_file, &ai_frame); + } + else + { + printf("Error: FH_AC_AI_GetFrame,ret=%d!\n", ret); + continue; + } + } + + if (test_ao) + { + if (playback_file) + { + ret = read_from_file(playback_file, playback_buffer, period_size * 2); + if (ret < 0) + { + printf("Error: read playback file failed!\n"); + break; + } + } + + ao_frame.len = period_size * 2; + ao_frame.data = (FH_UINT8 *)playback_buffer; + ret = FH_AC_AO_SendFrame(&ao_frame); + if (ret == 0) + { + if (!test_ai) + statistic(ao_frame.len/2); + } + else + { + printf("Error: FH_AC_AO_SendFrame failed,ret=%d!\n", ret); + } + } + } + printf("[INFO]: stop audio test!\n"); + +Exit: + if (ai_enabled) + FH_AC_AI_Disable(); + + if (ao_enabled) + FH_AC_AO_Disable(); + + FH_AC_DeInit(); + + printf("audio_demo: finished!\n"); + g_running = 0; + + return 0; +} + +void audio_demo(int argc, char *argv[]) +{ + pthread_attr_t attr; + pthread_t thd; + + if (g_running) + { + g_exit_flag = 1; + printf("audio_demo: send exit signal...\n"); + return; + } + + g_running = 1; + g_exit_flag = 0; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, 4 * 1024); + pthread_create(&thd, &attr, audio_run, NULL); +} + +void user_main(void) +{ +} + +#include +SHELL_CMD_EXPORT(audio_demo, audio demo/with -h to show help); +``` + +## 5. 编译代码 + +输入如下命令开始编译代码: + +```bash +make clean;make +``` + +![image-20251205165931584](figures/image-20251205165931584.png) + +编译结果如下图: + +在 `audio_demo/out/bin/` 中生成了 audio_demo.bin 固件。 + +![image-20251212113423571](figures/image-20251212113423571.png) + +## 6. 烧录固件 + +将编译生成的 audio_demo.bin 固件复制到共享文件夹中。 + +### 6.1 进入 uboot + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +**Hit any key to stop autoboot** + +![image-20251205171847725](figures/image-20251205171847725.png) + +### 6.2 查看设备 IP + +输入下述命令查看当前的信息 + +```bahs +pri +``` + +输出内容如下: + +![image-20251205172033034](figures/image-20251205172033034.png) + +输入下述命令进行IP配置: + +```bash +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +```bash +saveenv +``` + +配置电脑IP地址: + +![image-20251205172122432](figures/image-20251205172122432.png) + +开启 tftp: + +![image-20251205172133756](figures/image-20251205172133756.png) + +### 6.3 烧录主处理器固件 + +加载应用固件,出现下述内容则表示加载成功: + +```bash +tftp 10000000 audio_demo.bin +``` + +![image-20251212113848588](figures/image-20251212113848588.png) + +然后输入下述命令进行准备: + +```bash +go 10000000 +``` + +**停顿一下,敲enter键,出现:msh />,再去执行后续操作:** + +![image-20251205172310038](figures/image-20251205172310038.png) + +## 7. 测试 Audio + +在 shell 中输入 `pinctrl -l` 命令可以查看引脚复用情况: + +![image-20251212113551339](figures/image-20251212113551339.png) + +将耳机接入丝印为 CH3 的耳机接口,输入 `audio_demo` 开始 audio 测试: + +![image-20251212113802419](figures/image-20251212113802419.png) + +再次输入 `audio_demo` 停止 audio 测试: + +![image-20251212113813746](figures/image-20251212113813746.png) + +## 8. 播放 WAV 音频 + +对 `static int read_from_file(char *file_name, char *data, int len)` 函数稍加修改,同时关闭 AI 测试,只保留 AO 测试,播放保存在SD卡中的 `/mnt/music/Canon.wav` 音频。 + +```c +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dsp/fh_audio_mpi.h" + +#define CHECK_RET(expr) \ + do \ + { \ + ret = expr; \ + if (ret) \ + { \ + printf("%s:%d failed %08x: "#expr"\n", __func__, __LINE__, ret); \ + goto Exit; \ + } \ + else \ + { \ + printf("done: "#expr"\n"); \ + } \ + }while (0) + +static int g_running = 0; +static int g_stat_tim; +static int g_stat_samples; +static int g_exit_flag = 0; + +// WAV文件头结构体 +typedef struct { + char chunk_id[4]; // "RIFF" + uint32_t chunk_size; + char format[4]; // "WAVE" + + char subchunk1_id[4]; // "fmt " + uint32_t subchunk1_size; + uint16_t audio_format; // 1 for PCM + uint16_t num_channels; // 1 for mono, 2 for stereo + uint32_t sample_rate; + uint32_t byte_rate; + uint16_t block_align; + uint16_t bits_per_sample; + + char subchunk2_id[4]; // "data" + uint32_t subchunk2_size; +} wav_header_t; + +// 读取WAV文件头并跳过 +static int skip_wav_header(int fd) +{ + wav_header_t header; + int ret; + + ret = read(fd, &header, sizeof(wav_header_t)); + if (ret != sizeof(wav_header_t)) + { + printf("Error: read wav header failed!\n"); + return -1; + } + + // 验证WAV文件格式 + if (memcmp(header.chunk_id, "RIFF", 4) != 0 || + memcmp(header.format, "WAVE", 4) != 0 || + memcmp(header.subchunk1_id, "fmt ", 4) != 0) + { + printf("Error: not a valid WAV file!\n"); + return -1; + } + + // 检查是否为PCM格式 + if (header.audio_format != 1) + { + printf("Error: only PCM WAV files are supported!\n"); + return -1; + } + + // 打印WAV文件信息 + printf("[WAV Info]:\n"); + printf(" Channels: %d\n", header.num_channels); + printf(" Sample Rate: %d Hz\n", header.sample_rate); + printf(" Bits per Sample: %d\n", header.bits_per_sample); + printf(" Data Size: %d bytes\n", header.subchunk2_size); + + // 检查是否已经是正确的格式(16bit,16kHz,单声道) + if (header.sample_rate != 16000) + { + printf("Warning: Sample rate is %d, not 16000 Hz\n", header.sample_rate); + } + + if (header.bits_per_sample != 16) + { + printf("Warning: Bits per sample is %d, not 16-bit\n", header.bits_per_sample); + } + + if (header.num_channels != 1) + { + printf("Warning: Channels is %d, converting to mono\n", header.num_channels); + } + + return 0; +} + +static int config_AI_alg_parameter(int enable_hpf, int enable_nr, int enable_agc, int enable_doa, int enable_aec) +{ + int ret; + FH_AC_SesParam alg; + + ret = FH_AC_AI_MIX_Get_Algo_Param(&alg, sizeof(alg)); + if (ret) + { + printf("FH_AC_AI_MIX_Get_Algo_Param: error, ret=%d!\n", ret); + return -1; + } + + alg.hpf_flag = enable_hpf; + alg.anc_flag = enable_nr; + alg.agc_flag = enable_agc; + alg.doa_flag = enable_doa; + alg.aec_flag = enable_aec; + + ret = FH_AC_AI_MIX_Set_Algo_Param(&alg, sizeof(alg)); + if (ret) + { + printf("FH_AC_AI_MIX_Set_Algo_Param: error, ret=%d!\n", ret); + return -1; + } + + return 0; +} + +static int config_AO_alg_parameter(int enable_hpf, int enable_nr, int enable_agc) +{ + int ret; + FH_AC_SesParam alg; + + ret = FH_AC_AO_Get_Algo_Param(&alg, sizeof(alg)); + if (ret) + { + printf("FH_AC_AO_Get_Algo_Param: error, ret=%d!\n", ret); + return -1; + } + + alg.hpf_flag = enable_hpf; + alg.anc_flag = enable_nr; + alg.agc_flag = enable_agc; + + ret = FH_AC_AO_Set_Algo_Param(&alg, sizeof(alg)); + if (ret) + { + printf("FH_AC_AO_Set_Algo_Param: error, ret=%d!\n", ret); + return -1; + } + + return 0; +} + +static void statistic_start(void) +{ + g_stat_samples = 0; + g_stat_tim = time(0); +} + +static void statistic(int samples) +{ + int now; + int diff; + + g_stat_samples += samples; + now = time(0); + diff = now - g_stat_tim; + if (diff >= 5) + { + printf("Sample rate:%d\n", g_stat_samples / diff); + g_stat_samples = 0; + g_stat_tim = now; + } +} + +static int channel_num(int mask) +{ + int i; + int num = 0; + + for (i=0; i<32; i++) + { + if (mask & (1 << i)) + { + num++; + } + } + + return num; +} + +static void save_ai_data(char *filename, FH_AC_AI_Frame_S *frame) +{ + int i; + char path[256]; + char *data; + static int total; + static int fd_initialized = 0; + static int fd[FH_AI_CHANNEL_NUM+2]; + + if (!filename || total >= 12*1024*1024) /*don't save too large file.*/ + return; + + if (!fd_initialized) + { + for (i=0; ifar; + } + else if (i == FH_AI_CHANNEL_NUM + 1) + { + sprintf(path, "%s_mix.pcm", filename); + data = frame->mix; + } + else + { + sprintf(path, "%s_ch%d.pcm", filename, i); + data = frame->ch_data[i]; + } + + if (!data) + continue; + + if (fd[i] < 0) + { + fd[i] = open(path, O_RDWR | O_TRUNC | O_CREAT); + if (fd[i] < 0) + { + printf("Create file %s failed!\n", path); + return; + } + fchmod(fd[i], 0644); + } + + if (frame->ch_data_len != write(fd[i], data, frame->ch_data_len)) + { + printf("write file %s failed!\n", path); + } + } + + total += frame->ch_data_len; +} + +static int read_from_file(char *file_name, char *data, int len) +{ + int ret; + static int fd = -1; + static int is_wav_file = 0; + static int wav_header_skipped = 0; + + if (fd < 0) + { + fd = open(file_name, O_RDONLY); + if (fd < 0) + { + printf("Error: cann't open file %s!\n", file_name); + return -1; + } + + // 检查是否是WAV文件 + char magic[4]; + ret = read(fd, magic, 4); + lseek(fd, 0, SEEK_SET); // 回到文件开头 + + if (memcmp(magic, "RIFF", 4) == 0) + { + is_wav_file = 1; + printf("Detected WAV file: %s\n", file_name); + } + } + + // 如果是WAV文件且还未跳过文件头 + if (is_wav_file && !wav_header_skipped) + { + if (skip_wav_header(fd) < 0) + { + printf("Error: invalid WAV file format!\n"); + return -1; + } + wav_header_skipped = 1; + printf("WAV header skipped, ready to play...\n"); + } + + while (len > 0) + { + ret = read(fd, data, len); + if (ret <= 0 || ret > len) + { + // 播放完回到文件开头循环播放 + if (is_wav_file) + { + lseek(fd, sizeof(wav_header_t), SEEK_SET); // 跳到WAV数据开始处 + printf("Playback loop...\n"); + continue; + } + else + { + lseek(fd, 0, SEEK_SET); + printf("Seek playback file...\n"); + continue; + } + } + + data += ret; + len -= ret; + } + + return 0; +} + +static void *audio_run(void *arg) +{ + int test_ai = 0; /*开启AI测试*/ + int test_ao = 1; /*开启AO测试*/ + int enable_hpf = 1; + int enable_nr = 1; + int enable_agc = 1; + int enable_aec = 0; + int enable_doa = 0; + + int sample_rate = 16000; + int period_size = 1024; + int channel_mask = 1; /*default enable mic0*/ + int mix_mask = 0; + int ain_select = FH_AC_MIC_IN; + int micin_vol = 2; + int ain_vol = 28; + int aout_vol = 3; + char *record_file = NULL; + // char *playback_file = NULL; + char *playback_file = "/mnt/music/Canon.wav"; + + FH_UINT32 version1; + FH_UINT32 version2; + FH_UINT32 support_chmask; + FH_AC_CONFIG ac_config; + FH_AC_MIX_CONFIG mix_config; + FH_AC_AI_Frame_S ai_frame; + FH_AC_AO_FRAME_S ao_frame; + char playback_buffer[period_size*2]; + int ai_enabled = 0; + int ao_enabled = 0; + int ret; + + if (!test_ai && !test_ao) + { + printf("Error: please specify test AI and or AO!\n"); + goto Exit; + } + + if (test_ao && !(playback_file || test_ai)) + { + printf("Error: please specify playback file!\n"); + goto Exit; + } + + printf("[INFO]: Playing WAV file: %s\n", playback_file); + printf("[INFO]: sample_rate=%d\n", sample_rate); + + CHECK_RET(FH_AC_Init()); + + CHECK_RET(FH_AC_Get_Algo_Version(&version1, &version2)); + printf("[INFO]: Alg version(%d.%d.%d),%08x-%d\n", version2>>24,(version2>>16)&0xff,(version2>>8)&0xff, version2, version1); + + CHECK_RET(FH_AC_AI_Get_Feature_ChannelMask(&support_chmask)); + printf("[INFO]: supported AI channel_mask=%08x.\n", support_chmask); + + statistic_start(); + + /***********************Config AI***********************************/ + if (test_ai) + { + if ((channel_mask & support_chmask) != channel_mask || !channel_mask) + { + channel_mask = support_chmask; + printf("[INFO]: Auto change channel_mask to %08x!\n", channel_mask); + } + +#ifndef CONFIG_ARCH_MC632X + ac_config.codec_sel = FH_AC_CODEC_INTERNAL; +#endif + ac_config.io_type = ain_select; + ac_config.sample_rate = sample_rate; + ac_config.bit_width = 16; + ac_config.enc_type = FH_PT_LPCM; + ac_config.period_size = period_size; + ac_config.channel_mask = channel_mask; + ac_config.frame_num = 0; /*default 0,mean use max buffer.*/ + ac_config.reserved = 0; + + CHECK_RET(FH_AC_Set_Config(&ac_config)); + + if (!mix_mask) + mix_mask = channel_mask; + + if (channel_num(mix_mask) > 1) + enable_doa = 1; + + mix_config.mix_enable = 1; + mix_config.mix_channel_mask = mix_mask; + mix_config.reserved = 0; + CHECK_RET(FH_AC_AI_MIX_Set_Config(&mix_config)); + CHECK_RET(FH_AC_AI_CH_SetAnologVol(0x0f, micin_vol, ain_vol)); + CHECK_RET(config_AI_alg_parameter(enable_hpf, enable_nr, enable_agc, enable_doa, enable_aec)); + } + + /***********************Config AO***********************************/ + if (test_ao) + { +#ifndef CONFIG_ARCH_MC632X + ac_config.codec_sel = FH_AC_CODEC_INTERNAL; +#endif + ac_config.io_type = FH_AC_LINE_OUT; + ac_config.sample_rate = sample_rate; + ac_config.bit_width = 16; + ac_config.enc_type = FH_PT_LPCM; + ac_config.period_size = period_size; + ac_config.channel_mask = 0x01; /*for AO, only one channel is supported*/ + ac_config.frame_num = 0; /*default 0,mean use max buffer*/ + ac_config.reserved = 0; + + CHECK_RET(FH_AC_Set_Config(&ac_config)); + CHECK_RET(FH_AC_AO_SetAnologVol(aout_vol)); + CHECK_RET(config_AO_alg_parameter(0, 0, 0)); + } + + /***********************Enable AI/AO*********************************/ + if (test_ai && test_ao) + { + CHECK_RET(FH_AC_AI_AO_SYNC_Enable()); + ai_enabled = 1; + ao_enabled = 1; + printf("[INFO]: start capturing and playing audio data...\n"); + } + else + { + if (test_ai) + { + CHECK_RET(FH_AC_AI_Enable()); + ai_enabled = 1; + printf("[INFO]: start capturing audio data...\n"); + } + if (test_ao) + { + CHECK_RET(FH_AC_AO_Enable()); + ao_enabled = 1; + printf("[INFO]: start playing audio data...\n"); + } + } + + while (!g_exit_flag) + { + if (test_ai) + { + ret = FH_AC_AI_GetFrame(&ai_frame); + if (ret == 0) + { + if (ai_frame.ch_data_len != period_size * 2 || !ai_frame.mix) + { + printf("Error: FH_AC_AI_GetFrame,len=%d,mix=%p,it should not happen!!!\n", ai_frame.ch_data_len, ai_frame.mix); + continue; + } + + statistic(ai_frame.ch_data_len/2); + memcpy(playback_buffer, ai_frame.mix, ai_frame.ch_data_len); + save_ai_data(record_file, &ai_frame); + } + else + { + printf("Error: FH_AC_AI_GetFrame,ret=%d!\n", ret); + continue; + } + } + + if (test_ao) + { + if (playback_file) + { + ret = read_from_file(playback_file, playback_buffer, period_size * 2); + if (ret < 0) + { + printf("Error: read playback file failed!\n"); + break; + } + } + + ao_frame.len = period_size * 2; + ao_frame.data = (FH_UINT8 *)playback_buffer; + ret = FH_AC_AO_SendFrame(&ao_frame); + if (ret == 0) + { + if (!test_ai) + statistic(ao_frame.len/2); + } + else + { + printf("Error: FH_AC_AO_SendFrame failed,ret=%d!\n", ret); + } + } + } + printf("[INFO]: stop audio test!\n"); + +Exit: + if (ai_enabled) + FH_AC_AI_Disable(); + + if (ao_enabled) + FH_AC_AO_Disable(); + + FH_AC_DeInit(); + + printf("audio_demo: finished!\n"); + g_running = 0; + + return 0; +} + +void audio_demo(int argc, char *argv[]) +{ + pthread_attr_t attr; + pthread_t thd; + + if (g_running) + { + g_exit_flag = 1; + printf("audio_demo: send exit signal...\n"); + return; + } + + g_running = 1; + g_exit_flag = 0; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, 20 * 1024); + pthread_create(&thd, &attr, audio_run, NULL); +} + +void user_main(void) +{ +} + +#include +SHELL_CMD_EXPORT(audio_demo, audio demo/with -h to show help); +``` + +# 十、FH8626V300L上的AES实践 + +## 1. 前置准备 + +### 1.1 硬件准备 + +**包含**:串口线、FH8626V300L开发板、电源线、网线。(本章用不到 Sensor 摄像头板) + +![image-20251205171346094](figures/image-20251205171346094.png) + +### 1.2 软件准备 + +**进入 SDK 的 rt-thread 目录** + +![image-20251205155037769](figures/image-20251205155037769.png) + +**应用初始配置** + +在终端中输入如下命令进行初始配置: + +```bash +make fh8626v300_defconfig +``` + +![image-20251205155257034](figures/image-20251205155257034.png) + +**使能AES外设** + +在终端中输入如下命令使用图形化界面配置工程 + +```bash +make menuconfig +``` + +选择 app demo 为 bsp_demo。 + +![image-20251205165833376](figures/image-20251205165833376.png) + +保存配置。 + +![image-20251205162418489](figures/image-20251205162418489.png) + +**进入 bsp_demo 目录** + +在终端中输入如下命令使用 VSCode 打开目前所在的目录 + +```bash +code . +``` + +bsp_demo 目录结构如下图所示: + +![image-20251205155758476](figures/image-20251205155758476.png) + +## 2. 修改 bsp_demo + +打开 `bsp_demo/startup/application.c` 文件,删除 `user_main()` 中的代码,修改测试方式为手动执行。 + +```c +#include +#include +#include + +#include "rttshell.h" + +extern void sadc_demo_init(void); +extern int sdcard_demo_init(void); +extern int aes_demo_init(void); +extern int pwm_demo_init(void); +extern int gpio_demo_init(void); +extern int uart_demo_init(void); +extern int i2c_demo_init(void); +extern int rtc_demo_init(void); + +void user_main(void) +{ +} + +static void bsp_demo_usage(void) +{ + printf("Usage:\n"); + printf(" bsp_demo -e: run aes demo\n"); + printf(" bsp_demo -t: run rtc demo\n"); + printf(" bsp_demo -i: run i2c demo\n"); + printf(" bsp_demo -a: run sadc demo\n"); + printf(" bsp_demo -p: run pwm demo\n"); + printf(" bsp_demo -g: run gpio demo\n"); + printf(" bsp_demo -u: run uart demo\n"); + printf(" bsp_demo -c: run sdcard demo\n"); +} + +static void bsp_demo(int argc, char *argv[]) +{ + if (argc < 2) + { + bsp_demo_usage(); + return; + } + if (strcmp(argv[1], "-e") == 0) + { + aes_demo_init(); + } + else if (strcmp(argv[1], "-u") == 0) + { + uart_demo_init(); + } + else if (strcmp(argv[1], "-g") == 0) + { + gpio_demo_init(); + } + else if (strcmp(argv[1], "-p") == 0) + { + pwm_demo_init(); + } + else if (strcmp(argv[1], "-c") == 0) + { + sdcard_demo_init(); + } + else if (strcmp(argv[1], "-a") == 0) + { + sadc_demo_init(); + } + else if (strcmp(argv[1], "-t") == 0) + { + rtc_demo_init(); + } + else if (strcmp(argv[1], "-i") == 0) + { + i2c_demo_init(); + } + else + { + bsp_demo_usage(); + } +} +SHELL_CMD_EXPORT(bsp_demo, bsp demo) +``` + +## 3. 修改 AES 代码 + +修改 `rt-thread/lib/inc/bsp/fh_crypto_api.h`,检查第 159 行是否正确。 + +![image-20251208105138748](figures/image-20251208105138748.png) + +AES dmeo 代码位于 `bsp_demo/aes/aes_demo.c` 。 + +```c +#include +#include +#include +#include +#include +#include +#include "fh_crypto_api.h" + +static const unsigned char plain_text[] = +{ + 0x6b,0xc1,0xbe,0xe2, 0x2e,0x40,0x9f,0x96, 0xe9,0x3d,0x7e,0x11, 0x73,0x93,0x17,0x2a, + 0xae,0x2d,0x8a,0x57, 0x1e,0x03,0xac,0x9c, 0x9e,0xb7,0x6f,0xac, 0x45,0xaf,0x8e,0x51, + 0x30,0xc8,0x1c,0x46, 0xa3,0x5c,0xe4,0x11, 0xe5,0xfb,0xc1,0x19, 0x1a,0x0a,0x52,0xef, + 0xf6,0x9f,0x24,0x45, 0xdf,0x4f,0x9b,0x17, 0xad,0x2b,0x41,0x7b, 0xe6,0x6c,0x37,0x10, +}; + +//================ aes cbc ===================== +static const unsigned char aes_cbc_iv_buf[] = +{ + 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, +}; + +static const unsigned char aes_cbc_key_buf[] = +{ + 0x2b,0x7e,0x15,0x16, 0x28,0xae,0xd2,0xa6, 0xab,0xf7,0x15,0x88, 0x09,0xcf,0x4f,0x3c, +}; + +static const unsigned char aes_cbc_encrypt_text[] = +{ + 0x76,0x49,0xab,0xac, 0x81,0x19,0xb2,0x46, 0xce,0xe9,0x8e,0x9b, 0x12,0xe9,0x19,0x7d, + 0x50,0x86,0xcb,0x9b, 0x50,0x72,0x19,0xee, 0x95,0xdb,0x11,0x3a, 0x91,0x76,0x78,0xb2, + 0x73,0xbe,0xd6,0xb8, 0xe3,0xc1,0x74,0x3b, 0x71,0x16,0xe6,0x9e, 0x22,0x22,0x95,0x16, + 0x3f,0xf1,0xca,0xa1, 0x68,0x1f,0xac,0x09, 0x12,0x0e,0xca,0x30, 0x75,0x86,0xe1,0xa7, +}; + +//================ aes ecb ===================== +static const unsigned char aes_ecb_key_buf[] = +{ + 0x60,0x3d,0xeb,0x10, 0x15,0xca,0x71,0xbe, 0x2b,0x73,0xae,0xf0, 0x85,0x7d,0x77,0x81, + 0x1f,0x35,0x2c,0x07, 0x3b,0x61,0x08,0xd7, 0x2d,0x98,0x10,0xa3, 0x09,0x14,0xdf,0xf4, +}; + +static const unsigned char aes_ecb_encrypt_text[] = +{ + 0xf3,0xee,0xd1,0xbd, 0xb5,0xd2,0xa0,0x3c, 0x06,0x4b,0x5a,0x7e, 0x3d,0xb1,0x81,0xf8, + 0x59,0x1c,0xcb,0x10, 0xd4,0x10,0xed,0x26, 0xdc,0x5b,0xa7,0x4a, 0x31,0x36,0x28,0x70, + 0xb6,0xed,0x21,0xb9, 0x9c,0xa6,0xf4,0xf9, 0xf1,0x53,0xe7,0xb1, 0xbe,0xaf,0xed,0x1d, + 0x23,0x30,0x4b,0x7a, 0x39,0xf9,0xf3,0xff, 0x06,0x7d,0x8d,0x8f, 0x9e,0x24,0xec,0xc7, +}; + +//================ aes ctr ===================== +static const unsigned char aes_ctr_iv_buf[] = +{ + 0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,0xf6,0xf7, 0xf8,0xf9,0xfa,0xfb, 0xfc,0xfd,0xfe,0xff, +}; + +static const unsigned char aes_ctr_key_buf[] = +{ + 0x8e,0x73,0xb0,0xf7, 0xda,0x0e,0x64,0x52, 0xc8,0x10,0xf3,0x2b, 0x80,0x90,0x79,0xe5, + 0x62,0xf8,0xea,0xd2, 0x52,0x2c,0x6b,0x7b, +}; + +static const unsigned char aes_ctr_plain_text[] = +{ + 0x6b,0xc1,0xbe,0xe2, 0x2e,0x40,0x9f,0x96, 0xe9,0x3d,0x7e,0x11, 0x73,0x93,0x17,0x2a, + 0xae,0x2d,0x8a,0x57, 0x1e,0x03,0xac,0x9c, 0x9e,0xb7,0x6f,0xac, 0x45,0xaf,0x8e,0x51, + 0x30,0xc8,0x1c,0x46, 0xa3,0x5c,0xe4,0x11, 0xe5,0xfb,0xc1,0x19, 0x1a,0x0a,0x52,0xef, + 0xf6,0x9f,0x24,0x45, 0xdf,0x4f,0x9b,0x17, 0xad,0x2b,0x41,0x7b, 0xe6,0x6c,0x37,0x10, +}; + +static const unsigned char aes_ctr_encrypt_text[] = +{ + 0x1a,0xbc,0x93,0x24, 0x17,0x52,0x1c,0xa2, 0x4f,0x2b,0x04,0x59, 0xfe,0x7e,0x6e,0x0b, + 0x09,0x03,0x39,0xec, 0x0a,0xa6,0xfa,0xef, 0xd5,0xcc,0xc2,0xc6, 0xf4,0xce,0x8e,0x94, + 0x1e,0x36,0xb2,0x6b, 0xd1,0xeb,0xc6,0x70, 0xd1,0xbd,0x1d,0x66, 0x56,0x20,0xab,0xf7, + 0x4f,0x78,0xa7,0xf6, 0xd2,0x98,0x09,0x58, 0x5a,0x97,0xda,0xec, 0x58,0xc6,0xb0,0x50, +}; + +//================ aes ofb ===================== +static const unsigned char aes_ofb_iv_buf[] = +{ + 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, +}; + +static const unsigned char aes_ofb_key_buf[] = +{ + 0x60,0x3d,0xeb,0x10, 0x15,0xca,0x71,0xbe, 0x2b,0x73,0xae,0xf0, 0x85,0x7d,0x77,0x81, + 0x1f,0x35,0x2c,0x07, 0x3b,0x61,0x08,0xd7, 0x2d,0x98,0x10,0xa3, 0x09,0x14,0xdf,0xf4, +}; + +static const unsigned char aes_ofb_plain_text[] = +{ + 0x6b,0xc1,0xbe,0xe2, 0x2e,0x40,0x9f,0x96, 0xe9,0x3d,0x7e,0x11, 0x73,0x93,0x17,0x2a, + 0xae,0x2d,0x8a,0x57, 0x1e,0x03,0xac,0x9c, 0x9e,0xb7,0x6f,0xac, 0x45,0xaf,0x8e,0x51, + 0x30,0xc8,0x1c,0x46, 0xa3,0x5c,0xe4,0x11, 0xe5,0xfb,0xc1,0x19, 0x1a,0x0a,0x52,0xef, + 0xf6,0x9f,0x24,0x45, 0xdf,0x4f,0x9b,0x17, 0xad,0x2b,0x41,0x7b, 0xe6,0x6c,0x37,0x10, +}; + +static const unsigned char aes_ofb_encrypt_text[] = +{ + 0xdc,0x7e,0x84,0xbf,0xda,0x79,0x16,0x4b,0x7e,0xcd,0x84,0x86,0x98,0x5d,0x38,0x60, + 0x4f,0xeb,0xdc,0x67,0x40,0xd2,0x0b,0x3a,0xc8,0x8f,0x6a,0xd8,0x2a,0x4f,0xb0,0x8d, + 0x71,0xab,0x47,0xa0,0x86,0xe8,0x6e,0xed,0xf3,0x9d,0x1c,0x5b,0xba,0x97,0xc4,0x08, + 0x01,0x26,0x14,0x1d,0x67,0xf3,0x7b,0xe8,0x53,0x8f,0x5a,0x8b,0xe7,0x40,0xe4,0x84, +}; + +//================ des ecb ===================== +static const unsigned char des_ecb_key_buf[] = +{ + 0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01, +}; + +static const unsigned char des_ecb_plain_text[] = +{ + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +static const unsigned char des_ecb_encrypt_text[] = +{ + 0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00,0xDD,0x7F,0x12,0x1C,0xA5,0x01,0x56,0x19, + 0x2E,0x86,0x53,0x10,0x4F,0x38,0x34,0xEA,0x4B,0xD3,0x88,0xFF,0x6C,0xD8,0x1D,0x4F, + 0x20,0xB9,0xE7,0x67,0xB2,0xFB,0x14,0x56,0x55,0x57,0x93,0x80,0xD7,0x71,0x38,0xEF, + 0x6C,0xC5,0xDE,0xFA,0xAF,0x04,0x51,0x2F,0x0D,0x9F,0x27,0x9B,0xA5,0xD8,0x72,0x60, +}; + +//================ des cbc ===================== +static const unsigned char des_cbc_key_buf[] = +{ + 0x01,0x23,0x45,0x67, 0x89,0xab,0xcd,0xef, +}; + +static const unsigned char des_cbc_iv_buf[] = +{ + 0x12,0x34,0x56,0x78, 0x90,0xab,0xcd,0xef, +}; + +static const unsigned char des_cbc_plain_text[] = +{ + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20, + +}; + +static const unsigned char des_cbc_encrypt_text[] = +{ + 0xe5,0xc7,0xcd,0xde,0x87,0x2b,0xf2,0x7c,0x43,0xe9,0x34,0x00,0x8c,0x38,0x9c,0x0f, + 0x68,0x37,0x88,0x49,0x9a,0x7c,0x05,0xf6, +}; + +//================ des ofb ===================== +static const unsigned char des_ofb_key_buf[] = +{ + 0x01,0x23,0x45,0x67, 0x89,0xab,0xcd,0xef, +}; + +static const unsigned char des_ofb_iv_buf[] = +{ + 0x12,0x34,0x56,0x78, 0x90,0xab,0xcd,0xef, +}; + +static const unsigned char des_ofb_plain_text[] = +{ + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,0x43,0xe9,0x34,0x00,0x8c,0x38,0x9c,0x0f, + 0x68,0x37,0x88,0x49,0x9a,0x7c,0x05,0xf6, +}; + +static const unsigned char des_ofb_encrypt_text[] = +{ + 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,0x1e,0x7e,0x5e,0x50,0xcb,0xbe,0xc4,0x10, + 0x33,0x35,0xa1,0x8a,0xde,0x4a,0x91,0x15, +}; + +//================ des3 ecb ===================== +static const unsigned char des3_ecb_key_buf[] = +{ + 0x01,0x23,0x45,0x67, 0x89,0xab,0xcd,0xef, 0x23,0x45,0x67,0x89, 0xab,0xcd,0xef,0x01, + 0x45,0x67,0x89,0xab, 0xcd,0xef,0x01,0x23, +}; + +static const unsigned char des3_ecb_plain_text[] = +{ + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,0x43,0xe9,0x34,0x00,0x8c,0x38,0x9c,0x0f, + 0x68,0x37,0x88,0x49,0x9a,0x7c,0x05,0xf6, +}; + +static const unsigned char des3_ecb_encrypt_text[] = +{ + 0x31,0x4f,0x83,0x27,0xfa,0x7a,0x09,0xa8,0xd5,0x89,0x5f,0xad,0xe9,0x8f,0xae,0xdf, + 0x98,0xf4,0x70,0xeb,0x35,0x53,0xa5,0xda, +}; + +//================ des3 cbc ===================== +static const unsigned char des3_cbc_key_buf[] = +{ + 0x01,0x23,0x45,0x67, 0x89,0xab,0xcd,0xef, 0x23,0x45,0x67,0x89, 0xab,0xcd,0xef,0x01, + 0x45,0x67,0x89,0xab, 0xcd,0xef,0x01,0x23, +}; + +static const unsigned char des3_cbc_iv_buf[] = +{ + 0x12,0x34,0x56,0x78, 0x90,0xab,0xcd,0xef, +}; + +static const unsigned char des3_cbc_plain_text[] = +{ + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,0x43,0xe9,0x34,0x00,0x8c,0x38,0x9c,0x0f, + 0x68,0x37,0x88,0x49,0x9a,0x7c,0x05,0xf6, +}; + +static const unsigned char des3_cbc_encrypt_text[] = +{ + 0xf3,0xc0,0xff,0x02,0x6c,0x02,0x30,0x89,0xc4,0x3a,0xdd,0x8f,0xd8,0xcd,0x5e,0x43, + 0x2b,0xfd,0x41,0xd3,0x13,0x0b,0xcf,0x40, +}; + +typedef struct FH_CRYPTO_CASE +{ + CRYPTO_CTRL_S stCryptoCtrl; + uint8_t* encrypto_buf; + uint8_t* decrypto_buf; + uint32_t crypto_size; + + uint8_t* key_buf; + uint8_t* iv_buf; + uint32_t key_size; + uint32_t iv_size; + + char name[8]; +} CRYPTO_CASE; + +CRYPTO_CASE stCryptoCase[] = +{ + { + .stCryptoCtrl.enKeySrc = CRYPTO_KEY_SRC_USER, + .stCryptoCtrl.enAlg = CRYPTO_ALG_AES, + .stCryptoCtrl.enWorkMode = CRYPTO_WORK_MODE_CBC, + .stCryptoCtrl.enKeyLen = CRYPTO_KEY_AES_128BIT, + .stCryptoCtrl.enIVLen = CRYPTO_IV_KEY_AES_128BIT, + .stCryptoCtrl.self_key_gen = 0, + .key_buf = (uint8_t*)aes_cbc_key_buf, + .key_size = sizeof(aes_cbc_key_buf), + .iv_buf = (uint8_t*)aes_cbc_iv_buf, + .iv_size = sizeof(aes_cbc_iv_buf), + .encrypto_buf = (uint8_t*)plain_text, + .decrypto_buf = (uint8_t*)aes_cbc_encrypt_text, + .crypto_size = 64, + .name = "aes_cbc", + }, + { + .stCryptoCtrl.enKeySrc = CRYPTO_KEY_SRC_USER, + .stCryptoCtrl.enAlg = CRYPTO_ALG_AES, + .stCryptoCtrl.enWorkMode = CRYPTO_WORK_MODE_ECB, + .stCryptoCtrl.enKeyLen = CRYPTO_KEY_AES_256BIT, + .stCryptoCtrl.enIVLen = CRYPTO_IV_KEY_AES_0BIT, + .stCryptoCtrl.self_key_gen = 0, + .key_buf = (uint8_t*)aes_ecb_key_buf, + .key_size = sizeof(aes_ecb_key_buf), + .iv_buf = NULL, + .iv_size = 0, + .encrypto_buf = (uint8_t*)plain_text, + .decrypto_buf = (uint8_t*)aes_ecb_encrypt_text, + .crypto_size = 64, + .name = "aes_ecb", + }, + { + .stCryptoCtrl.enKeySrc = CRYPTO_KEY_SRC_USER, + .stCryptoCtrl.enAlg = CRYPTO_ALG_AES, + .stCryptoCtrl.enWorkMode = CRYPTO_WORK_MODE_CTR, + .stCryptoCtrl.enKeyLen = CRYPTO_KEY_AES_192BIT, + .stCryptoCtrl.enIVLen = CRYPTO_IV_KEY_AES_128BIT, + .stCryptoCtrl.self_key_gen = 0, + .key_buf = (uint8_t*)aes_ctr_key_buf, + .key_size = sizeof(aes_ctr_key_buf), + .iv_buf = (uint8_t*)aes_ctr_iv_buf, + .iv_size = sizeof(aes_ctr_iv_buf), + .encrypto_buf = (uint8_t*)aes_ctr_plain_text, + .decrypto_buf = (uint8_t*)aes_ctr_encrypt_text, + .crypto_size = 64, + .name = "aes_ctr", + }, + { + .stCryptoCtrl.enKeySrc = CRYPTO_KEY_SRC_USER, + .stCryptoCtrl.enAlg = CRYPTO_ALG_AES, + .stCryptoCtrl.enWorkMode = CRYPTO_WORK_MODE_OFB, + .stCryptoCtrl.enKeyLen = CRYPTO_KEY_AES_256BIT, + .stCryptoCtrl.enIVLen = CRYPTO_IV_KEY_AES_128BIT, + .stCryptoCtrl.self_key_gen = 0, + .key_buf = (uint8_t*)aes_ofb_key_buf, + .key_size = sizeof(aes_ofb_key_buf), + .iv_buf = (uint8_t*)aes_ofb_iv_buf, + .iv_size = sizeof(aes_ofb_iv_buf), + .encrypto_buf = (uint8_t*)aes_ofb_plain_text, + .decrypto_buf = (uint8_t*)aes_ofb_encrypt_text, + .crypto_size = 64, + .name = "aes_ofb", + }, + { + .stCryptoCtrl.enKeySrc = CRYPTO_KEY_SRC_USER, + .stCryptoCtrl.enAlg = CRYPTO_ALG_DES, + .stCryptoCtrl.enWorkMode = CRYPTO_WORK_MODE_ECB, + .stCryptoCtrl.enKeyLen = CRYPTO_KEY_DES, + .stCryptoCtrl.enIVLen = CRYPTO_IV_KEY_AES_0BIT, + .stCryptoCtrl.self_key_gen = 0, + .key_buf = (uint8_t*)des_ecb_key_buf, + .key_size = sizeof(des_ecb_key_buf), + .iv_buf = NULL, + .iv_size = 0, + .encrypto_buf = (uint8_t*)des_ecb_plain_text, + .decrypto_buf = (uint8_t*)des_ecb_encrypt_text, + .crypto_size = 64, + .name = "des_ecb", + }, + { + .stCryptoCtrl.enKeySrc = CRYPTO_KEY_SRC_USER, + .stCryptoCtrl.enAlg = CRYPTO_ALG_DES, + .stCryptoCtrl.enWorkMode = CRYPTO_WORK_MODE_CBC, + .stCryptoCtrl.enKeyLen = CRYPTO_KEY_DES, + .stCryptoCtrl.enIVLen = CRYPTO_IV_KEY_AES_64BIT, + .stCryptoCtrl.self_key_gen = 0, + .key_buf = (uint8_t*)des_cbc_key_buf, + .key_size = sizeof(des_cbc_key_buf), + .iv_buf = (uint8_t*)des_cbc_iv_buf, + .iv_size = sizeof(des_cbc_iv_buf), + .encrypto_buf = (uint8_t*)des_cbc_plain_text, + .decrypto_buf = (uint8_t*)des_cbc_encrypt_text, + .crypto_size = 24, + .name = "des_cbc", + }, + { + .stCryptoCtrl.enKeySrc = CRYPTO_KEY_SRC_USER, + .stCryptoCtrl.enAlg = CRYPTO_ALG_DES, + .stCryptoCtrl.enWorkMode = CRYPTO_WORK_MODE_OFB, + .stCryptoCtrl.enKeyLen = CRYPTO_KEY_DES, + .stCryptoCtrl.enIVLen = CRYPTO_IV_KEY_AES_64BIT, + .stCryptoCtrl.self_key_gen = 0, + .key_buf = (uint8_t*)des_ofb_key_buf, + .key_size = sizeof(des_ofb_key_buf), + .iv_buf = (uint8_t*)des_ofb_iv_buf, + .iv_size = sizeof(des_ofb_iv_buf), + .encrypto_buf = (uint8_t*)des_ofb_plain_text, + .decrypto_buf = (uint8_t*)des_ofb_encrypt_text, + .crypto_size = 24, + .name = "des_ofb", + }, + { + .stCryptoCtrl.enKeySrc = CRYPTO_KEY_SRC_USER, + .stCryptoCtrl.enAlg = CRYPTO_ALG_3DES, + .stCryptoCtrl.enWorkMode = CRYPTO_WORK_MODE_ECB, + .stCryptoCtrl.enKeyLen = CRYPTO_KEY_DES_3KEY, + .stCryptoCtrl.enIVLen = CRYPTO_IV_KEY_AES_0BIT, + .stCryptoCtrl.self_key_gen = 0, + .key_buf = (uint8_t*)des3_ecb_key_buf, + .key_size = sizeof(des3_ecb_key_buf), + .iv_buf = NULL, + .iv_size = 0, + .encrypto_buf = (uint8_t*)des3_ecb_plain_text, + .decrypto_buf = (uint8_t*)des3_ecb_encrypt_text, + .crypto_size = 24, + .name = "des3_ecb", + }, + { + .stCryptoCtrl.enKeySrc = CRYPTO_KEY_SRC_USER, + .stCryptoCtrl.enAlg = CRYPTO_ALG_3DES, + .stCryptoCtrl.enWorkMode = CRYPTO_WORK_MODE_CBC, + .stCryptoCtrl.enKeyLen = CRYPTO_KEY_DES_3KEY, + .stCryptoCtrl.enIVLen = CRYPTO_IV_KEY_AES_64BIT, + .stCryptoCtrl.self_key_gen = 0, + .key_buf = (uint8_t*)des3_cbc_key_buf, + .key_size = sizeof(des3_cbc_key_buf), + .iv_buf = (uint8_t*)des3_cbc_iv_buf, + .iv_size = sizeof(des3_cbc_iv_buf), + .encrypto_buf = (uint8_t*)des3_cbc_plain_text, + .decrypto_buf = (uint8_t*)des3_cbc_encrypt_text, + .crypto_size = 24, + .name = "des3_cbc", + }, +}; + +void *aes_demo_proc(void *param) +{ + int ret; + int i; + int j; + int use_efuse = 0; + CRYPTO_HANDLE pCryptoHandle; + + uint8_t result[256]; + + /* 初始化加密功能 */ + ret = FH_CRYPTO_Init(); + if(ret < 0) + { + printf("[aes demo] FH_CRYPTO_Init failed, ret=%d\n", ret); + } + + /* 创建加密句柄 */ + FH_CRYPTO_CreateHandle(&pCryptoHandle); + + for(i = 0; i < (sizeof(stCryptoCase) / sizeof(CRYPTO_CASE)); i++) + { + printf("===============start %s============\n", stCryptoCase[i].name); + /* 设置加密key */ + memcpy(stCryptoCase[i].stCryptoCtrl.u32Key, stCryptoCase[i].key_buf, stCryptoCase[i].key_size); + if(stCryptoCase[i].iv_buf) + { + /* 设置加密init value */ + memcpy(stCryptoCase[i].stCryptoCtrl.u32IV, stCryptoCase[i].iv_buf, stCryptoCase[i].iv_size); + } + + /* 配置加密算法和相关参数 */ + ret = FH_CRYPTO_ConfigHandle(pCryptoHandle, &stCryptoCase[i].stCryptoCtrl); + if(ret < 0) + { + printf("[aes demo] FH_CRYPTO_ConfigHandle failed, ret=%d\n", ret); + } + + if( use_efuse && (stCryptoCase[i].stCryptoCtrl.enKeySrc == CRYPTO_KEY_SRC_EFUSE)) + { + /* 通过efuse写key */ + ret = FH_CRYPTO_WriteOTPKey(0, (uint8_t *)stCryptoCase[i].stCryptoCtrl.u32Key, + stCryptoCase[i].key_size); + if(ret < 0) + { + printf("[aes demo] FH_CRYPTO_WriteOTPKey failed, ret=%d\n", ret); + } + } + + memset(result, 0, sizeof(result)); + /* 加密数据 */ + FH_CRYPTO_Encrypt(pCryptoHandle, (uint32_t)stCryptoCase[i].encrypto_buf, + (uint32_t)result, stCryptoCase[i].crypto_size); + + ret = memcmp(stCryptoCase[i].decrypto_buf, result, stCryptoCase[i].crypto_size); + + if (ret != 0) + { + printf("[aes demo] CRYPTO_Encrypt result wrong, ret=%d\n", ret); + for(j = 0; j < stCryptoCase[i].crypto_size; j++) + { + if(stCryptoCase[i].encrypto_buf[j] != result[j]) + { + printf("no: %d, encrypto buff: 0x%x, result: 0x%x\n", + j, stCryptoCase[i].encrypto_buf[j], result[j]); + } + } + } + else + { + printf("[aes demo] CRYPTO_Encrypt memcmp pass\n"); + } + + memset(result, 0, sizeof(result)); + /* 解密数据 */ + FH_CRYPTO_Decrypt(pCryptoHandle, (uint32_t)stCryptoCase[i].decrypto_buf, + (uint32_t)result, stCryptoCase[i].crypto_size); + + ret = memcmp(stCryptoCase[i].encrypto_buf, result, stCryptoCase[i].crypto_size); + + if (ret != 0) + { + printf("[aes demo] CRYPTO_Decrypt memcmp failed, ret=%d\n", ret); + int j; + for(j = 0; j < stCryptoCase[i].crypto_size; j++) + { + if(stCryptoCase[i].decrypto_buf[j] != result[j]) + { + printf("no: %d, decrypto buff: 0x%x, result: 0x%x\n", + j, stCryptoCase[i].decrypto_buf[j], result[j]); + } + } + } + else + { + printf("[aes demo] CRYPTO_Decrypt memcmp pass\n"); + } + + } + + /* 销毁加密句柄 */ + ret = FH_CRYPTO_DestroyHandle(pCryptoHandle); + if(ret < 0) + { + printf("[aes demo] FH_CRYPTO_DestroyHandle failed, ret=%d\n", ret); + } + + /* 去初始化加密功能 */ + ret = FH_CRYPTO_DeInit(); + if(ret < 0) + { + printf("[aes demo] FH_CRYPTO_DeInit failed, ret=%d\n", ret); + } + + return 0; +} + +void aes_demo_init(void) +{ + pthread_attr_t attr; + pthread_t thrd; + struct sched_param param; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, 10240); + + param.sched_priority = 80; + pthread_attr_setschedparam(&attr, ¶m); + + if (pthread_create(&thrd, &attr, aes_demo_proc, NULL) != 0) + { + printf("[aes_demo] Create aes_demo thread failed!\n"); + } +} +``` + +## 4. 编译代码 + +输入如下命令开始编译代码: + +```bash +make clean;make +``` + +![image-20251205165931584](figures/image-20251205165931584.png) + +编译结果如下图: + +在 `bsp_demo/out/bin/` 中生成了 bsp_demo.bin 固件。 + +![image-20251205170009227](figures/image-20251205170009227.png) + +## 5. 烧录固件 + +将编译生成的 bsp_demo.bin 固件复制到共享文件夹中。 + +### 5.1 进入 uboot + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +**Hit any key to stop autoboot** + +![image-20251205171847725](figures/image-20251205171847725.png) + +### 5.2 查看设备 IP + +输入下述命令查看当前的信息 + +```bahs +pri +``` + +输出内容如下: + +![image-20251205172033034](figures/image-20251205172033034.png) + +输入下述命令进行IP配置: + +```bash +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +```bash +saveenv +``` + +配置电脑IP地址: + +![image-20251205172122432](figures/image-20251205172122432.png) + +开启 tftp: + +![image-20251205172133756](figures/image-20251205172133756.png) + +### 5.3 烧录主处理器固件 + +加载应用固件,出现下述内容则表示加载成功: + +```bash +tftp 10000000 bsp_demo.bin +``` + +![image-20251205172520750](figures/image-20251205172520750.png) + +然后输入下述命令进行准备: + +```bash +go 10000000 +``` + +**停顿一下,敲enter键,出现:msh />,再去执行后续操作:** + +![image-20251205172310038](figures/image-20251205172310038.png) + +## 6. 测试 AES + +输入 `bsp_demo -e` 开始 aes 测试: + +![image-20251208103909381](figures/image-20251208103909381.png) + +# 十一、FH8626V300L上的USB_HID实践 + +## 1. 前置准备 + +### 1.1 硬件准备 + +**包含**:串口线、FH8626V300L开发板、电源线、网线。(本章用不到 Sensor 摄像头板) + +![image-20251205171346094](figures/image-20251205171346094.png) + +### 1.2 软件准备 + +**进入 SDK 的 rt-thread 目录** + +![image-20251205155037769](figures/image-20251205155037769.png) + +**应用初始配置** + +在终端中输入如下命令进行初始配置: + +```bash +make fh8626v300_defconfig +``` + +![image-20251205155257034](figures/image-20251205155257034.png) + +**使能USB Device外设** + +在终端中输入如下命令使用图形化界面配置工程 + +```bash +make menuconfig +``` + +进入 Drivers 配置项。 + +![image-20251205162223990](figures/image-20251205162223990.png) + +进入 USB Configuration 配置项。 + +![image-20251211154139537](figures/image-20251211154139537.png) + +配置 USB HID。 + +![image-20251211154412633](figures/image-20251211154412633.png) + +选择 app demo 为 bsp_demo。 + +![image-20251205165833376](figures/image-20251205165833376.png) + +保存配置。 + +![image-20251205162418489](figures/image-20251205162418489.png) + +**进入 bsp_demo 目录** + +在终端中输入如下命令使用 VSCode 打开目前所在的目录 + +```bash +code . +``` + +bsp_demo 目录结构如下图所示: + +![image-20251205155758476](figures/image-20251205155758476.png) + +## 2. 修改 bsp_demo + +打开 `bsp_demo/startup/application.c` 文件,删除 `user_main()` 中的代码,修改测试方式为手动执行,同时添加 USB HID 测试代码。 + +```c +#include +#include +#include + +#include "rttshell.h" + +extern void sadc_demo_init(void); +extern int sdcard_demo_init(void); +extern int aes_demo_init(void); +extern int pwm_demo_init(void); +extern int gpio_demo_init(void); +extern int uart_demo_init(void); +extern int i2c_demo_init(void); +extern int rtc_demo_init(void); +extern int usb_hid_demo_init(void); + +void user_main(void) +{ +} + +static void bsp_demo_usage(void) +{ + printf("Usage:\n"); + printf(" bsp_demo -e: run aes demo\n"); + printf(" bsp_demo -t: run rtc demo\n"); + printf(" bsp_demo -i: run i2c demo\n"); + printf(" bsp_demo -a: run sadc demo\n"); + printf(" bsp_demo -p: run pwm demo\n"); + printf(" bsp_demo -g: run gpio demo\n"); + printf(" bsp_demo -u: run uart demo\n"); + printf(" bsp_demo -c: run sdcard demo\n"); + printf(" bsp_demo -h: run usb_hid demo\n"); +} + +static void bsp_demo(int argc, char *argv[]) +{ + if (argc < 2) + { + bsp_demo_usage(); + return; + } + if (strcmp(argv[1], "-e") == 0) + { + aes_demo_init(); + } + else if (strcmp(argv[1], "-u") == 0) + { + uart_demo_init(); + } + else if (strcmp(argv[1], "-g") == 0) + { + gpio_demo_init(); + } + else if (strcmp(argv[1], "-p") == 0) + { + pwm_demo_init(); + } + else if (strcmp(argv[1], "-c") == 0) + { + sdcard_demo_init(); + } + else if (strcmp(argv[1], "-a") == 0) + { + sadc_demo_init(); + } + else if (strcmp(argv[1], "-t") == 0) + { + rtc_demo_init(); + } + else if (strcmp(argv[1], "-i") == 0) + { + i2c_demo_init(); + } + else if (strcmp(argv[1], "-h") == 0) + { + usb_hid_demo_init(); + } + else + { + bsp_demo_usage(); + } +} +SHELL_CMD_EXPORT(bsp_demo, bsp demo) +``` + +## 3. 添加 USB_HID 代码 + +创建 `bsp_demo/usb_hid` 目录并在该目录下新建`usb_hid_demo.c` 。 + +```c +#include +#include +#include +#include +#include +#include +#include "types/type_def.h" +#include +#include "rttshell.h" + +#define DBG_TAG "demo.usb_hid" +#define DBG_LVL DBG_LOG +#include "rtdbg.h" + +/* HID 键盘的 Report ID 为 1 */ +#define HID_REPORT_ID_KEYBOARD1 1 + +/** + * HID 键盘输入/输出报告格式说明(Report ID = 1) + * + * 输入报告(设备 → 主机)8 字节: + * Byte 0: 修饰键(Ctrl/Shift/Alt/GUI) + * Byte 1: LED 状态(由主机控制) + * Byte 2~7: 当前按下的普通键,每字节记录一个 HID 按键码 + * + * 本 demo 中只使用: + * buf[2] 用来存放 1 个按键码 + */ +#define HID_INPUT_REPORT_LEN 8 + +/* 常用 HID Key Code 定义 */ +#define HID_KEY_CODE_a 4 +#define HID_KEY_CODE_1 30 +#define HID_KEY_CODE_UpArrow 82 +#define HID_KEY_CODE_DownArrow 81 + +/* 全局 HID 文件描述符 */ +static int g_hid_fp = 0; + +/** + * @brief 发送 HID 键盘按下事件 + * @param fp HID 设备文件描述符 + * @param num HID 键盘按键码 + */ +rt_err_t hid_key_press(int fp, char num) +{ + rt_err_t ret = -RT_ERROR; + char buf[HID_INPUT_REPORT_LEN] = {0}; + + /* 每次写 HID 报告前需调整 offset 到对应的 report ID */ + lseek(fp, HID_REPORT_ID_KEYBOARD1, SEEK_SET); + /* 填写按键码到 buf[2](标准 HID Keyboard 报告中的第一个按键位) */ + buf[2] = num; + /* 将 8 字节 HID 输入报告写入 HID 设备 */ + ret = write(fp, buf, HID_INPUT_REPORT_LEN); + if (ret < 0) + { + LOG_E("HID:WriteFail %d(L%d)", ret, __LINE__); + return ret; + } + + /* 打印调试日志 */ + switch (num) + { + case HID_KEY_CODE_a: + LOG_I("KEY 'A' pressed"); + break; + case HID_KEY_CODE_1: + LOG_I("KEY '1' pressed"); + break; + case HID_KEY_CODE_UpArrow: + LOG_I("KEY 'UP Arrow' pressed"); + break; + case HID_KEY_CODE_DownArrow: + LOG_I("KEY 'Down Arrow' pressed\n"); + break; + } + + return RT_EOK; +} + +/** + * @brief 释放按键(发送空报告) + */ +rt_err_t hid_key_release(int fp) +{ + rt_err_t ret = -RT_ERROR; + char buf[HID_INPUT_REPORT_LEN] = {0}; + + /* 将按键码清零(释放按键) */ + lseek(fp, HID_REPORT_ID_KEYBOARD1, SEEK_SET); + buf[2] = 0; + ret = write(fp, buf, HID_INPUT_REPORT_LEN); + if (ret < 0) + { + LOG_E("HID:WriteFail %d(L%d)", ret, __LINE__); + return ret; + } + + return RT_EOK; +} + +/** + * @brief USB HID demo 初始化与按键模拟循环 + * 依次模拟按下: + * 'a' → '1' → ↑ → ↓ (循环 5 次) + */ +int usb_hid_demo_init(void) +{ + int fp = 0; + int i = 0; + + /* 初始化 HID 设备(厂商 API) */ + fh_hid_init(); + /* 等待 USB 完成枚举 */ + rt_thread_mdelay(2000); + + /* 打开 HID 设备节点 */ + fp = open("/dev/hidd", O_RDWR); + if (fp == -1) + { + LOG_E("[/dev/hidd] open hidd failed"); + return 0; + } + g_hid_fp = fp; + + /* 模拟 5 轮按键输入 */ + for (i = 0; i < 5; i++) + { + LOG_I("[/dev/hidd] open hidd %d", i); + + /* 模拟按键 'a' */ + hid_key_press(fp, HID_KEY_CODE_a); + rt_thread_mdelay(10); + hid_key_release(fp); + + /* 模拟按键 '1' */ + rt_thread_mdelay(500); + hid_key_press(fp, HID_KEY_CODE_1); + rt_thread_mdelay(10); + hid_key_release(fp); + + /* 模拟上箭头 ↑ */ + rt_thread_mdelay(500); + hid_key_press(fp, HID_KEY_CODE_UpArrow); + rt_thread_mdelay(10); + hid_key_release(fp); + + /* 模拟下箭头 ↓ */ + rt_thread_mdelay(500); + hid_key_press(fp, HID_KEY_CODE_DownArrow); + rt_thread_mdelay(10); + hid_key_release(fp); + + rt_thread_mdelay(2000); + } + return 0; +} +``` + +## 4. 编译代码 + +输入如下命令开始编译代码: + +```bash +make clean;make +``` + +![image-20251205165931584](figures/image-20251205165931584.png) + +编译结果如下图: + +在 `bsp_demo/out/bin/` 中生成了 bsp_demo.bin 固件。 + +![image-20251205170009227](figures/image-20251205170009227.png) + +## 5. 烧录固件 + +将编译生成的 bsp_demo.bin 固件复制到共享文件夹中。 + +### 5.1 进入 uboot + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +**Hit any key to stop autoboot** + +![image-20251205171847725](figures/image-20251205171847725.png) + +### 5.2 查看设备 IP + +输入下述命令查看当前的信息 + +```bahs +pri +``` + +输出内容如下: + +![image-20251205172033034](figures/image-20251205172033034.png) + +输入下述命令进行IP配置: + +```bash +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +```bash +saveenv +``` + +配置电脑IP地址: + +![image-20251205172122432](figures/image-20251205172122432.png) + +开启 tftp: + +![image-20251205172133756](figures/image-20251205172133756.png) + +### 5.3 烧录主处理器固件 + +加载应用固件,出现下述内容则表示加载成功: + +```bash +tftp 10000000 bsp_demo.bin +``` + +![image-20251205172520750](figures/image-20251205172520750.png) + +然后输入下述命令进行准备: + +```bash +go 10000000 +``` + +**停顿一下,敲enter键,出现:msh />,再去执行后续操作:** + +![image-20251205172310038](figures/image-20251205172310038.png) + +## 6. 测试 USB_HID + +在 shell 中输入 `ls /dev` 命令查看启用的外设: + +![image-20251211153103483](figures/image-20251211153103483.png) + +输入 `bsp_demo -h` 开始 usb_hid 测试: + +![image-20251211152957548](figures/image-20251211152957548.png) + +![image-20251211152927056](figures/image-20251211152927056.png) + +# 十二、FH8626V300L上的USB_VCOM实践 + +## 1. 前置准备 + +### 1.1 硬件准备 + +**包含**:串口线、FH8626V300L开发板、电源线、网线。(本章用不到 Sensor 摄像头板) + +![image-20251205171346094](figures/image-20251205171346094.png) + +### 1.2 软件准备 + +**进入 SDK 的 rt-thread 目录** + +![image-20251205155037769](figures/image-20251205155037769.png) + +**应用初始配置** + +在终端中输入如下命令进行初始配置: + +```bash +make fh8626v300_defconfig +``` + +![image-20251205155257034](figures/image-20251205155257034.png) + +**使能USB Device外设** + +在终端中输入如下命令使用图形化界面配置工程 + +```bash +make menuconfig +``` + +进入 Drivers 配置项。 + +![image-20251205162223990](figures/image-20251205162223990.png) + +进入 USB Configuration 配置项。 + +![image-20251211175441100](figures/image-20251211175441100.png) + +配置 USB CDC。 + +![image-20251211175415724](figures/image-20251211175415724.png) + +选择 app demo 为 bsp_demo。 + +![image-20251205165833376](figures/image-20251205165833376.png) + +保存配置。 + +![image-20251205162418489](figures/image-20251205162418489.png) + +**进入 bsp_demo 目录** + +在终端中输入如下命令使用 VSCode 打开目前所在的目录 + +```bash +code . +``` + +bsp_demo 目录结构如下图所示: + +![image-20251205155758476](figures/image-20251205155758476.png) + +## 2. 修改 bsp_demo + +打开 `bsp_demo/startup/application.c` 文件,删除 `user_main()` 中的代码,修改测试方式为手动执行,同时添加 USB VCOM 测试代码。 + +```c +#include +#include +#include + +#include "rttshell.h" + +extern void sadc_demo_init(void); +extern int sdcard_demo_init(void); +extern int aes_demo_init(void); +extern int pwm_demo_init(void); +extern int gpio_demo_init(void); +extern int uart_demo_init(void); +extern int i2c_demo_init(void); +extern int rtc_demo_init(void); +extern int usb_vcom_demo_init(void); + +void user_main(void) +{ +} + +static void bsp_demo_usage(void) +{ + printf("Usage:\n"); + printf(" bsp_demo -e: run aes demo\n"); + printf(" bsp_demo -t: run rtc demo\n"); + printf(" bsp_demo -i: run i2c demo\n"); + printf(" bsp_demo -a: run sadc demo\n"); + printf(" bsp_demo -p: run pwm demo\n"); + printf(" bsp_demo -g: run gpio demo\n"); + printf(" bsp_demo -u: run uart demo\n"); + printf(" bsp_demo -c: run sdcard demo\n"); + printf(" bsp_demo -v: run usb_vcom demo\n"); +} + +static void bsp_demo(int argc, char *argv[]) +{ + if (argc < 2) + { + bsp_demo_usage(); + return; + } + if (strcmp(argv[1], "-e") == 0) + { + aes_demo_init(); + } + else if (strcmp(argv[1], "-u") == 0) + { + uart_demo_init(); + } + else if (strcmp(argv[1], "-g") == 0) + { + gpio_demo_init(); + } + else if (strcmp(argv[1], "-p") == 0) + { + pwm_demo_init(); + } + else if (strcmp(argv[1], "-c") == 0) + { + sdcard_demo_init(); + } + else if (strcmp(argv[1], "-a") == 0) + { + sadc_demo_init(); + } + else if (strcmp(argv[1], "-t") == 0) + { + rtc_demo_init(); + } + else if (strcmp(argv[1], "-i") == 0) + { + i2c_demo_init(); + } + else if (strcmp(argv[1], "-v") == 0) + { + usb_vcom_demo_init(); + } + else + { + bsp_demo_usage(); + } +} +SHELL_CMD_EXPORT(bsp_demo, bsp demo); +``` + +## 3. 添加 USB_VCOM 代码 + +创建 `bsp_demo/usb_vcom` 目录并在该目录下新建`usb_vcom_demo.c` 。 + +```c +#include +#include "types/type_def.h" +#include +#include +#include "rttshell.h" + +#define DBG_TAG "demo.usb_vcom" +#define DBG_LVL DBG_LOG +#include "rtdbg.h" + +static rt_device_t usb_vcom_dev = RT_NULL; // USB虚拟串口设备句柄 +static rt_thread_t vcom_rx_thread = RT_NULL; // VCOM 接收线程句柄 + +/** + * @brief USB VCOM 数据接收线程 + * + * 不断从 VCOM 设备读取数据,并打印到日志。 + */ +static void vcom_rx_thread_entry(void *parameter) +{ + char rx_buffer[128]; // 接收缓冲区 + rt_size_t rx_size; // 实际读取的数据长度 + + while (1) + { + /* 尝试从 USB VCOM 设备读取数据(非阻塞) */ + rx_size = rt_device_read(usb_vcom_dev, 0, rx_buffer, sizeof(rx_buffer) - 1); + + if (rx_size > 0) + { + /* 添加字符串结束符,保证安全打印 */ + rx_buffer[rx_size] = '\0'; + + /* 打印接收到的数据 */ + LOG_I("recv: %s", rx_buffer); + } + + /* 短暂延时避免占用过多CPU */ + rt_thread_mdelay(10); + } +} + +/** + * @brief shell 命令:向 USB VCOM 发送数据 + * + * 用法:send_to_vcom "字符串" + */ +static void send_to_vcom(int argc, char **argv) +{ + rt_size_t tx_size; + + if (argc < 2) + { + LOG_I("Usage: send_to_vcom \"string\""); + return; + } + + if (usb_vcom_dev == RT_NULL) + { + LOG_E("USB VCOM device not initialized!"); + return; + } + + /* 发送用户输入的字符串 */ + tx_size = rt_device_write(usb_vcom_dev, 0, argv[1], rt_strlen(argv[1])); + /* 发送换行,便于串口显示 */ + rt_device_write(usb_vcom_dev, 0, "\r\n", 2); + + LOG_D("Sent %d bytes to VCOM: %s", tx_size, argv[1]); +} +SHELL_CMD_EXPORT(send_to_vcom, Send string to USB VCOM); + +/** + * @brief USB VCOM 示例初始化 + * + * 初始化 USB CDC、打开 VCOM 设备、启动接收线程。 + */ +int usb_vcom_demo_init(void) +{ + rt_err_t ret; + + /* 初始化 USB CDC 功能 */ + fh_cdc_init(); + + /* 查找系统中名为 "vcom" 的 USB CDC 设备 */ + usb_vcom_dev = rt_device_find("vcom"); + if (!usb_vcom_dev) + { + LOG_E("Failed to find USB VCOM device!"); + return -1; + } + + /* 以读写 + 中断接收模式打开设备 */ + ret = rt_device_open(usb_vcom_dev, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX); + if (ret != RT_EOK) + { + LOG_E("Failed to open USB VCOM device: %d", ret); + return -1; + } + + /* 创建数据接收线程 */ + vcom_rx_thread = rt_thread_create("vcom_rx", + vcom_rx_thread_entry, + RT_NULL, + 1024, + 20, + 20); + + if (vcom_rx_thread != RT_NULL) + { + /* 启动线程 */ + rt_thread_startup(vcom_rx_thread); + LOG_I("VCOM RX thread started"); + } + else + { + LOG_E("Failed to create VCOM RX thread"); + return -1; + } + + LOG_I("USB VCOM demo initialized"); + + return 0; +} +``` + +## 4. 编译代码 + +输入如下命令开始编译代码: + +```bash +make clean;make +``` + +![image-20251205165931584](figures/image-20251205165931584.png) + +编译结果如下图: + +在 `bsp_demo/out/bin/` 中生成了 bsp_demo.bin 固件。 + +![image-20251205170009227](figures/image-20251205170009227.png) + +## 5. 烧录固件 + +将编译生成的 bsp_demo.bin 固件复制到共享文件夹中。 + +### 5.1 进入 uboot + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +**Hit any key to stop autoboot** + +![image-20251205171847725](figures/image-20251205171847725.png) + +### 5.2 查看设备 IP + +输入下述命令查看当前的信息 + +```bahs +pri +``` + +输出内容如下: + +![image-20251205172033034](figures/image-20251205172033034.png) + +输入下述命令进行IP配置: + +```bash +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +```bash +saveenv +``` + +配置电脑IP地址: + +![image-20251205172122432](figures/image-20251205172122432.png) + +开启 tftp: + +![image-20251205172133756](figures/image-20251205172133756.png) + +### 5.3 烧录主处理器固件 + +加载应用固件,出现下述内容则表示加载成功: + +```bash +tftp 10000000 bsp_demo.bin +``` + +![image-20251205172520750](figures/image-20251205172520750.png) + +然后输入下述命令进行准备: + +```bash +go 10000000 +``` + +**停顿一下,敲enter键,出现:msh />,再去执行后续操作:** + +![image-20251205172310038](figures/image-20251205172310038.png) + +## 6. 测试 USB_VCOM + +输入 `bsp_demo -v` 初始化 usb_vcom,使用串口工具连接 VCOM 后输入字符会在 MSH 终端中打印出来。 + +如在虚拟串口中输入`RT-Thread`,会在 MSH 终端中打印出来: + +![image-20251211180201322](figures/image-20251211180201322.png) + +使用 `send_to_vcom "Hello RT-Thread!"` 命令向虚拟串口发送字符串`Hello RT-Thread!`。 + +![image-20251211180228172](figures/image-20251211180228172.png) + +在 shell 中输入 `ls /dev` 命令查看启用的外设: + +![image-20251211181607385](figures/image-20251211181607385.png) + +# 十三、常电双路摄像头应用方案 + +## 1. 硬件搭建 + +### 1.1 整体硬件环境 + +将开发包中的串口、开发板、sensor板、电源板,另外加网线,搭建如下图所示,确认电源开关打开时,sensor板的指示灯均亮起。 + +![image-20251212160010400](figures/image-20251212160010400.png) + +### 1.2 Sensor 硬件确认 + +开发板套件中,一般配置了一对相同sensor:一对cv2005,或者是一对SC200AI。根据所分配到的sensor类型(sensor板正面会有文字描述),进行snesor相应的配置确认。 + +**备注 1:出现两个相同的 sensor 时,由于两路都在同一个 IIC 总线上,注意将二者的跳线帽改成不一致(一上一下即可),进行IIC地址的硬件区分,从而对应sensor驱动中不同的 IIC 地址。** + +**备注 2:该开发板为 FH8626V300L,具体可以看丝印;硬件的 mipi 已经改成了 1lane\*2 的配置,(所以不管是跑单路还是双路,基本都只能跑1lane的senosr配置)。如果想改成 2lane\*1 的需要硬件修改,FH8626V300L无法同时接入2路2lane的sensor。** + + ![image-20251212160132174](figures/image-20251212160132174.png) + +![image-20251212160136775](figures/image-20251212160136775.png) + +### 1.3 镜头滤光片确认 + +镜头的滤光片有**红外截止滤光片**和**全透滤光片**形态,正常使用时需要通过接线控制。此次demo演示,**确认镜头为红外截止滤光片**状态即可。全透滤光片,当前软件未做应用适配。 + +![image-20251212160157546](figures/image-20251212160157546.png) + +![image-20251212160201187](figures/image-20251212160201187.png) + +## 2. 基于已有固件测试 + +### 2.1 测试固件 + +**资源路径:**\FH8626V300L平台_AE部资源包_20251114\测试固件\20250915V01_双路_常电模式(sc200ai+sc200ai) + +**备注:**若是开发套件中的sensor板为cv2005,则另选择相应的测试固件调试 + +![image-20251212162402648](figures/image-20251212162402648.png) + +![image-20251212162407485](figures/image-20251212162407485.png) + +### 2.2 烧录步骤 + +**固件烧录两种方式:** + +**1)临时在线调试烧录方式 :固件格式不为.img,一般为.bin,断电后需要重新烧录** + +**2) 上电固化flash烧录方式:固件格式为.img,断电后仍保存** + + **备注: 烧录前,检查ip地址是否正确能ping通开发板** + +#### 2.2.1 **临时在线调试烧录方式** + +![image-20251212162514086](figures/image-20251212162514086.png) + +##### 2.2.1.1 **使用串口连接开发板** + +使用任意的串口终端软件与开发板连接,这里以SecureCRT软件为例。 + +![image-20251212162529270](figures/image-20251212162529270.png) + +![image-20251212162534477](figures/image-20251212162534477.png) + +![image-20251212162537349](figures/image-20251212162537349.png) + +##### 2.2.1.2 **BOOT固件烧录(通过串口以Xmodem协议烧录**) + +**一般出厂的开发板已经烧录 uboot,无须进行烧录,直接跳过。** + +若没有可以上电立刻enter键,然后将xmodem_FH8626V300_SPI_1_WIRE.img(等于rom+ram+uboot)镜像文件拖入即可。 + +![image-20251212162608398](figures/image-20251212162608398.png) + +![image-20251212162620219](figures/image-20251212162620219.png) + +![image-20251212162622921](figures/image-20251212162622921.png) + +##### 2.2.1.3 **烧录协处理器固件(通过网线tftp方式)** + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +`Hit any key to stop autoboot` + +**进入uboot:**出现下述图片所示的信息表示进入了 uboot 命令行模式。 + +![image-20251212162710073](figures/image-20251212162710073.png) + +**查看设置IP:** + +输入下述命令查看当前的信息 + +``` +pri +``` + +输出内容如下: + +![image-20251212162730048](figures/image-20251212162730048.png) + +输入下述命令进行IP配置: + +``` +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +``` +saveenv +``` + +配置电脑 IP 地址: + +![image-20251212162858438](figures/image-20251212162858438.png) + +开启 tftp: + +![image-20251212162905965](figures/image-20251212162905965.png) + +执行下述命令加载协处理器的固件。 + +![image-20251212162918525](figures/image-20251212162918525.png) + +``` +tftp 11000000 rtthread_arc_rpc.img +``` + +然后执行下述命令擦除指定区间空间 + +``` +sf probe 0 +sf erase D0000 260000 +sf write 11000000 D0000 260000 +``` + +输出下述内容表示执行成功: + +![image-20251212163018588](figures/image-20251212163018588.png) + +##### 2.2.1.4 烧录主处理器固件:应用固件 media_demo(通过网线 tftp 方式) + +加载应用固件,出现下述内容则表示加载成功: + +``` +tftp 10000000 media_demo.bin +``` + +![image-20251212163050565](figures/image-20251212163050565.png) + +然后依次输入下述命令: + +![image-20251212163139620](figures/image-20251212163139620.png) + +出现下述内容表示 boot 启动参数设置成功。 + +![image-20251212163146427](figures/image-20251212163146427.png) + +按下开发板上的 RESET_IN 按键后会自动进入内核。 + +![image-20251212163153727](figures/image-20251212163153727.png) + +#### 2.2.2 **上电固化flash烧录方式** + +**上电flash固化的方式烧录与临时在线调试方式的烧录步骤基本相同,即步骤1和步骤2 烧录方式一样,不再赘述,步骤3将应用固件的media_demo.bin转化为img镜像文件,固化到flash上。** + +![image-20251212163243997](figures/image-20251212163243997.png) + +1. **将应用固件media_demo.bin转化为镜像文件** + +![image-20251212163300535](figures/image-20251212163300535.png) + +2. **烧录应用固件的镜像文件到fhash上** + +``` +tftp 10000000 media_demo.bin.img +sf probe 0 +sf erase 0x330000 0x300000 +sf write 10000000 0x330000 0x300000 +``` + +此时烧录好相关镜像之后,添加新的bootcmd命令即可 + +``` +set bootcmd 'sf probe 0; sf read 10000000 0x330000 0x300000; go 10000000’ +sa +``` + +**此时对开发板重新上电即可进入内核。** + +### 2.3 程序运行 + +需要再次配置开发板地址 + +![image-20251212163410944](figures/image-20251212163410944.png) + +**输入**: + +vlcview -p 1234 (仅使用于 rtsp 协议流) + +vlcview -i 电脑 ip -p 1234(适用于 udp 协议流) + +使用rtsp协议流时,在vlc中输入`rtsp://192.168.70.100:1240`播放视频流。 + +使用udp协议流时,在vlc中输入`udp://@:1240`播放视频流。 + +![image-20251212163446280](figures/image-20251212163446280.png) + +vlc 预览:port 口为代码的 demo 内置,可自行修改 + +![image-20251212163457762](figures/image-20251212163457762.png) + +## 3. SDK文件夹布局熟悉 + +![image-20251212160428286](figures/image-20251212160428286.png) + +**备注1:下述涉及文件路径的为作者的本地路径,开发者选择同样的相对路径。** + +**备注2:FH8626V300L正常有四种应用开发模式,通过小核(ARC架构,RT-Thread系统)+大核(ARM架构,RT-Thread系统)组合形式进行开发,所以都需要编译arc固件demo+arm固件demo。** + +![image-20251212160502857](figures/image-20251212160502857.png) + +**本文主要介绍常电模式的固件编译** + +## 4. 编译协处理器固件 + +**备注:新增或修改 Sensor 时当前固件需更新,刚上手无需关心该小节内容** + +进入下面目录: + +```bash +/home/rtt/FH8626V300_RT_V1.0.0_20250627/make_arcfirmware/app/arc_rpc_demo +``` + +然后依次执行下述命令生成最新的协处理器固件: + +```bash +make fh8626v300_rpc_defconfig +make clean;make +``` + +编译出 arc 固件 + +![image-20251212160751591](figures/image-20251212160751591.png) + +**备注1:新增 sensor 时,此文件一定要重新编译,主要编译sensor驱动,但不做 sensor 选择(在 media_demo 中选择),sensor驱动库添加完后,使用默认配置编译即可。** + +**备注2:上述命令涉及编译,所以有可能出现工具链找不到的问题,如下:** + +![image-20251212160821405](figures/image-20251212160821405.png) + +**如果出现上面的问题,请检查富瀚微工具链是否安装正确。** + +## 5. 编译主处理器固件 + + **备注:固件配置步骤** + +**1)环境配置:执行恢复默认配置、配置开发板类型、demo类型** +**2)ISP配置:配置sensor类型、sensor幅面模式、ISP分辨率** +**3)VPU配置:配置多媒体应用、编码、JPEG等。** +**4)视频流配置:配置视频输出的协议流,rtsp或者udp协议数据流** + +### 5.1 **环境配置** + +1. **环境进入、执行默认配置**: + +首先进入 rt-thread 路径,示例如下 + +![image-20251212161122329](figures/image-20251212161122329.png) + +然后执行下述命令使能默认配置: + +```bash +make fh8626v300_defconfig +``` + +*注:如果出现下述情况,请找到对应文件赋予执行权限。* + +![image-20251212161152653](figures/image-20251212161152653.png) + +执行下述命令赋予权限,然后再次执行上述命令。 + +![image-20251212161205916](figures/image-20251212161205916.png) + +在终端输入以下命令: + +```bash +make menuconfig +``` + +在 slect app demo 这一项选择 media demo: + +![image-20251212161326877](figures/image-20251212161326877.png) + +按 ESC 键退出保存配置。 + +### 5.2 ISP选项配置 + +在同样的路径下执行下述命令: + +```bash +make appconfig +``` + +下述是执行过程可能出现的问题: + +![image-20251212161906870](figures/image-20251212161906870.png) + +如出现上述问题,可执行下述命令: + +```bash +sudo apt update +sudo apt install ncurses-dev +export TERM=linux +sudo make appconfig +``` + +然后默认的配置页面如下,用户需要与该配置一致: + +![image-20251212161459035](figures/image-20251212161459035.png) + +首先进入 Video Group 0 选项进行 Video Group 0 的配置(Video Group 1 配置流程与Video Group 0 一致),如下图所示: + +![image-20251212161510973](figures/image-20251212161510973.png) + +在 Choose sensor 中选择当前开发板使用的 Sensor,这里以 sc200ai 为例: + +![image-20251212161518845](figures/image-20251212161518845.png) + +其它选项默认即可。 + +### 5.3 VPU 选项配置 + +![image-20251212161537286](figures/image-20251212161537286.png) + +- Channel 0 为主码流;一般需要开启,并进入进行分辨率配置。 +- Channel 1 为子码流;根据需要开启,并进入进行分辨率配置。 +- Channel 2 NN 的码流;需要开启 NN 的智能检测时,该选项必须选择,并进入进行分辨率配置。 + +![image-20251212161545438](figures/image-20251212161545438.png) + +VPU 的配置如下,用户与之保持一致即可。VPU 的分辨率选择,需要 16 像素对齐。 + +![image-20251212161556526](figures/image-20251212161556526.png) + +VENC 选项配置: + +![image-20251212161603853](figures/image-20251212161603853.png) + +用户首次使用与上述配置保持一致即可。 + +### 5.4 视频流网络协议配置 + +![image-20251212161620444](figures/image-20251212161620444.png) + +视频流的网络协议选择 RTSP 协议。 + +![image-20251212161626325](figures/image-20251212161626325.png) + +### 5.5 编译应用固件 + +**备注:开发板硬件为 1lane\*2 的配置;而 SDK 的 mipi 配置默认为 2lane 的配置,如果想跑双路需要在 SDK 中对 mipi 的配置进行修改。具体代码如下:** + +![image-20251212161659575](figures/image-20251212161659575.png) + +保存上述配置,在 rt-thread 路径执行下述命令编译生成应用固件: + +```bash +make clean;make +``` + +编译过程如果出现下述问题,与之前的处理方式一致,手动赋予权限。 + +![image-20251212162015669](figures/image-20251212162015669.png) + +修改权限后重新编译,输出类似下述日志则编译成功: + +![image-20251212161736013](figures/image-20251212161736013.png) + +然后进入下述路径查看生成的固件,用户进入与下述绝对路径一致的相对路径即可。 + +![image-20251212161754708](figures/image-20251212161754708.png) + +生成所需的 media_demo.bin 应用固件如下。 + +![image-20251212161802309](figures/image-20251212161802309.png) + +把生成的需要的固件拷贝到 Windows 物理机的一个测试固件目录中进行替换。 + +## 6. 原文链接 + +原文链接:[常电双目摄像头应用方案](https://static.app.yinxiang.com/verse/share/c4hFYioqQFS-PTj_JmDGcg/I1Yp9Gn3Ske2TUum9z1F9A/?fromNote=I1Yp9Gn3Ske2TUum9z1F9A&flatten=false) + +# 十四、双路人形检测方案 + +## 1. 硬件搭建 + +### 1.1 整体硬件环境 + +将开发包中的串口、开发板、sensor板、电源板,另外加网线,搭建如下图所示,确认电源开关打开时,sensor板的指示灯均亮起。 + +![image-20251212160010400](figures/image-20251212160010400.png) + +### 1.2 Sensor 硬件确认 + +开发板套件中,一般配置了一对相同sensor:一对cv2005,或者是一对SC200AI。根据所分配到的sensor类型(sensor板正面会有文字描述),进行snesor相应的配置确认。 + +> **备注 1:出现两个相同的 sensor 时,由于两路都在同一个 IIC 总线上,注意将二者的跳线帽改成不一致(一上一下即可),进行IIC地址的硬件区分,从而对应sensor驱动中不同的 IIC 地址。** + +> **备注 2:该开发板为 FH8626V300L,具体可以看丝印;硬件的 mipi 已经改成了 1lane\*2 的配置,(所以不管是跑单路还是双路,基本都只能跑1lane的senosr配置)。如果想改成 2lane\*1 的需要硬件修改,FH8626V300L无法同时接入2路2lane的sensor。** + + ![image-20251212160132174](figures/image-20251212160132174.png) + +![image-20251212160136775](figures/image-20251212160136775.png) + +### 1.3 镜头滤光片确认 + +镜头的滤光片有**红外截止滤光片**和**全透滤光片**形态,正常使用时需要通过接线控制。此次demo演示,**确认镜头为红外截止滤光片**状态即可。全透滤光片,当前软件未做应用适配。 + +![image-20251212160157546](figures/image-20251212160157546.png) + +![image-20251212160201187](figures/image-20251212160201187.png) + +## 2. 基于已有固件测试 + +### 2.1 测试固件 + +**资源路径:** FH8626V300L平台\_AE部资源包\_20251204\测试固件\20251204V01\_双路\_常电模式_智能检测\ + +> **备注:** **若是开发套件中的sensor板类型,选择“sensor:cv2005+cv2005_fps15_fps15”版本,或者“sensor:sc200ai+sc200ai_fps15_fps15”版本** + +![image-20251215100207813](figures/image-20251215100207813.png) + +![image-20251215100216382](figures/image-20251215100216382.png) + +### 2.2 烧录步骤 + +**固件烧录两种方式:** + +**1)临时在线调试烧录方式: 固件格式不为.img,一般为.bin,断电后需要重新烧录** + +**2) 上电固化flash烧录方式: 固件格式为.img,断电后仍保存** + +> **备注: 烧录前,检查ip地址是否正确能ping通开发板** + +#### 2.2.1 **临时在线调试烧录方式** + +![image-20251212162514086](figures/image-20251212162514086.png) + +##### 2.2.1.1 **使用串口连接开发板** + +使用任意的串口终端软件与开发板连接,这里以SecureCRT软件为例。 + +![image-20251212162529270](figures/image-20251212162529270.png) + +![image-20251212162534477](figures/image-20251212162534477.png) + +![image-20251212162537349](figures/image-20251212162537349.png) + +##### 2.2.1.2 **BOOT固件烧录(通过串口以Xmodem协议烧录**) + +**一般出厂的开发板已经烧录 uboot,无须进行烧录,直接跳过。** + +若没有可以上电立刻enter键,然后将xmodem_FH8626V300_SPI_1_WIRE.img(等于rom+ram+uboot)镜像文件拖入即可。 + +![image-20251212162608398](figures/image-20251212162608398.png) + +![image-20251212162620219](figures/image-20251212162620219.png) + +![image-20251212162622921](figures/image-20251212162622921.png) + +##### 2.2.1.3 **烧录协处理器固件(通过网线tftp方式)** + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +`Hit any key to stop autoboot` + +1. **进入uboot**:出现下述图片所示的信息表示进入了 uboot 命令行模式。 + +![image-20251212162710073](figures/image-20251212162710073.png) + +2. **查看设置IP:** + +输入下述命令查看当前的信息 + +``` +pri +``` + +输出内容如下: + +![image-20251212162730048](figures/image-20251212162730048.png) + +输入下述命令进行IP配置: + +``` +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +``` +saveenv +``` + +配置电脑 IP 地址: + +![image-20251212162858438](figures/image-20251212162858438.png) + +开启 tftp: + +![image-20251212162905965](figures/image-20251212162905965.png) + +执行下述命令加载协处理器的固件。 + +![image-20251212162918525](figures/image-20251212162918525.png) + +``` +tftp 11000000 rtthread_arc_rpc.img +``` + +然后执行下述命令擦除指定区间空间 + +``` +sf probe 0 +sf erase d0000 200000 +sf write 11000000 d0000 200000 +``` + +输出下述内容表示执行成功: + +![image-20251212163018588](figures/image-20251212163018588.png) + +##### 2.2.1.4 烧录主处理器固件:应用固件 media_demo(通过网线 tftp 方式) + +加载应用固件,出现下述内容则表示加载成功: + +``` +tftp 10000000 media_demo.bin +``` + +![image-20251212163050565](figures/image-20251212163050565.png) + +然后依次输入下述命令: + +``` +备注: +1)配置boot参数(可将加载命令设置在boot中,下次上电可直接tftp加载) +set bootargs 'console=ttyS0 ,115200 root=/dev/ram0 mem=28M ip=192.168.70.100' +set bootcmd 'tftp 10000000 media_demo.bin;go 10000000' +save +``` + +输入下述命令,执行固件media_demo.bin + +``` +go 10000000 +``` + +停顿一下,敲enter键,出现:msh />,再去执行后续操作 + +![image-20251212163153727](figures/image-20251212163153727.png) + +##### 2.2.1.5 修改开发板ip + +``` +ifconfig e0 192.168.70.100 +``` + +##### 2.2.1.6 加载人形检测模型:case30083 _persondet.nbg + +``` +tftp -g -r case30083_persondet.nbg 192.168.70.50 +``` + +#### 2.2.2 **上电固化flash烧录方式** + +**上电flash固化的方式烧录与临时在线调试方式的烧录步骤基本相同,即步骤1和步骤2 烧录方式一样,不再赘述,步骤3将应用固件的media_demo.bin转化为img镜像文件,固化到flash上。** + +![image-20251212163243997](figures/image-20251212163243997.png) + +1. **将应用固件media_demo.bin转化为镜像文件** + +![image-20251212163300535](figures/image-20251212163300535.png) + +2. **烧录应用固件的镜像文件到fhash上** + +``` +tftp 10000000 media_demo.bin.img +sf probe 0 +sf erase 0x330000 0x300000 +sf write 10000000 0x330000 0x300000 +``` + +此时烧录好相关镜像之后,添加新的bootcmd命令即可 + +``` +set bootcmd 'sf probe 0; sf read 10000000 0x330000 0x300000; go 10000000’ +sa +``` + +**此时对开发板重新上电即可进入内核。** + +### 2.3 程序运行 + +需要再次配置开发板地址 + +![image-20251212163410944](figures/image-20251212163410944.png) + +**输入**:**vlcview -p 1234 (仅使用于 rtsp 协议流)** + +``` +备注: +vlcview -i 电脑 ip -p 1234(适用于 udp 协议流) + +使用udp协议流时,在vlc中输入 udp://@:1240 播放视频流。 +``` + +![image-20251212163446280](figures/image-20251212163446280.png) + +**vlc 预览**:port 口为代码的 demo 内置,可自行修改 + +``` +第一路: +rtsp://192.168.70.100:1240 +第二路: +rtsp://192.168.70.100:1246 +``` + +![image-20251212163457762](figures/image-20251212163457762.png) + +## 3. SDK文件夹布局熟悉 + +![image-20251212160428286](figures/image-20251212160428286.png) + +**备注1:下述涉及文件路径的为作者的本地路径,开发者选择同样的相对路径。** + +**备注2:FH8626V300L正常有四种应用开发模式,通过小核(ARC架构,RT-Thread系统)+大核(ARM架构,RT-Thread系统)组合形式进行开发,所以都需要编译arc固件demo+arm固件demo。** + +![image-20251212160502857](figures/image-20251212160502857.png) + +**本文主要介绍常电模式的固件编译** + +## 4. 编译协处理器固件 + +**备注:新增或修改 Sensor 时当前固件需更新,刚上手无需关心该小节内容** + +进入下面目录: + +```bash +/home/rtt/FH8626V300_RT_V1.0.0_20250627/make_arcfirmware/app/arc_rpc_demo +``` + +然后依次执行下述命令生成最新的协处理器固件: + +```bash +make fh8626v300_rpc_defconfig +make clean;make +``` + +编译出 arc 固件 + +![image-20251212160751591](figures/image-20251212160751591.png) + +> **备注1:新增 sensor 时,此文件一定要重新编译,主要编译sensor驱动,但不做 sensor 选择(在 media_demo 中选择),sensor驱动库添加完后,使用默认配置编译即可。** + +> **备注2:上述命令涉及编译,所以有可能出现工具链找不到的问题,如下:** + +![image-20251212160821405](figures/image-20251212160821405.png) + +**如果出现上面的问题,请检查富瀚微工具链是否安装正确。** + +## 5. 编译主处理器固件 + +> **备注:固件配置步骤** +> +> **1)环境配置:执行恢复默认配置、配置开发板类型、demo类型** +> +> **2)ISP配置:配置sensor类型、sensor幅面模式、ISP分辨率** +> +> **3)VPU配置:配置多媒体应用、编码、JPEG等。** +> +> **4)视频流配置:配置视频输出的协议流,rtsp或者udp协议数据流** + +### 5.1 **环境配置** + +1. **环境进入、执行默认配置**: + +首先进入 rt-thread 路径,示例如下 + +![image-20251212161122329](figures/image-20251212161122329.png) + +然后执行下述命令使能默认配置: + +```bash +make fh8626v300_defconfig +``` + +**注:如果出现下述情况,请找到对应文件赋予执行权限。** + +![image-20251212161152653](figures/image-20251212161152653.png) + +执行下述命令赋予权限,然后再次执行上述命令。 + +![image-20251212161205916](figures/image-20251212161205916.png) + +在终端输入以下命令: + +```bash +make menuconfig +``` + +在 slect app demo 这一项选择 media demo: + +![image-20251212161326877](figures/image-20251212161326877.png) + +按 ESC 键退出保存配置。 + +### 5.2 ISP选项配置 + +在同样的路径下执行下述命令: + +```bash +make appconfig +``` + +下述是执行过程可能出现的问题: + +![image-20251212161906870](figures/image-20251212161906870.png) + +如出现上述问题,可执行下述命令: + +```bash +sudo apt update +sudo apt install ncurses-dev +export TERM=linux +sudo make appconfig +``` + +然后默认的配置页面如下,用户需要与该配置一致: + +![image-20251212161459035](figures/image-20251212161459035.png) + +首先进入 Video Group 0 选项进行 Video Group 0 的配置(Video Group 1 配置流程与Video Group 0 一致),如下图所示: + +![image-20251212161510973](figures/image-20251212161510973.png) + +在 Choose sensor 中选择当前开发板使用的 Sensor,这里以 sc200ai 为例: + +![image-20251212161518845](figures/image-20251212161518845.png) + +其它选项默认即可。 + +### 5.3 VPU 选项配置 + +![image-20251212161537286](figures/image-20251212161537286.png) + +- Channel 0 为主码流;一般需要开启,并进入进行分辨率配置。 +- Channel 1 为子码流;根据需要开启,并进入进行分辨率配置。 +- **Channel 2 NN 的码流;需要开启 NN 的智能检测时,该选项必须选择,并进入进行分辨率配置。** + +![image-20251212161545438](figures/image-20251212161545438.png) + +VPU 的配置如下,用户与之保持一致即可。VPU 的分辨率选择,需要 16 像素对齐。 + +![image-20251212161556526](figures/image-20251212161556526.png) + +VENC 选项配置: + +![image-20251212161603853](figures/image-20251212161603853.png) + +用户首次使用与上述配置保持一致即可。 + +### 5.4 视频流网络协议配置 + +![image-20251212161620444](figures/image-20251212161620444.png) + +视频流的网络协议选择 RTSP 协议。 + +![image-20251212161626325](figures/image-20251212161626325.png) + +### 5.5 跑智能检测模型所需配置 + +**1)** VPU中的Channel 2 使能,双路各自的VPU的Channel 2均需要开启。 + +![image-20251215101353923](figures/image-20251215101353923.png) + +**2)** app config需要设置 + +![image-20251215101410857](figures/image-20251215101410857.png) + +![image-20251215101420450](figures/image-20251215101420450.png) + +**以上所有配置完成后,退出保存,进行下一步的编译。** + +### 5.6 编译应用固件 + +保存上述配置,在 rt-thread 路径执行下述命令编译生成应用固件: + +```bash +make clean;make +``` + +编译过程如果出现下述问题,与之前的处理方式一致,手动赋予权限。 + +![image-20251212162015669](figures/image-20251212162015669.png) + +修改权限后重新编译,输出类似下述日志则编译成功: + +![image-20251212161736013](figures/image-20251212161736013.png) + +然后进入下述路径查看生成的固件,用户进入与下述绝对路径一致的相对路径即可。 + +![image-20251212161754708](figures/image-20251212161754708.png) + +生成所需的 media_demo.bin 应用固件如下。 + +![image-20251212161802309](figures/image-20251212161802309.png) + +把生成的需要的固件拷贝到 Windows 物理机的一个测试固件目录中进行替换。 + +## 6. 框架分析 + +### 6.1 NNA + +指的是 Neural Network Accelerator,即神经(网络)加速器,根据输入的视频图像,依据离线训练出来的模型文件,完成网络的前向推理,依据目标网络类型得出推理结果,检测网络得到目标个数以及相应位置信息,识别网络得出检测目标的特征向量,供后续模块进一步分析。 + +### 6.2 检测模型 + +富瀚微电子主要支持下列各种检测类型,及其相应组合模型,**通常采用非通用模型,也可通过提供训练工具,进行自行训练适配。** + +![image-20251215101633222](figures/image-20251215101633222.png) + +### 6.3 NNA数据流程 + +![image-20251215101804370](figures/image-20251215101804370.png) + +### 6.4 部署流程 + +#### 6.4.1 加载流程: + +![image-20251215101831843](figures/image-20251215101831843.png) + +#### 6.4.2 NNA初始化: + +![image-20251215101845234](figures/image-20251215101845234.png) + +#### 6.4.3 NNA检测输出: + +![image-20251215101855106](figures/image-20251215101855106.png) + +## 7. 原文链接 + +原文链接:[双路人形检测方案](https://static.app.yinxiang.com/verse/share/c4hFYioqQFS-PTj_JmDGcg/I1Yp9Gn3Ske2TUum9z1F9A/?fromNote=I1Yp9Gn3Ske2TUum9z1F9A&flatten=false) + +# 十五、低功耗AOV双路智能方案 + +## 1. 硬件搭建 + +### 1.1 整体硬件环境 + +将开发包中的串口、开发板、sensor板、电源板,另外加网线,搭建如下图所示,确认电源开关打开时,sensor板的指示灯均亮起。 + +![image-20251212160010400](figures/image-20251212160010400.png) + +### 1.2 Sensor 硬件确认 + +开发板套件中,一般配置了一对相同sensor:一对cv2005,或者是一对SC200AI。根据所分配到的sensor类型(sensor板正面会有文字描述),进行snesor相应的配置确认。 + +> **备注 1:出现两个相同的 sensor 时,由于两路都在同一个 IIC 总线上,注意将二者的跳线帽改成不一致(一上一下即可),进行IIC地址的硬件区分,从而对应sensor驱动中不同的 IIC 地址。** + +> **备注 2:该开发板为 FH8626V300L,具体可以看丝印;硬件的 mipi 已经改成了 1lane\*2 的配置,(所以不管是跑单路还是双路,基本都只能跑1lane的senosr配置)。如果想改成 2lane\*1 的需要硬件修改,FH8626V300L无法同时接入2路2lane的sensor。** + + ![image-20251212160132174](figures/image-20251212160132174.png) + +![image-20251212160136775](figures/image-20251212160136775.png) + +### 1.3 镜头滤光片确认 + +镜头的滤光片有**红外截止滤光片**和**全透滤光片**形态,正常使用时需要通过接线控制。此次demo演示,**确认镜头为红外截止滤光片**状态即可。全透滤光片,当前软件未做应用适配。 + +![image-20251212160157546](figures/image-20251212160157546.png) + +![image-20251212160201187](figures/image-20251212160201187.png) + +## 2. 基于已有固件测试 + +### 2.1 测试固件 + +**资源路径:**\FH8626V300L平台\_AE部资源包\_20251114\测试固件\20251025V01\_双路AOV\_智能检测_测试固件(sc200ai+sc200ai) + +> **备注:** **若是开发套件中的sensor板为cv2005,则另选择相应的测试固件调试** + +![image-20251212164611125](figures/image-20251212164611125.png) + +![image-20251212164623182](figures/image-20251212164623182.png) + +### 2.2 烧录步骤 + +**固件烧录两种方式:** + +**1)临时在线调试烧录方式 :固件格式不为.img,一般为.bin,断电后需要重新烧录** + +**2) 上电固化flash烧录方式:固件格式为.img,断电后仍保存** + +> **备注: 烧录前,检查ip地址是否正确能ping通开发板** + +#### 2.2.1 **临时在线调试烧录方式** + +![image-20251212162514086](figures/image-20251212162514086.png) + +##### 2.2.1.1 **使用串口连接开发板** + +使用任意的串口终端软件与开发板连接,这里以SecureCRT软件为例。 + +![image-20251212162529270](figures/image-20251212162529270.png) + +![image-20251212162534477](figures/image-20251212162534477.png) + +![image-20251212162537349](figures/image-20251212162537349.png) + +##### 2.2.1.2 **BOOT固件烧录(通过串口以Xmodem协议烧录**) + +**一般出厂的开发板已经烧录 uboot,无须进行烧录,直接跳过。** + +若没有可以上电立刻enter键,然后将xmodem_FH8626V300_SPI_1_WIRE.img(等于rom+ram+uboot)镜像文件拖入即可。 + +![image-20251212162608398](figures/image-20251212162608398.png) + +![image-20251212162620219](figures/image-20251212162620219.png) + +![image-20251212162622921](figures/image-20251212162622921.png) + +##### 2.2.1.3 **烧录协处理器固件(通过网线tftp方式)** + +按下开发板的电源开关按键复位,出现下述内容后立刻按回车键: + +`Hit any key to stop autoboot` + +**1)进入uboot**:出现下述图片所示的信息表示进入了 uboot 命令行模式。 + +![image-20251212162710073](figures/image-20251212162710073.png) + +**2)查看设置IP:** + +输入下述命令查看当前的信息 + +``` +pri +``` + +输出内容如下: + +![image-20251212162730048](figures/image-20251212162730048.png) + +输入下述命令进行IP配置: + +``` +setenv ipaddr 192.168.70.100 +setenv serverip 192.168.70.50 +setenv netmask 255.255.255.0 +setenv gatewayip 192.168.70.1 +``` + +执行下述命令保存配置: + +``` +saveenv +``` + +配置电脑 IP 地址: + +![image-20251212162858438](figures/image-20251212162858438.png) + +开启 tftp: + +![image-20251212162905965](figures/image-20251212162905965.png) + +执行下述命令加载协处理器的固件。 + +![image-20251212162918525](figures/image-20251212162918525.png) + +``` +tftp 11000000 rtthread_arc_FH8626V300.bin.img +``` + +然后执行下述命令擦除指定区间空间 + +``` +sf probe 0 +sf erase d0000 200000 +sf write 11000000 d0000 200000 +``` + +输出下述内容表示执行成功: + +![image-20251212163018588](figures/image-20251212163018588.png) + +##### 2.2.1.4 **烧录智能检测的模型:case32010.bin.img(通过网线 tftp 方式)** + +![image-20251212164941997](figures/image-20251212164941997.png) + +执行下述命令加载智能检测模型的固件。 + +``` +tftp a1000000 case32010.bin.img +``` + +然后执行下述命令擦除指定区间空间 + +``` +sf probe 0 +sf erase 930000 200000 +sf write 11000000 930000 200000 +``` + +##### 2.2.1.5 烧录主处理器固件:应用固件 **rpc_video _demo.bin**(通过网线 tftp 方式) + +加载应用固件,出现下述内容则表示加载成功: + +``` +tftp 10000000 rpc_video_demo.bin +``` + +![image-20251212163050565](figures/image-20251212163050565.png) + +然后输入下述命令进行准备: + +``` +go 10000000 +``` + +**停顿一下,敲enter键,出现:msh />,再去执行后续操作:** + +![image-20251212165151970](figures/image-20251212165151970.png) + +![image-20251212165204532](figures/image-20251212165204532.png) + +#### 2.2.2 **上电固化flash烧录方式** + +**上电flash固化的方式烧录与临时在线调试方式的烧录步骤基本相同,即步骤1和步骤2 烧录方式一样,不再赘述,步骤3将应用固件的media_demo.bin转化为img镜像文件,固化到flash上。** + +##### 2.2.2.1 **将应用固件rpc_video_demo.bin转化为镜像文件** + +![image-20251212163300535](figures/image-20251212163300535.png) + +##### 2.2.2.2 **烧录应用固件的镜像文件到fhash上** + +``` +tftp 11000000 rpc_video_demo.bin.img +sf probe 0 +sf erase 330000 300000 +sf write 11000000 330010 300000 +``` + +此时烧录好相关镜像之后,添加新的bootcmd命令即可 + +``` +配置boot参数 +set bootargs 'console=ttyS0 ,115200 root=/dev/ram0 mem=28M ip=192.168.70.100' +set bootcmd 'sf probe 0;sf write 11000000 330010 300000;go 10000000' +sa +``` + +**此时对开发板重新上电即可进入内核。** + +### 2.3 程序运行 + +需要再次配置开发板地址 + +![image-20251212163410944](figures/image-20251212163410944.png) + +为能够进行直接的拉流预览,强行`aov-enable 0`停止了aov,可直接通过vlc软件进行拉流即时预览; + +**执行命令:** + +``` +rpc_video_demo --ip 192.168.70.50 --port 1234 --aov-enable 0 --aovnn-enable 1 +``` + +> 备注1: +> 如果正常AOV运行,一秒一帧,不符合连续视频拉流播放要求;需要aov-enable 1,通过记录缓存的视频进行查看, +> 在/FH8626V300_RT_V1.0.0_20250627/rt-thread/app/rpc_video_demo通过查找宏定义”OPEN_RECORD“查看;编译arm固件时,打开”open record“选项 +> +> 备注2: +> +> ​ 完整初始控制命令,可查看ARM核的demo代码:/FH8626V300_RT_V1.0.0_20250627/rt-thread/app/rpc_video_demo/startup/demo_entry_rtt.c: +> +> rpc_video_demo --ip 192.168.70.50 --aov-enable 1 --port 8080 --interval 1000 --frame 30 --venc-mempool 50 --aovnn-enable 1 --aovnn-threshold 500 --aovmd-enable 1 --aovmd-threshold 50 --aov-sleep 1 + +**vlc预览(udp协议流)** + +* 第一路:udp://@:1234 +* 第二路:udp://@:1237 + +## 3. SDK文件夹布局熟悉 + +![image-20251212160428286](figures/image-20251212160428286.png) + +**备注1:下述涉及文件路径的为作者的本地路径,开发者选择同样的相对路径。** + +**备注2:FH8626V300L正常有四种应用开发模式,通过小核(ARC架构,RT-Thread系统)+大核(ARM架构,RT-Thread系统)组合形式进行开发,所以都需要编译arc固件demo+arm固件demo。** + +![image-20251212160502857](figures/image-20251212160502857.png) + +**本文主要介绍AOV模式的固件编译** + +## 4. 编译协处理器固件 + +1. **进入AOV模式的协处理器固件编译路径,直接选择”configs“中某一默认配置编译:** + +**以双路aov为例,拷贝configs中的fh8626v300_aov_double_defconfig文件名,执行:** + +```bash +make fh8626v300_aov_double_defconfig +make clean;make +``` + +编译出 arc 固件 + +![image-20251212165447200](figures/image-20251212165447200.png) + +2. **若自行进行配置选择,可在默认配置基础上进行手动修改**: + +```bash +make fh8626v300_aov_double_defconfig (恢复双路aov默认配置) +make fh8626v300_aov_defconfig (恢复单路aov默认配置) +``` + +接着执行下述命令,打开UI界面进行相关参数配置: + +![image-20251212165525437](figures/image-20251212165525437.png) + +![image-20251212165530276](figures/image-20251212165530276.png) + +![image-20251212165535628](figures/image-20251212165535628.png) + +![image-20251212165538820](figures/image-20251212165538820.png) + +VPU 的配置如下,用户与之保持一致即可。VPU 的分辨率选择,需要 16 像素对齐 + +![image-20251212165545957](figures/image-20251212165545957.png) + +VENC 选项配置: + +![image-20251212165600556](figures/image-20251212165600556.png) + +配置完毕后,保存退出,进行编译协处理器固件。 + +```bash +make clean;make +``` + +![image-20251212165615348](figures/image-20251212165615348.png) + +将生成的协处理器固件复制到window的测试固件目录中进行替换,烧录应用即可。 + +## 5. 编译主处理器固件 + +> **备注:固件配置步骤** +> +> **1)环境配置:执行恢复默认配置、配置开发板类型、demo类型** +> **2)ISP配置:配置sensor类型、sensor幅面模式、ISP分辨率** +> **3)VPU配置:配置多媒体应用、编码、JPEG等。** +> **4)视频流配置:配置视频输出的协议流,rtsp或者udp协议数据流** + +### 5.1 **执行默认配置编译**: + +![image-20251212165749902](figures/image-20251212165749902.png) + +执行编译命令: + +```bash +make clean;make +``` + +编译生成的结果存在于: + +![image-20251212165808941](figures/image-20251212165808941.png) + +将生成的主处理器固件复制到window的测试固件目录中进行替换,烧录应用即可。 + +### 5.2 **基于默认配置进行用户修改编译:** + +![image-20251212165833789](figures/image-20251212165833789.png) + +![image-20251212165836973](figures/image-20251212165836973.png) + +![image-20251212165840316](figures/image-20251212165840316.png) + +![image-20251212165843110](figures/image-20251212165843110.png) + +执行编译命令: + +```bash +make clean;make +``` + +编译生成的结果存在于: + +![image-20251212165905257](figures/image-20251212165905257.png) + +将生成的主处理器固件复制到window的测试固件目录中进行替换,烧录应用即可。 + +## 6. 原文链接 + +原文链接:[低功耗AOV双路智能摄像头](https://static.app.yinxiang.com/verse/share/c4hFYioqQFS-PTj_JmDGcg/I1Yp9Gn3Ske2TUum9z1F9A/?fromNote=I1Yp9Gn3Ske2TUum9z1F9A&flatten=false)