From 3159d3ae1adec5aa8017238235221421f397f789 Mon Sep 17 00:00:00 2001 From: Robofish <1683502971@qq.com> Date: Thu, 7 Aug 2025 04:40:31 +0800 Subject: [PATCH] =?UTF-8?q?can=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89id=E8=A7=A3=E6=9E=90=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 6148 -> 8196 bytes .vscode/settings.json | 7 +- .../about_interface.cpython-39.pyc | Bin 2088 -> 2268 bytes app/__pycache__/ai_interface.cpython-39.pyc | Bin 5290 -> 5288 bytes ...ode_configuration_interface.cpython-39.pyc | Bin 0 -> 6263 bytes .../code_generate_interface.cpython-39.pyc | Bin 0 -> 7908 bytes app/__pycache__/data_interface.cpython-39.pyc | Bin 25606 -> 21931 bytes .../function_fit_interface.cpython-39.pyc | Bin 7692 -> 7765 bytes app/__pycache__/home_interface.cpython-39.pyc | Bin 1744 -> 2070 bytes app/__pycache__/main_window.cpython-39.pyc | Bin 3480 -> 3480 bytes .../mini_tool_interface.cpython-39.pyc | Bin 3735 -> 3763 bytes .../part_library_interface.cpython-39.pyc | Bin 6919 -> 6960 bytes .../serial_terminal_interface.cpython-39.pyc | Bin 5838 -> 5838 bytes app/code_generate_interface.py | 77 ++-- .../__pycache__/bsp_interface.cpython-39.pyc | Bin 0 -> 29483 bytes .../component_interface.cpython-39.pyc | Bin 0 -> 15873 bytes app/code_page/bsp_interface.py | 141 ++++-- .../__pycache__/analyzing_ioc.cpython-39.pyc | Bin 0 -> 6849 bytes .../__pycache__/check_update.cpython-39.pyc | Bin 661 -> 661 bytes .../__pycache__/code_generator.cpython-39.pyc | Bin 0 -> 3039 bytes .../code_task_config.cpython-39.pyc | Bin 0 -> 8495 bytes .../__pycache__/part_download.cpython-39.pyc | Bin 1710 -> 1710 bytes .../__pycache__/update_code.cpython-39.pyc | Bin 0 -> 1170 bytes app/tools/code_generator.py | 30 +- assets/.DS_Store | Bin 0 -> 6148 bytes assets/User_code/.DS_Store | Bin 6148 -> 6148 bytes assets/User_code/bsp.zip | Bin 0 -> 17715 bytes assets/User_code/bsp/can.c | 411 ++++++++++-------- assets/User_code/bsp/can.h | 127 +++++- assets/User_code/bsp/gpio.c | 9 +- assets/User_code/bsp/gpio.h | 4 +- assets/User_code/bsp/spi.c | 32 +- assets/User_code/bsp/uart.c | 2 +- assets/User_code/component/ui.h | 16 +- assets/User_code/component/user_math.c | 26 +- assets/User_code/component/user_math.h | 19 +- assets/User_code/config.csv | 2 +- gpio.h | 5 +- 38 files changed, 558 insertions(+), 350 deletions(-) create mode 100644 app/__pycache__/code_configuration_interface.cpython-39.pyc create mode 100644 app/__pycache__/code_generate_interface.cpython-39.pyc create mode 100644 app/code_page/__pycache__/bsp_interface.cpython-39.pyc create mode 100644 app/code_page/__pycache__/component_interface.cpython-39.pyc create mode 100644 app/tools/__pycache__/analyzing_ioc.cpython-39.pyc create mode 100644 app/tools/__pycache__/code_generator.cpython-39.pyc create mode 100644 app/tools/__pycache__/code_task_config.cpython-39.pyc create mode 100644 app/tools/__pycache__/update_code.cpython-39.pyc create mode 100644 assets/.DS_Store create mode 100644 assets/User_code/bsp.zip diff --git a/.DS_Store b/.DS_Store index 6e47c2fd93d99c4cb3fe7bc95b1923d42380c5f7..765ded4c1e4392be57adfb1b629e6e33bd5308d7 100644 GIT binary patch literal 8196 zcmeI1&2G~`5Xb-9rj0`dic}E2AX(yCm9|u^5E4q$=1>VZ)CdlIgt)O<3)hZfhX7Sk zI2PW4SK!DCa7N<7GjQV0sr+}>t(;BEr4p)OH`<-`dd4&R^ZH{P0HWS&F90(D99Ai- zQ*2Hsa=)x2Wh@_=rWCYCvgJpK&#mf+t{t!hECEZv60ig;f%8Ft&um$oQ=a>JuWc;> zOW?mGAny+@tCY1|4zyIa4mK(Upe%7%753H3Kcy=NC~LVKXvq;4p-m~ZsmN0dk>?IV zn{$6H*B@x9%^{R$9w+xK@(e}fsfTctIz&xN+gbvaz$gKkyN{!V4mulAF@G1=cyawa zR7IIhQY+;zK!()N{q-kZzn^yU?*gCwP86ou{QP$@HeQ;TEIVaq%6aPTBz-SyWxcfC z>OPiR50WJEkNPeDVHotA)yr#1oVCI@=qiJ-9Z==TqcCnK{d&@i+o`hk^bV)uRGQVR zdwVzMXWfOBmHkI62T3ruT2aJD#=yZW7yEc_9+aVe14W9}DP; zx;w+VV>}V!QbD(jyV$@Q8n_P+4MTg8u%Bt|!$bBj;2t&^gU^~V5_y8m75;@D?i6e) zhD`^rhrOul=WQXTDZ?V=%mZ`QY9>Xi=^?8P#B%ZQN{sjm&}Fm%ULhFvjaB1%tk73X z)*-eO>yc>jW@LVwq_>K7`ft$7uDP`FgXF#zh?E&uprV_jH-iQ~84;D6@V*_qi|QvH zo6!uNAsS=AF-rUVR~&3(37nO{xIVy)%>NswfB!$L8*6U~SOVvmfGDkd>vaZr^!{tc zDsyd@^*O67Qg5K8GGU|AaY~hrQy%|e$i7QeX;aJPKueCW*be~;gKaEE zPM+K%qQ9|h1IuD|4h}(Ppkg2p;06+|AblGPzcWwfmvICc%)rRNzyhL~ASQ#wHplbK GVFm!JGZjSu diff --git a/.vscode/settings.json b/.vscode/settings.json index eaab07f..ec48fa4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,11 @@ "files.associations": { "user_math.h": "c", "bsp.h": "c", - "stdint.h": "c" + "stdint.h": "c", + "array": "c", + "string": "c", + "string_view": "c", + "vector": "c", + "can.h": "c" } } \ No newline at end of file diff --git a/app/__pycache__/about_interface.cpython-39.pyc b/app/__pycache__/about_interface.cpython-39.pyc index 8c795a0f4c8460f74e9e438c5c524a9e4fd39e33..ab4ca22ae74b379375a35018b8e6238fc9264510 100644 GIT binary patch delta 1008 zcmYjPPiPcZ7=Q20+nL$I7q^}Z`{mwW;UJo zwpCe))Ev}S>GCcG2_!vL5D$f7Xw6k9z4kPCGb!DJ^d@-od$Ykh%lqy3=QrPczwdp& zlpYUzb=S2JJo}&hIRAOE=Z)i~-o9OnvF_^_F~qdUh)v(jZ5kD0%eP|Nw{yP$zT-Qw z>$|b%dl1u^5e>y9zm(_AXgD76N5C%nqbCrvn7xFU9pG!4UuMoUs^8Y7IXQjCPjsC3Bqu`XG$Sz#4J$YHv0TOKo*DTeN#Wx|TL=oQ+ftVG%MB_+frwNIlWMCgh?|sftVI$Q=7$O@{xANdJO^|96lj;(rt2z z9$&l(?&Wg=349G-!Cjml5oARZl!2d%DztRatab4n#OSitMZ##AtibeJ1&op%UCdAi zrM@V%ic0uazBtIwpyVxzgmq~NBlQE8tuASc<*<`^nX@P%`v>!IPhUPXFT?^rT&*@k zG2b~q*=WbrW;LTDmKBv|9c7dAz9{#ZT;Ma|{-#6A* z{<$GHA70&9`~Khc^}#ToT>UP*4uh@~(lH>X+ZDVi!@`3}CmmAGgaQK~GujJ50?U!= zDx_{9GkB)~tHD!SzOU~-um@tkK4>6)Td{I@M_F$GsKeg{K$u_?Q{u_n`r@bR9`bzV z&doKVI_Hfbist5CDX~{k@;W83TsWKpnAqE%s>tceHaTrfeUSH-*=H`*#G%QWIME3Q zy?b9@h&r$x-{wotw{`(u%yp!;vK)EO7{{Lc(-{Bcf9b0FD~-Gql$l53HtR&eQ49>O QXk}c&4k_U>ap0el7h^~M;Q#;t delta 841 zcmYjOO=}ZD7@l`__9L6kHmUK{R#HW6ENHt$*VY%mf9KS;hFb+=KY%QskceHkVu$FEN!@c zf5d3m-M||Cy|(~SL={gf>yBPF9HV_F;vREiWz#XsaVIWpD%CuzoNy9tzwX)P4yQwK z!%1F3G)B!SL`@g!ij$)88z^fvR{K?G;$hbKJB0^|jZ~V?!yTCAe_(I|Q?Zu`AZAb{ zLUmkIB4vp%wG>+hKoMRtBSkV6r-WIhgv`(E1+<8%K0|6GBBhR{WQ0noeLazkB9Yt3 zId);xud>S(<_2ShqWdc?8m}G}(0ch{b3Hkmxq96n^;zbo?|Y;EWBwK2g-)JTM!@9H zl`cKdgf`ImiX!bcxz-~eTjGQn0SGKGu^}*tO@X{dh9)9mf0|>6K^%r9EpIUDhjR$oklgP@A-{g{|Kt|5ybQ-4*|(7REC`No+`ep zx{WG$K=w_<&~toRJ#*odC}ijJo9&gg)~lJ;m&w+<`JWq&t?9YVPrS9xH$T4K-q_e$ zSlya?|6}sS`1B!!vTD#NUIl`p;3(fw*ScasLSA|#7y_DlSS=RaFbrb+n|5rVSK2hM zz}%1pC#9+leUfDa$P*3~M8^9KSPmy&iATd=q| zArWAJoercWm+j=g^|L3M_Jc96>Q>mJaeB{X;og@CMZ4S}CYj0a8r@*=XGZtX|8``U f0~z=0ZW`yxKCOE0c@Tt$a{}jL@lGFq`*pFzp%8VC_gE`M6V>jU^64jN&x^= C3=azc delta 50 zcmZ3Xxk{5ak(ZZ?0SMR~n=_I&^4?<>)5s_(DX`MlH#9ZTGd9;VGBnjQGBViwpLwMK E06S+5DF6Tf diff --git a/app/__pycache__/code_configuration_interface.cpython-39.pyc b/app/__pycache__/code_configuration_interface.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b341a8849e645891f41b253bc0481a4866a9a24d GIT binary patch literal 6263 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 literal 0 HcmV?d00001 diff --git a/app/__pycache__/data_interface.cpython-39.pyc b/app/__pycache__/data_interface.cpython-39.pyc index 41a00567e1db946ec0754dc6263614c8e3fda5bf..e389e440b75e3cd7b6ae8b5f2f3959a48b072748 100644 GIT binary patch delta 10858 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 literal 25606 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 diff --git a/app/__pycache__/function_fit_interface.cpython-39.pyc b/app/__pycache__/function_fit_interface.cpython-39.pyc index 28423999dff7362fb1aa9e0a71eafb0c0552abb8..dd6a1b81e2ec0984982909835c6c012e0b4abbe8 100644 GIT binary patch delta 2143 zcmZuyU2NM_6!uMQ$4QekYtyu8o6hUTI=3*2#3nXEH?-05+imQRnT^bioi>>hr^im4 zR;enj8=7Dhn=TJX2-Z$W2nivkN-!jZgm^@I;DHy52Oc&A5|4loLKElSW`7m7?(y;Y zyZ4^&+;cBwf6T^>SS%voGx*o#$=c>C@m})lm7(H7Ii;t{oq8t`Ou>}wEY6D@M+B{vCdjQGE#Sv&$1rm<4xAl#oU^`iqRFlPLB5lSPH%+1 zBApbJJH)3`;hWN9xS#gbeUWYw8$cFRB$@=nwA7;Y9l{?!2+j<=#&n#VWZVuUb$Y$! z`=Qgw;k1G6!@gMbtnxZbKb)PgDptJ;Bj@PH(W7LT{u|wx)x%(wooVY;XGRl&Poub& zZRI`7^hKP|1r~T+FxZK*1$rX(LY(0c!m$sBdyRe;>t6WK3pB_gnGZICrQp2S5K7{* zWQr?<2o13$o02J;p{2ln;q<9_iEBeE!o18mr6DsrFWitAh8F^9VUeKa@TtIjXkPIm z4aF2{1kQUc4P}v30%ibb3Ul9RLvDl`;f0kT5vEF0drblHP{v>rE)7^t|4BYq&s(-S zTC^=!-8Q(rZo7322-Ei>IjRNpP`Oyi;lA~jX~V8rZqBLLvsw&f)a$JimUpmfRak&A zqijJErM_(Bz2dY5!_1_`U9ddN=02xZ@$@hv0W6#gI%?r{W*@dHHS{%5#WLpyT@TLtK^{glRbd@)-1Ed=3CiGA_eN9}+EeKdncMX=^R5G?QpO z+rey#NHDuq%s3XKix%j?Y7}fn%1kZtv{cx?!^rn>Ehi^FAb-AxBeh)m){p&z8W z=}O|}f{IE_;V^QvdK?dE5@y9z^@>gfo%pJ1D8>VYSmhb| zd@Z_M&#~jE%d`A@fAi8r8Z{Wu#=DKP9NY*a8UfwBJN4`W0 zFp$jcpx2`v^x5Pwo|HA0Ii`K6(gbLr?8aTM-%Q30A@Rj=JUep=7&9uv2m6wQHS2&c z*~YkKV=J@Fx#(!o!#1PlYcOriwNHRiom8EIYN&-;1&@?dfy@CGlGRErj^vlOuin0V z@%DvJZ-4#HZdL0AmNM9b#1FZaca&i>%KieCsxKJ;#wal*E!#tgzaqUv%~-*X8&v^!s7;_s#=E zR*?mb?n-OwAhL5^rd3ecLbuhm-4PWZu)G>nR2ZP=(od5^^qcgf>*HNQ&!1QCq*X!= z(~UhnGRqj$>E52l`8@+4vHx|8coAiP)1{ut1$IyIYlmL~yww0ZU~5>gO#)jnuxWs~ z`LSFsZyTR1KxPv)9Fel&FN%~W!H<<`1*bJL5 J@^KOg{s*)O1_=NF delta 2038 zcmZWqZ)_Ar6yLeqz1zF?u19;lw%310g|9VzTp^dGGcDKb-5#@h z^e9&wsVD&o;z*()hSrb>i5j$q#HbjfpD=`&=m*CbC816D=r=wY-%Kli&b!Q;-^{%C zX6E^ zRB(i#Nx#{R)m@4ay{jm!8Qq?3@cp16&VCPmh3eUP{U2nq_d++d9yo37>`*v~BFh2N zHV}qJd)ZW#(Y751+)tfRx<{-@@rppJK#a0qs($Ku4UpmEzTTBw&3YtPp~*w(VUj1M z0_}T)-KgG;dRcpPu>a7I_d-0N&CvNak4 z6oj?`n)?>}Ig*?>=J}@mWi*4v{bglDoz}2AgOF18j|8TJGs;F~|CVu8uIMw$xF%7k ztO*@2TvjI$Xe`_38xM>Jy(+J|9GpaxXk3?ik+N0}l=T@uQVyAi)?fvg)dpxg>`n!3 zW6AzhX^_~dO<9|`sqPiMCEG2fWM@zW8b*{|k0vI#uYk=kB^J&QVL*Ff&8%{X2UKiu zig}L*4qJASxIExFcGmUiUa`rmAb5!6i#b9qk5F-U?uS)s0y07i9I6G&JIGOn`|yyd z1C1GMd6uM-`v)DHKch+KbieRf5!0t(?l?3z4nje3q@pmYMo}qa?9W7!U8-q{YOol9 zCYj$Rncq@YrhUMvzwF0K5z#H4e?$eWVr|%m15-ZWT^-TN2nVq~n$J*#Dj4DVlMA)0<2~8n3RkF6$dfdo>*(^ut1@WaNSMR$`ModoCSs< znYXhuv8Jwy>#hNVbI{ys5DVAUk&bHF?L;HH7rQwjUxF?JBxAreYUPKCKimtqEv$o|1CABl(#S9ihu z1GcqxPxyYW_pvLr-*=bQ3-HW8^yBc93MsBn*W##5c73`I*DRtqjG`^ZW7uQw^My~kiKIk~YkL(UJ;j~D?YX1Dy`KiyKfM^h2hjPuf4iFn^ z4#7oWK$$;vaqgWHYg0u(4DP;vZNc>IZ|8TOzdCo}`rPE%2lN%A_YLNbe=_&Y*|jO7 zMRG{{V1)M}1q*HUVD*VFqjh zl?>Bo#moQ*UR`kPBbgzG=8CpOH?Yn`M@*D58TG|uvAu~7w2K{0G{q|z+6^dR5!q}MoflM z;!xcsV{JGEKT5nJ&8O&c_G8mJwEf-Wys&jb}*~CIUvZPqwHAo6SDl% zOJZDc_N_4YH@nq*a6)`ONR>J6&i-YYuL4x6QMxC%45r=!)%~+Rhy_@ zG!4RBlC!*m?Ra+fK<`j?xJU`DXVa~1D8asK-PtdEJhZ*MqS&76>70X$Ht7>}+f9O4 U26b>H6bBvp#lH{Eg~I-S0c^DS0RR91 diff --git a/app/__pycache__/home_interface.cpython-39.pyc b/app/__pycache__/home_interface.cpython-39.pyc index 149139476f4ca682c8a3738b055a766c0dbc9aa2..7b34d20bfa8e8553a4460a835f4d86edaed694f4 100644 GIT binary patch delta 778 zcmZ8f&ubGw6rMNxYqHr*HZ?|&9u&MRmZBhdDJ?20f{L)yoey?AX;jJe}g9vdv=rDyn1vd2_-o2zJ2fe-uvF}us`*#k+F4MMeO|j zbWpvP>SPw7+PS>8Oc50wt*A|&dQqnmm0PHoxr?YmNefX@fu>N*Qqe+Ysm5LL~Z7lLFMk7Mj(Zl_~DQlr@FM8XFt$9VPqS@z>Vy z`@yjL>i5aF(c9MO2!A`Q@8SV9x_sy7; z9^Ah7=!Rv*uxu)^QnfwX_uW|VHoX|vy;yu<`_)*i)z_c9X|^#|?57^*Oo(;2;@JNB z%Swq8ACa3!C|r@QU*d{aZ@A^DqVTVj86d1;1Ka}3%AH(3TmTF1htHt0?Gq|Bp$S`J zAVw)F_W)2J)YL%q(>0AMZ!oVTosy{%$vp(f&(IW`kpd~ovOZ&`se!~ZKSx!j%7Of! zI&o)enyE^lFx8$PR%SLj)#jH4I9dpV34>?rb5v&*Bp`DONOXo~W?gD9eO(;s;Rn0~ zg)hIb36MV&A7i%=TH@H?cZS@v94<1*hMUqNXkk~{SmkxBmr7;F_Plb%aZ06W_hjVi z>D)P%WmtHa0RflSrV-whpWNZJo8`doe4@-*oUV?^%0`_woXRTyF+Gie0UBHY0t6G~ EA9*Uwg8%>k delta 454 zcmZ9Ize~eF6vyvfa+gb+#MECnbZ`+ZiqgqN?5L9{1qY>s(hEpU5t_PPQHZNUI1tC{ zD2{@wtD|!lC;tlv@6rs#gZuK{`@HXa$32B#e$e&(3exBPEW7%4@}Lf<`F3md2yvT} z2gFGXnRVfD+C~j0e;z|GuPw`K+=gTMf#W+)G8o&!R*cgL01{T;751pouX5)Rn_PLE z&4{8C1Zd=QS9^#cD$sokC36Ka(J15|4N%LG<6 zVHFizt`E7dM=-(W7BIEQgR;vNv*%*vN!#AB)^_*ansx(VNnVn3`A&Y|MgGD*9j@qq zqwe@^;OtfXBs)gvAVl51c{G{Q_)af)0n==)5 WW16yq!41Dn;zKY_swD&u*6|;aW@LE) diff --git a/app/__pycache__/main_window.cpython-39.pyc b/app/__pycache__/main_window.cpython-39.pyc index b02a880c226dc30dafbf8082d2784574aa659729..e6c11c84d133d8e56a76eedca4e6d7a359a3ad83 100644 GIT binary patch delta 731 zcmZuvQESss6uu`-yQE8MSDBQx&Z=9tbf~Cx;Lzg8TAffk)~OJXkS5tyOdGsO-HYJE zd=f`SK0 z%2UPrC0;#e|J!G7x01>~+`1o3Y{mM>xaWa=x_YDjB9mA`LIu13-= z&l>a`tI=ZX@}nEqur5lqHd}^xuhVWuLP+T^fu6%H z%G#bExXtJ8Fhq)r8i7lzxF^KCjmHi~ARrKtJ)LeC70hClDOZT{K`5__RMWIQD+p}Y z^Gq}0OWZUz=PcIEV#JzCpk$>PNtR|Q=QWL`ln-!|eOBJSEOWC=JNXdI{=_csr*X>a z`J*twawVcn&kEetdfYKFLeiUo?~FXR0ep@MLLL-Q1O@%AV|E!cg}qT_Q2{CS87lMx$#qs1b>4gvqn?_v8(y~&3I;KcE6+CQ7&yrl1Okpd-Zm3V)-z= zLNkXKf98o9waQxg4ly%k_8l>^EO`*t&YRILk(cKR{Y2-{@I4wWVCkv({m3_3Dj|hS z2tIw`(*dk=KY$I+iU@t{ywAGQ^>T8Hc0jVn91JJrr3$azIkzx=pFAZ{;y9(VKP)sOH25yMmJ76QG z3>}x*479}1=}c^UXg|>sE`!m~HeBW>O=dBdDaZj#kzp4hIt_)BSQ^C7Q+Je8b&ai zc>%{l21bSyhG2#wGoU_A&dEPGRVFKPMR9`7VdP;H*xbQo&&U`sS&~0R*QT1poj5 diff --git a/app/__pycache__/part_library_interface.cpython-39.pyc b/app/__pycache__/part_library_interface.cpython-39.pyc index 3674bf687762ea2d24a48677dabc757f0f422e43..1c409d4fed8d1613c541ebbdcb5770ecc5348ef6 100644 GIT binary patch delta 1458 zcmZ8gO>7%Q6yCAd>wm{~wrS#~X+w*Pql%~rO$i`q(+XPkN2CFynuE3WjO}&TyUy&m zTwF!ev=K-Z6?2H7fb1Jl4+Z%Icf=JgmDo$g35f&Z!i@v(tsS?@uJ)Vv^Sw9ky_wx! z`F&Qqs`iO5X(CKRT{6}pU1cmssW$Y8SXa3n6mgMgBx$%CxUF{7MyfZ_Q5tEV z9qefx6(ygOp%LJOI-wCK3!W{dgQU=iKG|3N?e$L34?ECNx}>9&rXb~1?;wrRSS{dl zQJ+R@V`i-9`bzH*jr&}X8?*fYWJBiAlh~6Rhxa^Ny*ZkssXeuKgiegp9i_uA0u2oV zX@X|%Lqflod76b@w2n6F*@iD>JnzatkCXUJt) zPS|8w{+5^}>+;>`+Ag0K$2M3jl@Vd{h3C**SFzEh&Vn z0A9qjt4^tGa6XS}yka>nTWbs9*!&o>j?2%pbJ|4|FUdjnX5Jq=_UdWWG%TmKf8a~t z+msh3|03IRQGfl+TNry5pb+=Mb;C7;;CvhOV$^i6w{6?BYhF|^-ZX7PFi-u+Fa^IO z`}*8btZ|q4gW12$C*b;e@Kpbk=r=&*MF1~sl--sg>inMcrk3(wqT?%sFA&C;!izgC zW|yjtMHzoAmku_!&H|y3>%KY5K`465Trh1$CI|8#FxYXWwl- z0p6eG(oFq>;YlI+9s>SG{x87sLi0@oJRpwa4GE6lP=rRQe7f|OPH p&rFWwWjuF+yf2q?#njsvq`CFBFfD#VKFqD8pOrM6v-~5M{~tQ0Uw;4q delta 1367 zcmZ8hOK%%h6rMYtnT*FCJ5HQ9c1_ZzG^$0F)FBU1#4Aux!=h=kNR(C@O?@Y^or%Y~ zGXV)rm8x#k1*#BSiH88m*;KR=2;>byh*eko02U*pN^Fo=v0#DNz&Y1uTE&*XIgjt0 zd(P);f4g*d$+S(=kl=OuYN!6=cjk&bUaAK{`@-B@b#Y<#`Q_R9>f-GD{CQrJUocc4 zCg9`0$M4IPgCjzuQ0}UMMwJeUy`hd2+d5VInIPGbZYBaFNHx<`>&Q2iP-&XoOei(8 zf}QB9p@Np+4AUXtsG&OG-n#t+aRJL{od#IwapMP~T}J;R zUr#TSOZ@$Gi&XhP=`y*@3+7b*SlK1uuJu;UbA(*w?`GB)EeKQ+%!Wrq8q9&`135}s z0khw6nD4MF5P9m{J#ZcVZ)Od~UCS0;uVI=ZU@3IM`6GpSUch!SECz7V!nvc|juTk5 zx>MVAsI}d29lzFln1wA~LCUMVnQNB&Ci-ItuOX}eRGwuX|1hqpH_B+XM zfXOzobjZHpx9ySKUtr+L=%P@7C_Dq%NBml`e$ZDR$#)R&XCN*y!z;-=1Qea2QVh>ySR0v^ zRda3MuQ{%3Sx?EjfD~~?9xVLt^Tz>nqTpN3oH5G!sBY@d!Kcjfe5F(*>->6YEAs}> aBF(Sw2Mw2P@JFSk;U`n~N9V?gng0N9(J(y# diff --git a/app/__pycache__/serial_terminal_interface.cpython-39.pyc b/app/__pycache__/serial_terminal_interface.cpython-39.pyc index f18474423d64ca4931fab786722b5225c06a4b6c..52fd265b0dc9a3b20fb9aca9f938e80a78c156fe 100644 GIT binary patch delta 20 acmX@7drp@-k(ZZ?0SG!a^={-oECv8PSOwz% delta 20 acmX@7drp@-k(ZZ?0SF4&nl^GD76Sk`cm)*z diff --git a/app/code_generate_interface.py b/app/code_generate_interface.py index 489861f..3bbd50d 100644 --- a/app/code_generate_interface.py +++ b/app/code_generate_interface.py @@ -155,30 +155,49 @@ class CodeGenerateInterface(QWidget): def generate_code(self): - """生成代码逻辑""" - # 收集所有已加载的页面对象 - pages = [] - for i in range(self.stack.count()): - widget = self.stack.widget(i) - pages.append(widget) - - # 生成 BSP 代码 - bsp_result = bsp.generate_bsp(self.project_path, pages) - - # 生成 Component 代码 - from app.code_page.component_interface import component - component_result = component.generate_component(self.project_path, pages) - - # 合并结果信息 - combined_result = f"BSP代码生成:\n{bsp_result}\n\nComponent代码生成:\n{component_result}" - - # 用 InfoBar 在主界面弹出 - InfoBar.success( - title="代码生成结果", - content=combined_result, - parent=self, - duration=5000 # 增加显示时间,因为内容更多 - ) + """生成代码逻辑 - 修复导入问题""" + try: + # 收集所有已加载的页面对象 + pages = [] + for i in range(self.stack.count()): + widget = self.stack.widget(i) + pages.append(widget) + + # 确保导入成功 + from app.code_page.bsp_interface import bsp + from app.code_page.component_interface import component + + # 生成 BSP 代码 + bsp_result = bsp.generate_bsp(self.project_path, pages) + + # 生成 Component 代码 + component_result = component.generate_component(self.project_path, pages) + + # 合并结果信息 + combined_result = f"BSP代码生成:\n{bsp_result}\n\nComponent代码生成:\n{component_result}" + + # 用 InfoBar 在主界面弹出 + InfoBar.success( + title="代码生成结果", + content=combined_result, + parent=self, + duration=5000 + ) + + except ImportError as e: + InfoBar.error( + title="导入错误", + content=f"模块导入失败: {str(e)}", + parent=self, + duration=3000 + ) + except Exception as e: + InfoBar.error( + title="生成失败", + content=f"代码生成过程中出现错误: {str(e)}", + parent=self, + duration=3000 + ) def _get_freertos_status(self): """获取FreeRTOS状态""" @@ -220,7 +239,6 @@ class CodeGenerateInterface(QWidget): if widget: self.stack.setCurrentWidget(widget) -# ...existing code... def _get_or_create_page(self, class_name): """获取或创建页面""" if class_name in self.page_cache: @@ -235,12 +253,12 @@ class CodeGenerateInterface(QWidget): if class_name.startswith('bsp_'): # BSP页面 from app.code_page.bsp_interface import get_bsp_page - # 提取外设名,如 bsp_delay -> delay - periph_name = class_name[len('bsp_'):].replace("_", " ") + # 提取外设名,如 bsp_error_detect -> error_detect + periph_name = class_name[len('bsp_'):] # 移除 .replace("_", " ") page = get_bsp_page(periph_name, self.project_path) elif class_name.startswith('component_'): from app.code_page.component_interface import get_component_page - comp_name = class_name[len('component_'):].replace("_", " ") + comp_name = class_name[len('component_'):] # 移除 .replace("_", " ") page = get_component_page(comp_name, self.project_path, self.component_manager) self.component_manager.register_component(page.component_name, page) else: @@ -253,5 +271,4 @@ class CodeGenerateInterface(QWidget): except Exception as e: print(f"创建页面 {class_name} 失败: {e}") return None - -# ...existing code... \ No newline at end of file + diff --git a/app/code_page/__pycache__/bsp_interface.cpython-39.pyc b/app/code_page/__pycache__/bsp_interface.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cc9b99601e18bad5d17a8764f2239ba32a6fbf83 GIT binary patch literal 29483 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 literal 0 HcmV?d00001 diff --git a/app/code_page/__pycache__/component_interface.cpython-39.pyc b/app/code_page/__pycache__/component_interface.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..174f3817ffbbd4e8ee2a1b4e9919272ab2a2e2b6 GIT binary patch literal 15873 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 aK{IB?%|xuInstance == {instance})") + get_lines.append(f" if (hcan->Instance == {instance})") else: - get_lines.append(f" else if (hcan->Instance == {instance})") - get_lines.append(f" return {self.enum_prefix}_{name};") + get_lines.append(f" else if (hcan->Instance == {instance})") + get_lines.append(f" return {self.enum_prefix}_{name};") content = CodeGenerator.replace_auto_generated( template_content, "AUTO GENERATED CAN_GET", "\n".join(get_lines) ) @@ -420,41 +421,106 @@ class bsp_can(BspPeripheralBase): # Handle函数 handle_lines = [] for name, instance in configs: + num = ''.join(filter(str.isdigit, instance)) # 提取数字 handle_lines.append(f" case {self.enum_prefix}_{name}:") - handle_lines.append(f" return &h{instance.lower()};") + handle_lines.append(f" return &hcan{num};") content = CodeGenerator.replace_auto_generated( content, f"AUTO GENERATED {self.enum_prefix}_GET_HANDLE", "\n".join(handle_lines) ) # 生成CAN初始化代码 init_lines = [] - for idx, (name, instance) in enumerate(configs): - can_num = instance[-1] # CAN1 -> 1, CAN2 -> 2 - - init_lines.append(f" // 初始化 {instance}") - init_lines.append(f" CAN_FilterTypeDef can{can_num}_filter = {{0}};") - init_lines.append(f" can{can_num}_filter.FilterBank = {0 if can_num == '1' else 14};") - init_lines.append(f" can{can_num}_filter.FilterIdHigh = 0;") - init_lines.append(f" can{can_num}_filter.FilterIdLow = 0;") - init_lines.append(f" can{can_num}_filter.FilterMode = CAN_FILTERMODE_IDMASK;") - init_lines.append(f" can{can_num}_filter.FilterScale = CAN_FILTERSCALE_32BIT;") - init_lines.append(f" can{can_num}_filter.FilterMaskIdHigh = 0;") - init_lines.append(f" can{can_num}_filter.FilterMaskIdLow = 0;") - init_lines.append(f" can{can_num}_filter.FilterActivation = ENABLE;") - if can_num == '1': - init_lines.append(f" can{can_num}_filter.SlaveStartFilterBank = 14;") - init_lines.append(f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO0;") - else: - init_lines.append(f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO1;") - - init_lines.append(f" HAL_CAN_ConfigFilter(BSP_CAN_GetHandle({self.enum_prefix}_{name}), &can{can_num}_filter);") - init_lines.append(f" HAL_CAN_Start(BSP_CAN_GetHandle({self.enum_prefix}_{name}));") - - # 注册回调和激活中断 - fifo = "FIFO0" if can_num == '1' else "FIFO1" - init_lines.append(f" HAL_CAN_ActivateNotification(BSP_CAN_GetHandle({self.enum_prefix}_{name}), CAN_IT_RX_{fifo}_MSG_PENDING);") - init_lines.append("") - + # 先设置初始化标志 + init_lines.append(" // 先设置初始化标志,以便后续回调注册能通过检查") + init_lines.append(" inited = true;") + init_lines.append("") + + # 检查是否同时有CAN1和CAN2 + has_can1 = any(instance == 'CAN1' for _, instance in configs) + has_can2 = any(instance == 'CAN2' for _, instance in configs) + + if has_can1 and has_can2: + # 同时配置CAN1和CAN2的情况 - 统一使用FIFO0 + init_lines.extend([ + " // 初始化 CAN1 - 使用 FIFO0", + " CAN_FilterTypeDef can1_filter = {0};", + " can1_filter.FilterBank = 0;", + " can1_filter.FilterIdHigh = 0;", + " can1_filter.FilterIdLow = 0;", + " can1_filter.FilterMode = CAN_FILTERMODE_IDMASK;", + " can1_filter.FilterScale = CAN_FILTERSCALE_32BIT;", + " can1_filter.FilterMaskIdHigh = 0;", + " can1_filter.FilterMaskIdLow = 0;", + " can1_filter.FilterActivation = ENABLE;", + " can1_filter.SlaveStartFilterBank = 14; // 重要:设置从过滤器起始组", + " can1_filter.FilterFIFOAssignment = CAN_RX_FIFO0;", + " HAL_CAN_ConfigFilter(&hcan1, &can1_filter);", + " HAL_CAN_Start(&hcan1);", + " HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);", + "", + " // 初始化 CAN2 - 使用 FIFO0(注意:通过 CAN1 配置 CAN2 的过滤器)", + " CAN_FilterTypeDef can2_filter = {0};", + " can2_filter.FilterBank = 14; // CAN2 使用过滤器组 14", + " can2_filter.FilterIdHigh = 0;", + " can2_filter.FilterIdLow = 0;", + " can2_filter.FilterMode = CAN_FILTERMODE_IDMASK;", + " can2_filter.FilterScale = CAN_FILTERSCALE_32BIT;", + " can2_filter.FilterMaskIdHigh = 0;", + " can2_filter.FilterMaskIdLow = 0;", + " can2_filter.FilterActivation = ENABLE;", + " can2_filter.FilterFIFOAssignment = CAN_RX_FIFO0; // 改为 FIFO0", + " HAL_CAN_ConfigFilter(&hcan1, &can2_filter); // 通过 CAN1 配置", + " HAL_CAN_Start(&hcan2);", + " HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING); // 激活 FIFO0 中断", + "", + " // 注册回调函数", + f" BSP_CAN_RegisterCallback({self.enum_prefix}_CAN1, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifoCallback);", + f" BSP_CAN_RegisterCallback({self.enum_prefix}_CAN2, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifoCallback);", + ]) + else: + # 只有单个CAN的情况 + for idx, (name, instance) in enumerate(configs): + can_num = instance[-1] # CAN1 -> 1, CAN2 -> 2 + + init_lines.append(f" // 初始化 {instance}") + init_lines.append(f" CAN_FilterTypeDef can{can_num}_filter = {{0}};") + + if instance == 'CAN1': + init_lines.extend([ + f" can{can_num}_filter.FilterBank = 0;", + f" can{can_num}_filter.SlaveStartFilterBank = 14;", + f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO0;", + ]) + else: # CAN2 + init_lines.extend([ + f" can{can_num}_filter.FilterBank = 14;", + f" can{can_num}_filter.FilterFIFOAssignment = CAN_RX_FIFO0;", + ]) + + init_lines.extend([ + f" can{can_num}_filter.FilterIdHigh = 0;", + f" can{can_num}_filter.FilterIdLow = 0;", + f" can{can_num}_filter.FilterMode = CAN_FILTERMODE_IDMASK;", + f" can{can_num}_filter.FilterScale = CAN_FILTERSCALE_32BIT;", + f" can{can_num}_filter.FilterMaskIdHigh = 0;", + f" can{can_num}_filter.FilterMaskIdLow = 0;", + f" can{can_num}_filter.FilterActivation = ENABLE;", + ]) + + if instance == 'CAN2': + init_lines.append(f" HAL_CAN_ConfigFilter(&hcan1, &can{can_num}_filter); // 通过 CAN1 配置") + else: + init_lines.append(f" HAL_CAN_ConfigFilter(&hcan{can_num}, &can{can_num}_filter);") + + init_lines.extend([ + f" HAL_CAN_Start(&hcan{can_num});", + f" HAL_CAN_ActivateNotification(&hcan{can_num}, CAN_IT_RX_FIFO0_MSG_PENDING);", + "", + f" // 注册回调函数", + f" BSP_CAN_RegisterCallback({self.enum_prefix}_{name}, HAL_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifoCallback);", + "" + ]) + content = CodeGenerator.replace_auto_generated( content, "AUTO GENERATED CAN_INIT", "\n".join(init_lines) ) @@ -463,6 +529,8 @@ class bsp_can(BspPeripheralBase): save_with_preserve(output_path, content) return True + + class bsp_spi(BspPeripheralBase): def __init__(self, project_path): super().__init__( @@ -654,16 +722,17 @@ class bsp_gpio(QWidget): template_content, "AUTO GENERATED BSP_GPIO_MAP", "\n".join(map_lines) ) - # 生成EXTI使能代码 + # 生成EXTI使能代码 - 使用用户自定义的BSP枚举名称 enable_lines = [] disable_lines = [] for config in configs: if config['has_exti']: ioc_label = config['ioc_label'] - enable_lines.append(f" case {ioc_label}_Pin:") + custom_name = config['custom_name'] + enable_lines.append(f" case BSP_GPIO_{custom_name}:") enable_lines.append(f" HAL_NVIC_EnableIRQ({ioc_label}_EXTI_IRQn);") enable_lines.append(f" break;") - disable_lines.append(f" case {ioc_label}_Pin:") + disable_lines.append(f" case BSP_GPIO_{custom_name}:") disable_lines.append(f" HAL_NVIC_DisableIRQ({ioc_label}_EXTI_IRQn);") disable_lines.append(f" break;") @@ -678,6 +747,8 @@ class bsp_gpio(QWidget): save_with_preserve(output_path, content) return True + + def _save_config(self, configs): config_path = os.path.join(self.project_path, "User/bsp/bsp_config.yaml") config_data = CodeGenerator.load_config(config_path) diff --git a/app/tools/__pycache__/analyzing_ioc.cpython-39.pyc b/app/tools/__pycache__/analyzing_ioc.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d9bf58a2f9f2f7387d458dd3b37e7b8ab8a7d648 GIT binary patch literal 6849 zcmeHMU2q#$72dmAt^OUwaonVYA}GWtByQrgr44DOshuCw_-8C<+6reDMZ2*zktO-= z%5BYRCQN=xnfy`G08XGbgiZp}cBaF$nbw6FhNnL8kjH(+a^j~l!xQ15eCMttOSK$l z%J5Q=dq( za#GUegcSFrA#eEAMr0v2q$Ja&q-=O}rpu?KlPsx#_vnh?z2LpNDtHyVPxlMn2R@(& z1@8wR(!+uefRE@cf)9dUqelfF($``wtxhDBOJ!f4%H&41Og^1vbqn)@r>h&6`Dc)f zRAQE7<6(69oO~f!l5M$1I?_|}*q#|SE76^|gO_#BEaP1h?Yd%nCM6-m1L)pac| z9q;chd)Q%5Ez%q8Z+MR~BwkzzT;_uyqj-l$T1(7kGjI>AQL))i0J^gW1H@^ zQhM>`*FYq%!djRge=SS~jk4{c9Tu`6=+u_`e*q02*9Yr0ko*OW(K?Xmo^zfH(-oMU zYJkZG0TTru|IvvJx>vx2WCGnam@WKQwWQ4P-X+~f)xoZ!P%BJ{qK9vE?0=OTEi z|AxxRkNH|6^eH$6UPlE4jGXSMW}aJy9{2He5GO-bcg}RB`FiTzPUHb18>oXH3N4o! zH$LlX8%7PQ1_tU>1;j=SGamwxR0Xb8?`GiTHu*uwwy>$qjV`v5x&I0GdLD19_WhT; zQ(~}p6?Z}p;ZC@BHFGEaCCtD#5ozi{7{}?G@vngN^BCwd7cmQ&<}L!o>MlZ^sxGnv z=2vzR*2Y$Mk$Q9gcaiB+-Fy32aS`+oE`s~#auJMM)kV^&TyqzJVs#gxPE{8<@SnR# zy}6ZLbXjegi`zrs+VdN zqwr0lf}yJCiHS|9dK6SHBwMO_sBRIP15`Vz*i@*xPq@q`;WDUxbpJ*P1wPd~K3$!a zbro&D?X%@c#xG|iTef|>B~(ASZ1MqnjbiigYgP)_@{BSoVbzn^ zrua%hJ2>N|oz$#c3h5C$ILXXgdJEkzGOpSo)L?67!JF#DEjwffCM6ShNTajpDY&(y z=bK6I_U5G$ttU9c>UX?|4cFU&PYhCgC%bj`Q)e{R>UoGE!Gq&&f;ojK% z%}Z#;4yBG7*%->N*nz>`flubnE}VaD@fX+1r{A0Z@N)Uu z-#Im1!-%N4R!)*jsqscU>8E6?CAyzY1_amFn;59F1BqUt@2cs$w3;4lRll>Q-?^j* zEA&(wLVqafce$Ruf+L%*3|vJ`;~MT9S5YHR;YJ>CPqT<4e-V zN$MA@gu@5}2(k8vzj%v$7Tj`zTzxFxjV-af~(x2GE$QBNU* z4PBO8?}o2w>Fv!}#<=Nt5TE#0;mh%esJ)%QXd#o=Xw&F~1?z76%w}! z>hVXSEDVYIslxo9DzfZ(h{+z>F}BK6_XwX2GcF6C0ZcAVRrnV(d`_V1YZi(trV&;a@}#FZO3JO z{Z(Hj(1zo<4W`qqh-G=RZ2*MpSHa=RY`qKXJ8u;dkY; zr^^?AfBS=X$d(&_Kbe~r0PD>aiq=*Ut+j!oRcQcYwYA)LT;?5k1pZATaUxrYY$MVM z0-U<=7Be~_F}ph>-%6dnMdUj~c2Reqz?(o)(m$5Msn1JRhCcz7ql_aeBm+2T$%_?Z zhiqyYdJsOa*$Se|-#c`3AP?gkvwaYGHqg)an- zYvs?3z;D0~08>GnqROHal7TM9KNf|M#6Je&RK10?D8x_(l|q)!4xMCr^tcz=kSNo_ zxKnu+u_GvdPz*s6(W83cv|BKhsGy~d6T z?6+O@3KV}V3Z?bUP+Wf~HTYcL;)&_SAO7^-MgI>vtPGBOI(Ef6kmf}3pB_u)az?fy z(z*}s?eE`rNE14d`A7rvs9%N$hIVw6w#GU;JCA%06fXgou$%N?uB4pM9HuSOsaR4* zJB(%3)*yf$_c~s&XvbGss+$BUX$oA$1I;os$NwuNz7xdpaifq;rE%1nHF9p2UhAHa zg$pl^YZa^J{UEvqW|6KflRu3KlHrO8obYlh8LGB&#c{ruR?#eJHyp9iGO9V-2Yi_a zG3N)X_^z%Gz7z9)&L*Y zw25LWODBcY!dbnQNsk-WSYGFJ$j=`p@^vELAhMarlSG~(vX2NI<<}89(WZ(3|M0-$ t#y}9ZSg;+}1Gv^#F5>s#8j_jl-5+=Fb(Vx-aX{|h?XGwa+2k!C{|0@C+8F=< literal 0 HcmV?d00001 diff --git a/app/tools/__pycache__/check_update.cpython-39.pyc b/app/tools/__pycache__/check_update.cpython-39.pyc index 7477353e3615e274cf4f1d20f6426c7dd599b6e9..de74a0309a79d53ce8b94c427818328cb3e2a5e8 100644 GIT binary patch delta 20 acmbQrI+c|>k(ZZ?0SKJyCT!&HVgdjvumoNJ delta 20 acmbQrI+c|>k(ZZ?0SM}wn>KQHF#!N9ECi7N diff --git a/app/tools/__pycache__/code_generator.cpython-39.pyc b/app/tools/__pycache__/code_generator.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..444942942bb8e667e0aea27a7aa93c9c7c17f01c GIT binary patch literal 3039 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 BnOFb- literal 0 HcmV?d00001 diff --git a/app/tools/__pycache__/part_download.cpython-39.pyc b/app/tools/__pycache__/part_download.cpython-39.pyc index 7e11e9c6e08a7aaf79df905a45e40d558864be27..3edd79ff5d89c87ae1bb98f7c296f77c9d5b362c 100644 GIT binary patch delta 20 acmZ3-yN;JTk(ZZ?0SG!a^={-|%mx55$OSV1 delta 20 acmZ3-yN;JTk(ZZ?0SL^^n>TVVW&;2%eFR+q diff --git a/app/tools/__pycache__/update_code.cpython-39.pyc b/app/tools/__pycache__/update_code.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e663d28cf647bfb2c8d10b8e08a0591019f8bf1 GIT binary patch literal 1170 zcmYjR&92)-6rN){w)1nt?GGtsQ6YBO#DN8sstPJ76)YO0UZ5f}vK-H(aju>5otbcZ zqe(YmTeuIvB3beRJONKJTULDoRDr}9yTG0CIdjhE^YhJ2;`HdKLvZ~4;&So3N5~)6 zxjI~Q9-zpNP*FmmAk$`rDb&6*b?Vify7lT!J?c@1xngH@y;JMP_EhTt2cXWu*?OBlmA?$MOI_-{bha(s+J^@MM78%F)!p}W zYk6d&w|-rrue}3^nR;t~Y%L(#-(NeBhvfTTwm}_nT?Y+DTek^z2z5yPQ%C%CwrrSa zPlt%Nb+Erd1FZHN;x~1hhP3_C0aC}^tYcl>MxJkQ^)|+IcFxc5Z9BTNA7GbT8uKlS zr+9iE&Yf%XKOpk2G48?6?@-Q`8ZJQ$G-$GGqQeu6R_|QG#kWAVT_BtHwSzGaw4;f- zt-CweA(y9^Px1YWF72MYvBqSK7T!Q_viW48RCO2#O0ktPe$7G}UoO@v zFN`lrB^WcI?OY&169`r`-PwxD^BnnwWqQhx9rEQBTbb6mz_T-+U@0~2&!1t zQ|YQy;JzCN<_6fWM2zrwU*FB{#gEf0{(_e*e#o*ihu`qz=1x5a2BjUp`N*}}+vxe?uG8y_J qL|gQ&x@Of4t8Q6kgKEB4RD_rb@0Xme3-+=7tw{SB2(frQoqqsBP)LFR literal 0 HcmV?d00001 diff --git a/app/tools/code_generator.py b/app/tools/code_generator.py index 8b41d68..e3a45b5 100644 --- a/app/tools/code_generator.py +++ b/app/tools/code_generator.py @@ -2,7 +2,8 @@ import os import yaml import shutil from typing import Dict, List, Tuple - +import sys +import os class CodeGenerator: """通用代码生成器""" @@ -61,15 +62,20 @@ class CodeGenerator: @staticmethod def get_template_dir(): - """获取模板文件目录""" - # 从当前文件向上找到 MRobot 目录,然后定位到模板目录 - current_dir = os.path.dirname(os.path.abspath(__file__)) - # 向上找到 MRobot 根目录 - while os.path.basename(current_dir) != 'MRobot' and current_dir != '/': - current_dir = os.path.dirname(current_dir) - - if os.path.basename(current_dir) == 'MRobot': - return os.path.join(current_dir, "assets/User_code/bsp") + """获取模板目录路径,兼容打包环境""" + if getattr(sys, 'frozen', False): + # 打包后的环境 + base_path = sys._MEIPASS + template_dir = os.path.join(base_path, "assets", "User_code", "bsp") else: - # 如果找不到,使用相对路径作为备选 - return os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "assets/User_code/bsp") \ No newline at end of file + # 开发环境 + current_dir = os.path.dirname(os.path.abspath(__file__)) + while os.path.basename(current_dir) != 'MRobot' and current_dir != '/': + current_dir = os.path.dirname(current_dir) + template_dir = os.path.join(current_dir, "assets", "User_code", "bsp") + + print(f"模板目录路径: {template_dir}") + if not os.path.exists(template_dir): + print(f"警告:模板目录不存在: {template_dir}") + + return template_dir \ No newline at end of file diff --git a/assets/.DS_Store b/assets/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..306d69802ef1deb33d9c6ca91192de1954c6ca35 GIT binary patch literal 6148 zcmeHKO;6iE5S>i|tc5D&0HPNpOI%S2A1Xpz+%z0|#f2UKrEzS5h4G>|X%0~&U)w*! zk$=M9p>ID@DFMU@MA3{i`(}6N?aI%|u7`+3a}aM5)rm;LHC8+{kC>j<{=h13WDY3w z8s9S2jWQLXuNP!{`wHlHSEGy+os*h*e_t^7>E4)m5J^{*P?s*K4Ms}QO#aPGzDGw? zfYC#K7dyn1Of$sl^NeU%T)W@YZFHTbMZeLw6P0RhZhk>7$VGV;UZ`Q%@AL;nv(r1# zz3)n8(IoCf$7wQb*O$Jkyx&Rlq-O|eoFL`&N1DfK*i?f&E(|xc6Vj7jyS_3SZ8z5a z&E4Jcx%GGZp4hj4PjD2u8fjXd_%QKaqV|K!v zFc?_@R)7_FVFlc=BNtzIA6}jnU}{GuClC3s<2CS9l2Dq>~6Na?1*^0@Dgq zZMUxP|AVLN|7jBUSOHexT`3@Ht+3U^Be}cv!Ncjh)`$OuYtwn9#eWn8<|;<6zKTD> ajbYr^0Wfe_TEqy9KLm^n+^_<#s=!~{5OU`L literal 0 HcmV?d00001 diff --git a/assets/User_code/.DS_Store b/assets/User_code/.DS_Store index 038a9973cdfc977f2bf0be31ee0780e9de8af44d..08591375155ab3be091f39b61c922fe3d7612f77 100644 GIT binary patch literal 6148 zcmeHKPfrs;6n|5yY(Zp!RuE&-*oz4S0g1#ILn#;~#(3TGdGF24Z+CWf0Du%~?gW4d00tI; z$u6w^AfjKCHc4oUh$A8gcWj^A*b?bti5Z9)_}3W_d$$8@2%);*x9s0p>>2wdMJ_^n z*?VDC@A8j!)%U_^eEcg(bR;ia>@+%!Zey#s!}p4j71hFm6>Nys3g^Dv)Gd3}qkAPY zJ;zyOd5i`!z;h|OY(Ddt%l8Vr#@tZG7FCClGEyaT@bK{V_-J-wdirQIdw6#e^{G2k zM@K0mle=|qxwPw77=NWWC-_N{(xb5nuTjy9@tnF|4EfSr%y-jlE+^I1eW~Yiui4i> z(3kGZWUdSjWv&ii8!njxw&m=W12N4x?(?AF*XTw$@Z4h6ay(XEi|EU!=pE3K*?-1$ znYzzUOe_0U^huu>WV(j|rA+2q+};jpw025gFPXie6L8;O;-MFLoULz$Nb*8ND+_F! zsAn0tV|30TfSvee~}e<6!FTM=WwQG-Ye5$b19%AWp3uD z;xLzg+*EEV#e|$v0CM?Br5fp`Nh4WdoY7P+zoZN)JXS_v7M{Q=?7{)Og?I2CKEY@B z20!4KbP|)?AR}ao+$S^S5qV0Mi9>dXM*@`~(R{?$TSp=xw)G>f7X#*VRz{2PPJsg) zDp19m0mTxXdG9}<*Xj4ZOGYr*1`o3jIz*8;$N0Q>?`d#0RN+A6 z$e2fuO!N(f=&J|GN_QZ6g>fA-5HrxqK!<9Y;{1Pb{{6o-C~n0J#0>mb43Ok}alU{{ z(r0Vi;>1~-#qt7+5aHKQC_}K)$FWqzQ9Oi23if4%f|%FXP>2?k_(wp}5LYn+f0cpX Dp12g; delta 82 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 == can_id) { return node->queue; @@ -69,15 +71,15 @@ static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) { } // 获取互斥锁 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { + if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { return BSP_ERR_TIMEOUT; } // 检查是否已存在 - BSP_CAN_QueueNode_t *node = g_can_queue_list; + BSP_CAN_QueueNode_t *node = queue_list; while (node != NULL) { if (node->can_id == can_id) { - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); return BSP_ERR; // 已存在 } node = node->next; @@ -86,7 +88,7 @@ static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) { // 创建新节点 BSP_CAN_QueueNode_t *new_node = (BSP_CAN_QueueNode_t *)BSP_Malloc(sizeof(BSP_CAN_QueueNode_t)); if (new_node == NULL) { - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); return BSP_ERR_NULL; } @@ -94,17 +96,17 @@ static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) { new_node->queue = osMessageQueueNew(queue_size, sizeof(BSP_CAN_Message_t), NULL); if (new_node->queue == NULL) { BSP_Free(new_node); - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); return BSP_ERR; } // 初始化节点 new_node->can_id = can_id; new_node->queue_size = queue_size; - new_node->next = g_can_queue_list; - g_can_queue_list = new_node; + new_node->next = queue_list; + queue_list = new_node; - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); return BSP_OK; } @@ -114,11 +116,11 @@ static int8_t BSP_CAN_CreateIdQueue(uint32_t can_id, uint8_t queue_size) { */ static int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id) { // 获取互斥锁 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { + if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { return BSP_ERR_TIMEOUT; } - BSP_CAN_QueueNode_t **current = &g_can_queue_list; + BSP_CAN_QueueNode_t **current = &queue_list; while (*current != NULL) { if ((*current)->can_id == can_id) { BSP_CAN_QueueNode_t *to_delete = *current; @@ -128,20 +130,39 @@ static int8_t BSP_CAN_DeleteIdQueue(uint32_t can_id) { osMessageQueueDelete(to_delete->queue); BSP_Free(to_delete); - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); return BSP_OK; } current = &(*current)->next; } - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); return BSP_ERR; // 未找到 } /** - * @brief FIFO0接收处理函数 + * @brief 获取帧类型 */ -static void BSP_CAN_RxFifo0Handler(void) { +static BSP_CAN_FrameType_t BSP_CAN_GetFrameType(CAN_RxHeaderTypeDef *header) { + if (header->RTR == CAN_RTR_REMOTE) { + return (header->IDE == CAN_ID_EXT) ? BSP_CAN_FRAME_EXT_REMOTE : BSP_CAN_FRAME_STD_REMOTE; + } else { + return (header->IDE == CAN_ID_EXT) ? BSP_CAN_FRAME_EXT_DATA : BSP_CAN_FRAME_STD_DATA; + } +} + +/** + * @brief 默认ID解析器(直接返回原始ID) + */ +static uint32_t BSP_CAN_DefaultIdParser(uint32_t original_id, BSP_CAN_FrameType_t frame_type) { + (void)frame_type; // 避免未使用参数警告 + return original_id; +} + +/** + * @brief FIFO接收处理函数 + */ +static void BSP_CAN_RxFifoCallback(void) { CAN_RxHeaderTypeDef rx_header; uint8_t rx_data[BSP_CAN_MAX_DLC]; @@ -152,59 +173,32 @@ static void BSP_CAN_RxFifo0Handler(void) { while (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO0) > 0) { if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data) == HAL_OK) { - uint32_t can_id = (rx_header.IDE == CAN_ID_STD) ? rx_header.StdId : rx_header.ExtId; + // 获取原始ID + uint32_t original_id = (rx_header.IDE == CAN_ID_STD) ? rx_header.StdId : rx_header.ExtId; - // 线程安全地查找队列 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) { - osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id); - osMutexRelease(g_can_queue_mutex); - - if (queue != NULL) { - BSP_CAN_Message_t msg; - msg.header = rx_header; - memcpy(msg.data, rx_data, BSP_CAN_MAX_DLC); - - // 非阻塞发送,如果队列满了就丢弃 - osMessageQueuePut(queue, &msg, 0, BSP_CAN_TIMEOUT_IMMEDIATE); - } - } - // 如果没有找到对应的队列或获取互斥锁超时,消息被直接丢弃 - } - } - } -} - -/** - * @brief FIFO1接收处理函数 - */ -static void BSP_CAN_RxFifo1Handler(void) { - CAN_RxHeaderTypeDef rx_header; - uint8_t rx_data[BSP_CAN_MAX_DLC]; - - // 遍历所有CAN接口处理FIFO1 - for (int can_idx = 0; can_idx < BSP_CAN_NUM; can_idx++) { - CAN_HandleTypeDef *hcan = BSP_CAN_GetHandle((BSP_CAN_t)can_idx); - if (hcan == NULL) continue; - - while (HAL_CAN_GetRxFifoFillLevel(hcan, CAN_RX_FIFO1) > 0) { - if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO1, &rx_header, rx_data) == HAL_OK) { - uint32_t can_id = (rx_header.IDE == CAN_ID_STD) ? rx_header.StdId : rx_header.ExtId; + // 获取帧类型 + BSP_CAN_FrameType_t frame_type = BSP_CAN_GetFrameType(&rx_header); - // 线程安全地查找队列 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) { - osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id); - osMutexRelease(g_can_queue_mutex); - - if (queue != NULL) { - BSP_CAN_Message_t msg; - msg.header = rx_header; - memcpy(msg.data, rx_data, BSP_CAN_MAX_DLC); - - // 非阻塞发送,如果队列满了就丢弃 - osMessageQueuePut(queue, &msg, 0, BSP_CAN_TIMEOUT_IMMEDIATE); + // 解析ID + uint32_t parsed_id = BSP_CAN_ParseId(original_id, frame_type); + + // 直接查找队列,不使用互斥锁(中断中快速执行) + osMessageQueueId_t queue = BSP_CAN_FindQueue(parsed_id); + + if (queue != NULL) { + BSP_CAN_Message_t msg = {0}; + msg.frame_type = frame_type; + msg.original_id = original_id; + msg.parsed_id = parsed_id; + msg.dlc = rx_header.DLC; + if (rx_header.RTR == CAN_RTR_DATA) { + memcpy(msg.data, rx_data, rx_header.DLC); } + msg.timestamp = HAL_GetTick(); // 添加时间戳 + + // 非阻塞发送,如果队列满了就丢弃 + osMessageQueuePut(queue, &msg, 0, BSP_CAN_TIMEOUT_IMMEDIATE); } - // 如果没有找到对应的队列或获取互斥锁超时,消息被直接丢弃 } } } @@ -212,178 +206,165 @@ static void BSP_CAN_RxFifo1Handler(void) { /* HAL Callback Functions --------------------------------------------------- */ void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_CPLT_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_CPLT_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_CPLT_CB]) + CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_CPLT_CB](); + } } void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_CPLT_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_CPLT_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_CPLT_CB]) + CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_CPLT_CB](); + } } void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_CPLT_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_CPLT_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_CPLT_CB]) + CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_CPLT_CB](); + } } void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_ABORT_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX0_ABORT_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_ABORT_CB]) + CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX0_ABORT_CB](); + } } void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_ABORT_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX1_ABORT_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_ABORT_CB]) + CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX1_ABORT_CB](); + } } void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_ABORT_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_TX_MAILBOX2_ABORT_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_ABORT_CB]) + CAN_Callback[bsp_can][HAL_CAN_TX_MAILBOX2_ABORT_CB](); + } } void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_MSG_PENDING_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_MSG_PENDING_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_MSG_PENDING_CB]) + CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_MSG_PENDING_CB](); + } } void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_FULL_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO0_FULL_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_FULL_CB]) + CAN_Callback[bsp_can][HAL_CAN_RX_FIFO0_FULL_CB](); + } } void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_MSG_PENDING_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_MSG_PENDING_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_MSG_PENDING_CB]) + CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_MSG_PENDING_CB](); + } } void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_FULL_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_RX_FIFO1_FULL_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_FULL_CB]) + CAN_Callback[bsp_can][HAL_CAN_RX_FIFO1_FULL_CB](); + } } void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_SLEEP_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_SLEEP_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_SLEEP_CB]) + CAN_Callback[bsp_can][HAL_CAN_SLEEP_CB](); + } } void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_WAKEUP_FROM_RX_MSG_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_WAKEUP_FROM_RX_MSG_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_WAKEUP_FROM_RX_MSG_CB]) + CAN_Callback[bsp_can][HAL_CAN_WAKEUP_FROM_RX_MSG_CB](); + } } void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) { - BSP_CAN_t bsp_can = BSP_CAN_GetInstance(hcan); - if (bsp_can != BSP_CAN_ERR) { - if (g_can_callbacks[bsp_can][BSP_CAN_ERROR_CB] != NULL) { - g_can_callbacks[bsp_can][BSP_CAN_ERROR_CB](); - } - } + BSP_CAN_t bsp_can = CAN_Get(hcan); + if (bsp_can != BSP_CAN_ERR) { + if (CAN_Callback[bsp_can][HAL_CAN_ERROR_CB]) + CAN_Callback[bsp_can][HAL_CAN_ERROR_CB](); + } } /* Exported functions ------------------------------------------------------- */ int8_t BSP_CAN_Init(void) { - if (g_can_initialized) { + if (inited) { return BSP_ERR_INITED; } // 清零回调函数数组 - memset(g_can_callbacks, 0, sizeof(g_can_callbacks)); + memset(CAN_Callback, 0, sizeof(CAN_Callback)); + + // 初始化ID解析器为默认解析器 + id_parser = BSP_CAN_DefaultIdParser; // 创建互斥锁 - g_can_queue_mutex = osMutexNew(NULL); - if (g_can_queue_mutex == NULL) { + queue_mutex = osMutexNew(NULL); + if (queue_mutex == NULL) { return BSP_ERR; } /* AUTO GENERATED CAN_INIT */ - // 注册默认的接收中断处理函数 - for (int can_idx = 0; can_idx < BSP_CAN_NUM; can_idx++) { - BSP_CAN_RegisterCallback((BSP_CAN_t)can_idx, BSP_CAN_RX_FIFO0_MSG_PENDING_CB, BSP_CAN_RxFifo0Handler); - BSP_CAN_RegisterCallback((BSP_CAN_t)can_idx, BSP_CAN_RX_FIFO1_MSG_PENDING_CB, BSP_CAN_RxFifo1Handler); - } - - g_can_initialized = true; + inited = true; return BSP_OK; } int8_t BSP_CAN_DeInit(void) { - if (!g_can_initialized) { + if (!inited) { return BSP_ERR; } // 删除所有队列 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) { - BSP_CAN_QueueNode_t *current = g_can_queue_list; + if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) == osOK) { + BSP_CAN_QueueNode_t *current = queue_list; while (current != NULL) { BSP_CAN_QueueNode_t *next = current->next; osMessageQueueDelete(current->queue); BSP_Free(current); current = next; } - g_can_queue_list = NULL; - osMutexRelease(g_can_queue_mutex); + queue_list = NULL; + osMutexRelease(queue_mutex); } // 删除互斥锁 - if (g_can_queue_mutex != NULL) { - osMutexDelete(g_can_queue_mutex); - g_can_queue_mutex = NULL; + if (queue_mutex != NULL) { + osMutexDelete(queue_mutex); + queue_mutex = NULL; } // 清零回调函数数组 - memset(g_can_callbacks, 0, sizeof(g_can_callbacks)); + memset(CAN_Callback, 0, sizeof(CAN_Callback)); - g_can_initialized = false; + // 重置ID解析器 + id_parser = NULL; + + inited = false; return BSP_OK; } @@ -401,7 +382,7 @@ CAN_HandleTypeDef *BSP_CAN_GetHandle(BSP_CAN_t can) { int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type, void (*callback)(void)) { - if (!g_can_initialized) { + if (!inited) { return BSP_ERR_INITED; } if (callback == NULL) { @@ -414,19 +395,19 @@ int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type, return BSP_ERR; } - g_can_callbacks[can][type] = callback; + CAN_Callback[can][type] = callback; return BSP_OK; } int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format, uint32_t id, uint8_t *data, uint8_t dlc) { - if (!g_can_initialized) { + if (!inited) { return BSP_ERR_INITED; } if (can >= BSP_CAN_NUM) { return BSP_ERR; } - if (data == NULL) { + if (data == NULL && format != BSP_CAN_FORMAT_STD_REMOTE && format != BSP_CAN_FORMAT_EXT_REMOTE) { return BSP_ERR_NULL; } if (dlc > BSP_CAN_MAX_DLC) { @@ -473,8 +454,30 @@ int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format, return (result == HAL_OK) ? BSP_OK : BSP_ERR; } +int8_t BSP_CAN_TransmitStdDataFrame(BSP_CAN_t can, BSP_CAN_StdDataFrame_t *frame) { + if (frame == NULL) { + return BSP_ERR_NULL; + } + return BSP_CAN_Transmit(can, BSP_CAN_FORMAT_STD_DATA, frame->id, frame->data, frame->dlc); +} + +int8_t BSP_CAN_TransmitExtDataFrame(BSP_CAN_t can, BSP_CAN_ExtDataFrame_t *frame) { + if (frame == NULL) { + return BSP_ERR_NULL; + } + return BSP_CAN_Transmit(can, BSP_CAN_FORMAT_EXT_DATA, frame->id, frame->data, frame->dlc); +} + +int8_t BSP_CAN_TransmitRemoteFrame(BSP_CAN_t can, BSP_CAN_RemoteFrame_t *frame) { + if (frame == NULL) { + return BSP_ERR_NULL; + } + BSP_CAN_Format_t format = frame->is_extended ? BSP_CAN_FORMAT_EXT_REMOTE : BSP_CAN_FORMAT_STD_REMOTE; + return BSP_CAN_Transmit(can, format, frame->id, NULL, frame->dlc); +} + int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size) { - if (!g_can_initialized) { + if (!inited) { return BSP_ERR_INITED; } @@ -482,7 +485,7 @@ int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size) { } int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id) { - if (!g_can_initialized) { + if (!inited) { return BSP_ERR_INITED; } @@ -490,7 +493,7 @@ int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id) { } int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t timeout) { - if (!g_can_initialized) { + if (!inited) { return BSP_ERR_INITED; } if (msg == NULL) { @@ -498,12 +501,12 @@ int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t time } // 线程安全地查找队列 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { + if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { return BSP_ERR_TIMEOUT; } osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id); - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); if (queue == NULL) { return BSP_ERR_NO_DEV; // 队列不存在 @@ -514,17 +517,17 @@ int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t time } int32_t BSP_CAN_GetQueueCount(uint32_t can_id) { - if (!g_can_initialized) { + if (!inited) { return -1; } // 线程安全地查找队列 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { + if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { return -1; } osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id); - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); if (queue == NULL) { return -1; // 队列不存在 @@ -534,17 +537,17 @@ int32_t BSP_CAN_GetQueueCount(uint32_t can_id) { } int8_t BSP_CAN_FlushQueue(uint32_t can_id) { - if (!g_can_initialized) { + if (!inited) { return BSP_ERR_INITED; } // 线程安全地查找队列 - if (osMutexAcquire(g_can_queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { + if (osMutexAcquire(queue_mutex, CAN_QUEUE_MUTEX_TIMEOUT) != osOK) { return BSP_ERR_TIMEOUT; } osMessageQueueId_t queue = BSP_CAN_FindQueue(can_id); - osMutexRelease(g_can_queue_mutex); + osMutexRelease(queue_mutex); if (queue == NULL) { return BSP_ERR_NO_DEV; // 队列不存在 @@ -559,5 +562,33 @@ int8_t BSP_CAN_FlushQueue(uint32_t can_id) { return BSP_OK; } +int8_t BSP_CAN_RegisterIdParser(BSP_CAN_IdParser_t parser) { + if (!inited) { + return BSP_ERR_INITED; + } + if (parser == NULL) { + return BSP_ERR_NULL; + } + + id_parser = parser; + return BSP_OK; +} + +int8_t BSP_CAN_UnregisterIdParser(void) { + if (!inited) { + return BSP_ERR_INITED; + } + + id_parser = BSP_CAN_DefaultIdParser; + return BSP_OK; +} + +uint32_t BSP_CAN_ParseId(uint32_t original_id, BSP_CAN_FrameType_t frame_type) { + if (id_parser != NULL) { + return id_parser(original_id, frame_type); + } + return BSP_CAN_DefaultIdParser(original_id, frame_type); +} + /* USER CAN FUNCTIONS BEGIN */ /* USER CAN FUNCTIONS END */ \ No newline at end of file diff --git a/assets/User_code/bsp/can.h b/assets/User_code/bsp/can.h index c589e72..efa2c07 100644 --- a/assets/User_code/bsp/can.h +++ b/assets/User_code/bsp/can.h @@ -23,26 +23,27 @@ extern "C" { typedef enum { /* AUTO GENERATED BSP_CAN_NAME */ BSP_CAN_NUM, - BSP_CAN_ERR = 0xFF, + BSP_CAN_ERR, } BSP_CAN_t; typedef enum { - BSP_CAN_TX_MAILBOX0_CPLT_CB, - BSP_CAN_TX_MAILBOX1_CPLT_CB, - BSP_CAN_TX_MAILBOX2_CPLT_CB, - BSP_CAN_TX_MAILBOX0_ABORT_CB, - BSP_CAN_TX_MAILBOX1_ABORT_CB, - BSP_CAN_TX_MAILBOX2_ABORT_CB, - BSP_CAN_RX_FIFO0_MSG_PENDING_CB, - BSP_CAN_RX_FIFO0_FULL_CB, - BSP_CAN_RX_FIFO1_MSG_PENDING_CB, - BSP_CAN_RX_FIFO1_FULL_CB, - BSP_CAN_SLEEP_CB, - BSP_CAN_WAKEUP_FROM_RX_MSG_CB, - BSP_CAN_ERROR_CB, - BSP_CAN_CB_NUM + HAL_CAN_TX_MAILBOX0_CPLT_CB, + HAL_CAN_TX_MAILBOX1_CPLT_CB, + HAL_CAN_TX_MAILBOX2_CPLT_CB, + HAL_CAN_TX_MAILBOX0_ABORT_CB, + HAL_CAN_TX_MAILBOX1_ABORT_CB, + HAL_CAN_TX_MAILBOX2_ABORT_CB, + HAL_CAN_RX_FIFO0_MSG_PENDING_CB, + HAL_CAN_RX_FIFO0_FULL_CB, + HAL_CAN_RX_FIFO1_MSG_PENDING_CB, + HAL_CAN_RX_FIFO1_FULL_CB, + HAL_CAN_SLEEP_CB, + HAL_CAN_WAKEUP_FROM_RX_MSG_CB, + HAL_CAN_ERROR_CB, + BSP_CAN_CB_NUM, } BSP_CAN_Callback_t; +/* CAN消息格式枚举 - 用于发送和接收消息时指定格式 */ typedef enum { BSP_CAN_FORMAT_STD_DATA, /* 标准数据帧 */ BSP_CAN_FORMAT_EXT_DATA, /* 扩展数据帧 */ @@ -50,11 +51,48 @@ typedef enum { BSP_CAN_FORMAT_EXT_REMOTE, /* 扩展远程帧 */ } BSP_CAN_Format_t; +/* CAN帧类型枚举 - 用于区分不同类型的CAN帧 */ +typedef enum { + BSP_CAN_FRAME_STD_DATA, /* 标准数据帧 */ + BSP_CAN_FRAME_EXT_DATA, /* 扩展数据帧 */ + BSP_CAN_FRAME_STD_REMOTE, /* 标准远程帧 */ + BSP_CAN_FRAME_EXT_REMOTE, /* 扩展远程帧 */ +} BSP_CAN_FrameType_t; + +/* CAN消息结构体 - 支持不同类型帧 */ typedef struct { - CAN_RxHeaderTypeDef header; - uint8_t data[BSP_CAN_MAX_DLC]; + BSP_CAN_FrameType_t frame_type; /* 帧类型 */ + uint32_t original_id; /* 原始ID(未解析) */ + uint32_t parsed_id; /* 解析后的实际ID */ + uint8_t dlc; /* 数据长度 */ + uint8_t data[BSP_CAN_MAX_DLC]; /* 数据 */ + uint32_t timestamp; /* 时间戳(可选) */ } BSP_CAN_Message_t; +/* 标准数据帧结构 */ +typedef struct { + uint32_t id; /* CAN ID */ + uint8_t dlc; /* 数据长度 */ + uint8_t data[BSP_CAN_MAX_DLC]; /* 数据 */ +} BSP_CAN_StdDataFrame_t; + +/* 扩展数据帧结构 */ +typedef struct { + uint32_t id; /* 扩展CAN ID */ + uint8_t dlc; /* 数据长度 */ + uint8_t data[BSP_CAN_MAX_DLC]; /* 数据 */ +} BSP_CAN_ExtDataFrame_t; + +/* 远程帧结构 */ +typedef struct { + uint32_t id; /* CAN ID */ + uint8_t dlc; /* 请求的数据长度 */ + bool is_extended; /* 是否为扩展帧 */ +} BSP_CAN_RemoteFrame_t; + +/* ID解析回调函数类型 */ +typedef uint32_t (*BSP_CAN_IdParser_t)(uint32_t original_id, BSP_CAN_FrameType_t frame_type); + /* Exported functions prototypes -------------------------------------------- */ /** @@ -98,9 +136,33 @@ int8_t BSP_CAN_RegisterCallback(BSP_CAN_t can, BSP_CAN_Callback_t type, int8_t BSP_CAN_Transmit(BSP_CAN_t can, BSP_CAN_Format_t format, uint32_t id, uint8_t *data, uint8_t dlc); +/** + * @brief 发送标准数据帧 + * @param can CAN 枚举 + * @param frame 标准数据帧指针 + * @return BSP_OK 成功,其他值失败 + */ +int8_t BSP_CAN_TransmitStdDataFrame(BSP_CAN_t can, BSP_CAN_StdDataFrame_t *frame); + +/** + * @brief 发送扩展数据帧 + * @param can CAN 枚举 + * @param frame 扩展数据帧指针 + * @return BSP_OK 成功,其他值失败 + */ +int8_t BSP_CAN_TransmitExtDataFrame(BSP_CAN_t can, BSP_CAN_ExtDataFrame_t *frame); + +/** + * @brief 发送远程帧 + * @param can CAN 枚举 + * @param frame 远程帧指针 + * @return BSP_OK 成功,其他值失败 + */ +int8_t BSP_CAN_TransmitRemoteFrame(BSP_CAN_t can, BSP_CAN_RemoteFrame_t *frame); + /** * @brief 注册 CAN ID 接收队列 - * @param can_id CAN ID + * @param can_id 解析后的CAN ID * @param queue_size 队列大小,0使用默认值 * @return BSP_OK 成功,其他值失败 */ @@ -108,14 +170,14 @@ int8_t BSP_CAN_RegisterId(uint32_t can_id, uint8_t queue_size); /** * @brief 注销 CAN ID 接收队列 - * @param can_id CAN ID + * @param can_id 解析后的CAN ID * @return BSP_OK 成功,其他值失败 */ int8_t BSP_CAN_UnregisterIdQueue(uint32_t can_id); /** * @brief 获取 CAN 消息(阻塞方式) - * @param can_id CAN ID + * @param can_id 解析后的CAN ID * @param msg 存储消息的结构体指针 * @param timeout 超时时间(毫秒),0为立即返回,osWaitForever为永久等待 * @return BSP_OK 成功,其他值失败 @@ -124,18 +186,39 @@ int8_t BSP_CAN_GetMessage(uint32_t can_id, BSP_CAN_Message_t *msg, uint32_t time /** * @brief 获取指定ID队列中的消息数量 - * @param can_id CAN ID + * @param can_id 解析后的CAN ID * @return 消息数量,-1表示队列不存在 */ int32_t BSP_CAN_GetQueueCount(uint32_t can_id); /** * @brief 清空指定ID队列中的所有消息 - * @param can_id CAN ID + * @param can_id 解析后的CAN ID * @return BSP_OK 成功,其他值失败 */ int8_t BSP_CAN_FlushQueue(uint32_t can_id); +/** + * @brief 注册ID解析器 + * @param parser ID解析回调函数 + * @return BSP_OK 成功,其他值失败 + */ +int8_t BSP_CAN_RegisterIdParser(BSP_CAN_IdParser_t parser); + +/** + * @brief 注销ID解析器 + * @return BSP_OK 成功,其他值失败 + */ +int8_t BSP_CAN_UnregisterIdParser(void); + +/** + * @brief 解析CAN ID + * @param original_id 原始ID + * @param frame_type 帧类型 + * @return 解析后的ID + */ +uint32_t BSP_CAN_ParseId(uint32_t original_id, BSP_CAN_FrameType_t frame_type); + /* USER CAN FUNCTIONS BEGIN */ /* USER CAN FUNCTIONS END */ diff --git a/assets/User_code/bsp/gpio.c b/assets/User_code/bsp/gpio.c index da3a24c..59acc4f 100644 --- a/assets/User_code/bsp/gpio.c +++ b/assets/User_code/bsp/gpio.c @@ -43,8 +43,8 @@ int8_t BSP_GPIO_RegisterCallback(uint16_t pin, void (*callback)(void)) { return BSP_OK; } -int8_t BSP_GPIO_EnableIRQ(uint16_t pin) { - switch (pin) { +int8_t BSP_GPIO_EnableIRQ(BSP_GPIO_t gpio) { + switch (gpio) { /* AUTO GENERATED BSP_GPIO_ENABLE_IRQ */ default: return BSP_ERR; @@ -52,15 +52,14 @@ int8_t BSP_GPIO_EnableIRQ(uint16_t pin) { return BSP_OK; } -int8_t BSP_GPIO_DisableIRQ(uint16_t pin) { - switch (pin) { +int8_t BSP_GPIO_DisableIRQ(BSP_GPIO_t gpio) { + switch (gpio) { /* AUTO GENERATED BSP_GPIO_DISABLE_IRQ */ default: return BSP_ERR; } return BSP_OK; } - int8_t BSP_GPIO_WritePin(BSP_GPIO_t gpio, bool value){ if (gpio >= BSP_GPIO_NUM) return BSP_ERR; HAL_GPIO_WritePin(GPIO_Map[gpio].gpio, GPIO_Map[gpio].pin, value); diff --git a/assets/User_code/bsp/gpio.h b/assets/User_code/bsp/gpio.h index a11d717..d7e4ec1 100644 --- a/assets/User_code/bsp/gpio.h +++ b/assets/User_code/bsp/gpio.h @@ -22,8 +22,8 @@ typedef enum { /* Exported functions prototypes -------------------------------------------- */ int8_t BSP_GPIO_RegisterCallback(uint16_t pin, void (*callback)(void)); -int8_t BSP_GPIO_EnableIRQ(uint16_t pin); -int8_t BSP_GPIO_DisableIRQ(uint16_t pin); +int8_t BSP_GPIO_EnableIRQ(BSP_GPIO_t gpio); +int8_t BSP_GPIO_DisableIRQ(BSP_GPIO_t gpio); int8_t BSP_GPIO_WritePin(BSP_GPIO_t gpio, bool value); int8_t BSP_GPIO_TogglePin(BSP_GPIO_t gpio); diff --git a/assets/User_code/bsp/spi.c b/assets/User_code/bsp/spi.c index e545e80..26474cf 100644 --- a/assets/User_code/bsp/spi.c +++ b/assets/User_code/bsp/spi.c @@ -1,4 +1,5 @@ /* Includes ----------------------------------------------------------------- */ +#include #include "bsp\spi.h" /* Private define ----------------------------------------------------------- */ @@ -134,34 +135,29 @@ int8_t BSP_SPI_TransmitReceive(BSP_SPI_t spi, uint8_t *txData, uint8_t *rxData, uint8_t BSP_SPI_MemReadByte(BSP_SPI_t spi, uint8_t reg) { if (spi >= BSP_SPI_NUM) return 0xFF; - SPI_HandleTypeDef *hspi = BSP_SPI_GetHandle(spi); - if (hspi == NULL) return 0xFF; - - uint8_t data = 0; - HAL_SPI_Mem_Read(hspi, reg, &data, sizeof(data)); - return data; + uint8_t tmp[2] = {reg | 0x80, 0x00}; + BSP_SPI_TransmitReceive(spi, tmp, tmp, 2u, true); + return tmp[1]; } int8_t BSP_SPI_MemWriteByte(BSP_SPI_t spi, uint8_t reg, uint8_t data) { if (spi >= BSP_SPI_NUM) return BSP_ERR; - SPI_HandleTypeDef *hspi = BSP_SPI_GetHandle(spi); - if (hspi == NULL) return BSP_ERR; - - return HAL_SPI_Mem_Write(hspi, reg, &data, sizeof(data)); + uint8_t tmp[2] = {reg & 0x7f, data}; + return BSP_SPI_Transmit(spi, tmp, 2u, true); } int8_t BSP_SPI_MemRead(BSP_SPI_t spi, uint8_t reg, uint8_t *data, uint16_t size) { if (spi >= BSP_SPI_NUM) return BSP_ERR; - SPI_HandleTypeDef *hspi = BSP_SPI_GetHandle(spi); - if (hspi == NULL || data == NULL || size == 0) return BSP_ERR_NULL; - - return HAL_SPI_Mem_Read(hspi, reg, data, size); + if (data == NULL || size == 0) return BSP_ERR_NULL; + reg = reg | 0x80; + BSP_SPI_Transmit(spi, ®, 1u, true); + return BSP_SPI_Receive(spi, data, size, true); } int8_t BSP_SPI_MemWrite(BSP_SPI_t spi, uint8_t reg, uint8_t *data, uint16_t size) { if (spi >= BSP_SPI_NUM) return BSP_ERR; - SPI_HandleTypeDef *hspi = BSP_SPI_GetHandle(spi); - if (hspi == NULL || data == NULL || size == 0) return BSP_ERR_NULL; - - return HAL_SPI_Mem_Write(hspi, reg, data, size); + if (data == NULL || size == 0) return BSP_ERR_NULL; + reg = reg & 0x7f; + BSP_SPI_Transmit(spi, ®, 1u, true); + return BSP_SPI_Transmit(spi, data, size, true); } diff --git a/assets/User_code/bsp/uart.c b/assets/User_code/bsp/uart.c index d9a235d..8cde78a 100644 --- a/assets/User_code/bsp/uart.c +++ b/assets/User_code/bsp/uart.c @@ -1,5 +1,5 @@ /* Includes ----------------------------------------------------------------- */ -#include +#include #include "bsp/uart.h" diff --git a/assets/User_code/component/ui.h b/assets/User_code/component/ui.h index 5580d3e..3cfb3bb 100644 --- a/assets/User_code/component/ui.h +++ b/assets/User_code/component/ui.h @@ -45,12 +45,12 @@ typedef enum { WHITE } UI_Color_t; -typedef struct __packed { +typedef __Packed struct { uint8_t op; uint8_t num_layer; } UI_InterStudent_UIDel_t; -typedef struct __packed { +typedef __Packed struct { uint8_t name[3]; uint8_t type_op : 3; uint8_t type_ele : 3; @@ -66,28 +66,28 @@ typedef struct __packed { uint16_t y_end : 11; } UI_Ele_t; -typedef struct __packed { +typedef __Packed struct { UI_Ele_t grapic; } UI_Drawgrapic_1_t; -typedef struct __packed { +typedef __Packed struct { UI_Ele_t grapic[2]; } UI_Drawgrapic_2_t; -typedef struct __packed { +typedef __Packed struct { UI_Ele_t grapic[5]; } UI_Drawgrapic_5_t; -typedef struct __packed { +typedef __Packed struct { UI_Ele_t grapic[7]; } UI_Drawgrapic_7_t; -typedef struct __packed { +typedef __Packed struct { UI_Ele_t grapic; uint8_t character[30]; } UI_Drawcharacter_t; -typedef struct __packed { +typedef __Packed struct { uint8_t del_operation; uint8_t layer; } UI_Del_t; diff --git a/assets/User_code/component/user_math.c b/assets/User_code/component/user_math.c index 1fceac2..f3f3964 100644 --- a/assets/User_code/component/user_math.c +++ b/assets/User_code/component/user_math.c @@ -117,16 +117,16 @@ inline float CalculateRpm(float bullet_speed, float fric_radius, bool is17mm) { return 60.0f * (float)bullet_speed / (M_2PI * fric_radius); } -/** - * @brief 断言失败处理 - * - * @param file 文件名 - * @param line 行号 - */ -void VerifyFailed(const char *file, uint32_t line) { - UNUSED(file); - UNUSED(line); - while (1) { - __NOP(); - } -} +// /** +// * @brief 断言失败处理 +// * +// * @param file 文件名 +// * @param line 行号 +// */ +// void VerifyFailed(const char *file, uint32_t line) { +// UNUSED(file); +// UNUSED(line); +// while (1) { +// __NOP(); +// } +// } diff --git a/assets/User_code/component/user_math.h b/assets/User_code/component/user_math.h index eda0545..13e1ae5 100644 --- a/assets/User_code/component/user_math.h +++ b/assets/User_code/component/user_math.h @@ -8,12 +8,11 @@ extern "C" { #endif -#include "stm32f4xx.h" -#define ARM_MATH_CM4 - #include #include #include +#include +#include #define M_DEG2RAD_MULT (0.01745329251f) #define M_RAD2DEG_MULT (57.2957795131f) @@ -149,10 +148,10 @@ float CalculateRpm(float bullet_speed, float fric_radius, bool is17mm); #define VERIFY(expr) ((void)(expr)) #endif -/** - * @brief 断言失败处理 - * - * @param file 文件名 - * @param line 行号 - */ -void VerifyFailed(const char *file, uint32_t line); +// /** +// * @brief 断言失败处理 +// * +// * @param file 文件名 +// * @param line 行号 +// */ +// void VerifyFailed(const char *file, uint32_t line); diff --git a/assets/User_code/config.csv b/assets/User_code/config.csv index 66f08b4..047265b 100644 --- a/assets/User_code/config.csv +++ b/assets/User_code/config.csv @@ -1,4 +1,4 @@ bsp,can,dwt,gpio,i2c,mm,spi,uart,pwm,time -component,pid,filter,ahrs +component,ahrs,ballistics,capacity,cmd,crc8,crc16,error_detect,filter,FreeRTOS_CLI,limiter,mixer,pid,ui,user_math device,dr16,ai,nuc module,chassis,gimbal,arm,shoot \ No newline at end of file diff --git a/gpio.h b/gpio.h index 3ad4f46..9ed26d4 100644 --- a/gpio.h +++ b/gpio.h @@ -26,8 +26,9 @@ typedef enum { /* Exported functions prototypes -------------------------------------------- */ int8_t BSP_GPIO_RegisterCallback(uint16_t pin, void (*callback)(void)); -int8_t BSP_GPIO_EnableIRQ(uint16_t pin); -int8_t BSP_GPIO_DisableIRQ(uint16_t pin); +int8_t BSP_GPIO_EnableIRQ(BSP_GPIO_t gpio); +int8_t BSP_GPIO_DisableIRQ(BSP_GPIO_t gpio); + int8_t BSP_GPIO_WritePin(BSP_GPIO_t gpio, bool value); int8_t BSP_GPIO_TogglePin(BSP_GPIO_t gpio);