From ebd65366c95968731104f31b13ab0c5ee6a9bc3d Mon Sep 17 00:00:00 2001 From: Frank Voorburg Date: Fri, 26 May 2017 14:06:01 +0000 Subject: [PATCH] Refs #268. Removed deprecated SerialBoot program and sources. It is replaced by BootCommander and LibOpenBLT. git-svn-id: https://svn.code.sf.net/p/openblt/code/trunk@271 5dc33758-31d5-4daf-9ae8-b24bf3d40d73 --- Host/BootCommander.exe | Bin 0 -> 96256 bytes Host/SerialBoot.exe | Bin 61440 -> 0 bytes Host/Source/SerialBoot/CMakeLists.txt | 82 -- Host/Source/SerialBoot/firmware.c | 125 --- Host/Source/SerialBoot/firmware.h | 84 -- Host/Source/SerialBoot/main.c | 365 --------- .../Source/SerialBoot/port/linux/serialport.c | 208 ----- Host/Source/SerialBoot/port/linux/timeutil.c | 69 -- .../SerialBoot/port/windows/serialport.c | 260 ------ .../Source/SerialBoot/port/windows/timeutil.c | 60 -- Host/Source/SerialBoot/serialport.h | 70 -- Host/Source/SerialBoot/srecparser.c | 751 ----------------- Host/Source/SerialBoot/srecparser.h | 52 -- Host/Source/SerialBoot/timeutil.h | 52 -- Host/Source/SerialBoot/xcploader.c | 755 ------------------ Host/Source/SerialBoot/xcploader.h | 108 --- Host/Source/SerialBoot/xcptpuart.c | 255 ------ Host/Source/SerialBoot/xcptpuart.h | 66 -- 18 files changed, 3362 deletions(-) create mode 100644 Host/BootCommander.exe delete mode 100644 Host/SerialBoot.exe delete mode 100644 Host/Source/SerialBoot/CMakeLists.txt delete mode 100644 Host/Source/SerialBoot/firmware.c delete mode 100644 Host/Source/SerialBoot/firmware.h delete mode 100644 Host/Source/SerialBoot/main.c delete mode 100644 Host/Source/SerialBoot/port/linux/serialport.c delete mode 100644 Host/Source/SerialBoot/port/linux/timeutil.c delete mode 100644 Host/Source/SerialBoot/port/windows/serialport.c delete mode 100644 Host/Source/SerialBoot/port/windows/timeutil.c delete mode 100644 Host/Source/SerialBoot/serialport.h delete mode 100644 Host/Source/SerialBoot/srecparser.c delete mode 100644 Host/Source/SerialBoot/srecparser.h delete mode 100644 Host/Source/SerialBoot/timeutil.h delete mode 100644 Host/Source/SerialBoot/xcploader.c delete mode 100644 Host/Source/SerialBoot/xcploader.h delete mode 100644 Host/Source/SerialBoot/xcptpuart.c delete mode 100644 Host/Source/SerialBoot/xcptpuart.h diff --git a/Host/BootCommander.exe b/Host/BootCommander.exe new file mode 100644 index 0000000000000000000000000000000000000000..aa986f210b34d75b5c1b8c7ae4589db6e24bf0f7 GIT binary patch literal 96256 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

UumnEgiur3T4#e-BU5mWv)e6 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 Xq$U22inmRCJICAQ*JTF&Ee!kvAL#7V literal 0 HcmV?d00001 diff --git a/Host/SerialBoot.exe b/Host/SerialBoot.exe deleted file mode 100644 index 5d4e0a5450de0a752ad8e2d9ff06138b89d06984..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61440 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 EFOZD<18i&{W1JX#cxk`afv@rdeR> zTwoZ|{?llLqy3Y6kQDXl4**!^>9YvSJbeP;^YIk^Y^Za5Gg{ux9=SnJ#&8Y$E->2Z z6w-Kqif`+u)k2C=Nqu3Op+=mn%XnLFS0N%iHx3&Ii^GO}QexH^baDxDV;9AiFwG#V z!|-#M1H&8`=D-)01MshV8t*HNPLtw&=zGdaclYnnHCXWf;=2ZWFog);85$d!jv4a> zXlAx8!i}P^xlm|9Umg>WSS#l%&qG@c*CL+?iAnc4N=&~{wi4lHo`Fx0-Ug63SIX(h zCphLG7wX?iAuJ{iZRnbU95k7Em6#LoTZtkJ5DBzc823EpV)#xkMIvqz3gCrn0Rjvs z)Cpxv>A~JK`Fo|IkJX}s+(*#ry4Qk3?tuh0-2;5!iDuV55x_K`qG=62k@DY^MSBui z?!zs%)3q2`q8;i-39OI6-2WR7mIE-XSEseSawqk?e?Wj60pnJ^9S=ALfbvWOTCw%5 zL`m!VCE$!SonOYsyfkHMj|>ru?Kl@v49(GD?qj_&skPaOOyOS*!C*H}iJLG9f7r)a zEOyUmI&3CtD*P6)n%zZd$(@)-mB--t^rU%BA5E9}lENv%H1z85@yUT^!o!5^$YQe( z_{_EPlo?B*6o)WJE&`)ce};@rv#XVoF$_tszPBC4=Lm@SnsvsOWK zkb1iuSh^9c(K)+*Wj?t?0G3qGO?qbv@X5y15A$ ztGBiyjD0<;@ltE8W$o>EAXF?I#Haw1OWf4y^YS_Fod9%iz%ABjAHy0E?LbvIYHjW9 zgb^D$=0rC{tmnzKa1tP-DNB)X%*};(gU}of32-*(ZENT15C=D`o5)I!(3TSu<=2e|mMH5VL6n8fF=&-ymN$_Cj#7aM9PJSEL`RjI zisAg|e1xF^&|k;U0EqMzhPx3-WVm2FdjPN}p&C#rb`0STgh{Fg5hj%>M7RUtMvvED z>i4p$%B7_)Z;i9g;l$Z1KIX5fcXuEYo5za%eX(eVn@&g=k6R%*BS+T@Q3tO*cq zHR*B8Co*>e40goYu>?mtiN*w-07-4tBKsEtMq02O!}kEI<7dSOOThHkA#eT-vKm#o zhOmOo{2OFtDaM(oD*#v;!c{Bhdu#lDSA)d3&r;tPsUn4_gL`5^MRoyww7!Q4>==R7 zC3uE!0qmUhRf+Xo4w&=Rw-=QV-i8WA>zhkh<@)x=)R)bp`j)tyRYO|B>#K^FD_oWM zHIi~=4t9}8Cbl;rCpN9o2k7A`w43`T1g@mOcM!OQ0w)kiqrhJ5+8T)f0b?T_QG)p` zD=^H&H5XSIuEn?#RCW0EpTGg~2lR31WKp|PF~3JbDbm+zRe;7(?o2_hHtZp+@EM9oq zUS)z7A%Agc=*_mG!SeaYUS#|r*LcVE#z=TX`+va>S?DGuDP?+Y^Xeq-!~z$FX5}iA z_u^ZL=Dai_!k-rL=VEiH(jhzqQ^Me2cCbrrGp^nj3aE^c&;gLPBvh!p9%ea!@Vw?} zlr8Y(<~!1P;KJrR#__-u3lj z7J%Nmfb5y-B>mRrf9H>d*sC-F{T2oFU23txhN2XLJ&hsn#~P~FI5`i1BrpN`ft2)p zha;JExI!e84pN9@(xEDmOga>UiU2XSr`>5g;XQYH;J&t!5FNqZiJ*>ueyO()7@v2v z+xx1vQBs>rIAH$+oYi3k&~s0Aq}~39Hv4PjoA7J5A9mD^Kp(61OZA2LToU>hzKFie z#uo|A7K+qt>I`-63%La3K*xuMK7YUVu+QiM_o@3J%QIwEPL|DKC#n)vP;?D0kX}g{&Oky8~sIz$#nE>f1Z?``Ibr2lF2~Zx~Z^65JJb}2ixKoOhZz4qsQ@GtJ+t;NK zGB`aVPlRyPD(6RjK`aq6In?CE3oFDe_}NmQ!mR}zLtv+Qk!i49`ev^}7$bqn*247} z{0$B$S6&rTw+y^f$U^BYt(ag5eiZR%l{ktc0hO>@M1wWHj0cdk2Uu8%gAW*a`gi4Y zX+2X7Hx(z(ww8g9Bay9)%d{WC($H-v6ykgasMgw;X5D=VlnPS`Q^!yu}$>j-?*{>&gEr@VE``s)?f zBVr)*;#037LuXIY`~Mw!F?b^R{YOH7UY|502Ke#lwX8C#Gxw|WBdO>D43%* zDe?=VJ@N~xjPNkX3GPqhoLwk90hdIs2>OiO7l>7pyIP|%elX=XZFq+P6%7Ul(!42q zU}wzM=gV9_-m2NP&*AO^atx42&Ok;!w=8XT>x5uu^7Y{^7(>MYdbN8ZDz>B0TDceNbG zo!Be{Mx#0d5JO8OpeYy1@roCGhYA4hRUyI4s$f8{zMj7_SYJLZ8Tzh*GQS2GM=jVy zIHT$94^ljusFYtG`7am@xf|gpr)VBSiG4&9L!6M(@`$Nr3j~Jmxxi%bx1~eVLZ4(~ z@PmO&@EJ~GK-B`>LAh*Qhkp!?ECMA27)FenzHVu6=|y%BbC8IUqWGuk?Xy322;Trh z&cXzKIe#J(g6mM zOgf+-l1US;kxZJ)jbzf79Fa`=R49^3AFd2}zr%-ZsdQ#SAnE;mJ;gvu_9Cj&wx|2x zNfm-o!&M)4=n$rg;b1EZ7h@KGswo>A@9eC?X*@8Qf-<9$RPo*LF zPANp+HZmO4&~?`nh#|W7@EDw8mO+ebo0mGkV>-L>acmmJ%uN|^S3!Ql&(KgM^v=Zo zlS;raU+TGY{)`v-a|n|S;151&Q~k5KL!YRBR-RC2jq8WoRD{#)28oO@WaLQbn8guAv8KfIgEhtm9-9xG&^$qbs zG!7r3Bb(?Od0Ua%mw|x{jc|(6a7ta9a`PSlhu;)g_AOAwSr*B3aO<4Q?=%+~$(+S4 z75X7qz`ktiqs>F*V?t#sQq5w}n(L$*-HAfVgEZdKAtY9GC* zge%6P#ZjYX!TfY6DhrHpZ}HKDPoIcV*a(1N{y3yX0vAvLy<&o~W5}XGkGmrP?cRp= z3v_H90P=0eadXoxl-iGbvHLZOI6}9>xJ5FKa7^jjj^QnsPj|LvbgfEQc>%`~hreno zc2vm&Ta<_KhGQo%#f~@jpFH?dvZ?!c%n`*AcT3=0&m2lLYarwFKPCkQWzU4ZaSVk8S#x>9&5VBO=t z3;NXG23uM=TU0RPi@NNuQD;ILwS?@i^~?j}@aV3T4%DB@knxXqtL_B?wh;)5Lq`^=?9wPgP`r5s{1yP(g_W;Szqb9cB#d#}Gn4@mPuA8ATePqVZkG zek=}UYABU(qHlQeoH%)@=Nt`ke~bB2J~ImKv=3-@tC~M5x)lte&tWU*d-Z2!pTG7P(P@I0QIB*|) zmK;a(oz))-2O$IDD!5Ci{nl>OFxs0ve0b~0_;=_({49-6Mun6u+V2;_FkNq8`73axVusaBmKCMQ94ENbP9B(5L9eB`qRNv%9URVDL3=+5WcBW^U!Vkf(MD_ zNM<4TP11Y-_WQ^6x7OzO5=MU-9p6AlrQC-@{fH9>QYb+osK6%btqLf$+^yU~4kC|q z4(9<=Kh|F>c39h~4_geCDiotj&5gif- z#@4Fh(gVxfbdWXdY1~#&fgFLdA?P`=U1_oui4NV_=#b`%K*t${BpExTLu0;)Q~cs} z0`d^g!x$Q$NTd7t^5{N~81!mr07H>$hltb6pYM)Ixv;|6A&zo|YotQTL)kRMcP~Kx z`H|Pfqboq)jc&IbLmS8uV{xyRW9YO7#9WQ>074F$9CEiJ(Vc{GYGgB=eu3mm=SMPT z0r%peQh$z~J5^2GtK7wREUS{ zaPS#AE^HO z9RPbVw)rZK1B@yS*B3SVk3;$b|Ipq}yugT7?WTqWUwY$?NU|R}j1yIhYm@2ZTZeFp zJKc$p# zwcU<6>p)t$@C^Wxo7_L{!((6WFuqi{SZI+7>ls7cH%SQw|CMF*+et`K}%x7O5QrX_{jtad$+J zDQ}PMl>fHt*XI9`99lpd%oljzMj-{<*+ws5VcvlhN>_wawo;7yTJR4}i);_6m$&1v zP8u$^7aikII1&(#!?d;F=_m|e#Y&+KGyb;iHX)>lq~%Y)$Dq)((BbchrbSkFA&{0L z%`qNcZCxc#IoV#;Us{UTlJfZx2heHO&EN@GmmO@oZLlPy2o<^`N7f6s`C z`RK1r5i060!E^x#3mgv>HgZI0mucmMmBx_aAToFb(n8>UQ9o6sFjRChG&WLV0rTm3 zEzbPf$2CuyFHCo!JCE**8mpozhkNZ3NS#K5!gd%Y)SS1Gd1xaenF0!kWbVgZ9CgEf zktd{T&aL#-cL#2v$*ZJbQ(AIh7MkSH*ygXLYg4{`iT^7i)T;C==xsa)Yi>%vlHSng z5FuIN_s}^NEGU(;CXALQVT}Uix%)6tFI>V&L)V374Gwau4&#n=-kpeKQWrgvNyCds zCUqzynbaXfI{HsUOpz*iP9DDglY2L1=u6E=hg90W%xOC7+~J9(-Y($(Eo4T z2@c2g|Bsxn|9_IP=!gv6dWY~f#Lnm00@N$Vi`*rpUissAMeU{(oy2yNP}va(6rM-3PxPM!{Id;NQ8|6sUC?gm5B zIN+JO!TX!n?8js>{6Lre80jXh)E*Oa9}|~6I_NEmrGqc!q9wuRud}XzMCB!RXf?aX zHlK=icWrziIw;B!vT3$PySrLgZLnh;4v~ft@LbV;Zwl8fE}2Ls_3k5?)E|#zQrDiB zmoDjqv;m0l&7he)G+5Rs7#Q#4FoDUxB~83v7XAUzGVjYWN2+Xmb1gT^CJ#^yDHR6g-_@D>EZ zmjSBz1kr&7Mx-Aadp(^vpLPK}B_E(~BbosulP75+>KEJHCVeap=F?CcJ$?+NDG)GA zF#$QoKheDa4qF5DRn}@TCLe$^2lvk@R^J3ts@)iY;iI6@gyZ&&D(C2dlbgU9XdrcPkYFH@zB+7Dvd$H*Eia zTsURQo>r8K5quZa7N!M0;~m3B$_NQb8Trga6i;`1QFk#lXXG};Iyr>@ipbf`=JrX>iY(7nK-ajsm^-$%{p4`FVRX;rwp5i!sB(oQc zl*UVZe_B%bl8}8o+L3W+N7BKNG=%ZF|3(lL>jFuBtagHX=fhAZ)i&HLbff?D2sZ^9 zJE0O;FamN2Te!;-Tc19Z7s>4B_W^!a@%Bi~?`iy=&hO*+eLTNw`F$e4lLkgIujO|W zzgzgdiDUEgdn3Qs@jH#(Fz?LoOZa^ezmotl@67KGexJ+l)TzTP7r)cMDw3JU?-qV1 zi;rZI4*(7PP8t>0Gz`BCb6}VQ!yFjqz%U1fIWWwDVGay)V3-5L92n-nFb9S?FwB8r z4h(Z(m;=Kc80Nq*2ZlNDugL*go*DlAn{!}iRpGyR4Tq~Y%z;nG0qw9Yu$}lS;XnPi zq;Z%B|LHm)*FX2+A1H0%KHH>etH7_8&D~YK3Kx%V{9GL)*-F$@W7ySxvEM!M;v6~Qw%Ylo2lfPHURQDIM$@n&P4z9JhcHqJu8~&qb>{aT=N$*;x z*Ar-{()!&l?FuJOzgb%6(oSNNv@4xHZKcQS4K(^)Rat~!UOWh3YJA$Iu9}8r+JMhh zrCnL$cjLSqDXONS#*edf@L!aRx#j$I0hiWOt+kgrco7XAzqZlqX>@t(R%w0C6~N=H z^m=?gty5baXsGnpcp9{o&bqoRt#+Op1>#@87eK@+K;Rft{5PzGk3fi$m|Rt^$~vc4 zB24RPa7BSCJq;^d4IDKQ9h<4qQ`6vgdA0GGo!Y9J>S~u4na+YFYcxN`U^YPaD$nzQa&?J7?|>jP8k zs?_ zD&0=6wo;p~om`{6TB~cCJ^LEl=+v2RXTvh$A;;^fa)B0^u2qn3U7ePs-!PAJtlSuSXp(>ZeA5q`xUG*L>(8a2k%)dGh#5kme1j8A&)K%^A zf*ilZp{Qo@jB$7+b*=#Wf$WT8${Ln8cvd!OO9J3=y-PdO?Sc*1ydR*-}==Vf{$cvMS{Du|~u>*($u3 zuzA3uWkrDT;m^sIA;gU;THaK^oUO#!fUW_i0Lmn4u40+MuVqtlWdavta-C+^)VUg* z^)5t3WTT@|Ug> z^(|`nu!$%=_{fK`(X(JNR&5>+PvgsX?w9p34bI)v&K2y$bk5Ey9Nv%*qxarV95J z(09^h4g=fj>5TE6L4oC7yV55p2mS|HLgv#I&g_Rmz}L7 zW4L;PpXn66sO&?z`y|&%o+Z|E0#?K$=}`=tx$&MP&Wp$mlan+jiX*{sMAeSLwuy6# zV7;Zx!Dg`;Ob?CMp?R0G(#m1uB~sd~7>l4b9pA{(Z!Nxd!lUm_dPYV<7l5N2 zcL%#cvZEoKC9Y++G`bpYa;>sA%||Z07YAJ4Rpm~!p<)!p%>+wa00ITKu-Wh;^MS7f zo{A{0;ga(}Mjpt=kGOKg`5-USfl@9x@>U+CP_431uSJM=@svgmKNDp;Ab$_!9pHK~ z3pu=qWl;_!@`lpR7U!5XgX)AT)S&HiWfPo;N$i_Y|0o$3eW5>@Ypn;oCw(H#U5d~$ zgc_jHS8%<)8UB}Kpk-I%Pt^0+94^3;w~U9r1~IGgr~QO7MBDkaWyC{YgBpmxzlU9s zwa3;=wykRGqN=JzD=PgSPn~a3rPoi_N~2*>Rb8FWAE>Tgh;*HUGSpsw90{@05eNnJ;`%oYHZ$L4e zWtaoQ95@FDN=j#y-oD2lx$%$PH|)vX^zwI~tER7e*-Y!A`5y1`MLtipeTF@ zF?ZggIUb*Xk$6n&43Ed3)mXJuMtubWbPfN`&w-tu^QRA|{%3H&u>k$@b6o!!92lg=&Ob78eH@{Tlzty{Wc+ee@y;&t8u{H zviSTvW77X}dm$U|jZZ%ulTPJY0%AIahkt)R4$S29X7e##^Rnr2!&7$OLH?bkmBJm)rj$8E?UMXkNq1t zesK;qafX9x_eG$~!AJLJqi&eKbICO^em3MUt}evSV#yjjEay+QkMrrF%*TJ#r@f@) zmJ%#9+;Y=sW{)oO4ULhtQ>$j)Qe@IjU7DR^*6FnMtEy|f^)#x^^67I&v#EctA845A zXp8PsPAu+dwQj$^(R$r=D_5?}s^(Eym7e<1OdI>t>$44@4-1#R z>wGRO(pF{B`bkVpR=B)AS`ap5>2z6Ihs%p~!Fr!ou8%g*NVCd5?TQ+#x?)8VMPm(G zOaH^mXa-oVQ(IqyW*N&Q+Zpfyz2EW=74EvbX)^?`<(O1}1?^)Hi_=Bcu_)(P_$0$7r;96GWuU~IHTeNkN^3UK(s80x#Kj&-0MLT#z>w?w{#B*A1bn4|Mv^Wq9!h*dHN9YIE>!(mtv(kT zb*VjbP1MQ{j{~fn`jIoq2x!fuIBX<7D>+a6!u}^6xK&jv30R~oqTC7GawS9^~srG zOu8l_nj?;9not(+^E4pFkNp=~q|@pT{XWn7(OTq6cC$qFnf+RFET1QR z#GiOR-T?kKfp>YhO0h0Xl5@n29B9lj#Pzx8YtqQ%dc^vp^_+?NihE)vV;xTZeV+A{ z^=2L@o6Yr+_QrfZ{p0i51M%wf!8U_?h9#e87L-O-LUxd%IJ&*!)2DztjEpY?2Q8TB$gFa8b7k;V#Vu1}mx z?}z1hem!3RO?F^K=oY>U*p9JT1>UD4_9pD!orkwl>9DxFe3_)nQ?U=7 zc4&(`y3Yqmvl@i$v&)HQF+Q($X<`PO-OHfv>x!BW*fj=AsvRv!o`U7r(t-$a+PPX z7hwgB=BukPZdr*LV%jk`G_I7PL?3XzzS0+w-uN-ZkOus#)dO2cBmYYLU9>1`5m}O~ zJ@kFF`1SsoYl2_IdVO)cz^A7~0no&Y{>P@DUGm&4il=?f^!xM}harbK@UO=KCB9g^ z5ZBeX47jG@nu}`zF8Xg~n{chibuX@d{KvU(;W~)xC%Ep%wGP(`T-CVd;hKXh57)K0 z(r}#`sbD8@y@IO)*G^my;aZPt%qX(7|NC!Oih{k2>o~4=aGk=X9-&~D<1*l~;(7pa zbMah?YXz=#xHjT?0N10q9>?`8u9tDWg=+wp8Z_!~S#Zt3<-oNVmmAmDaD4+f{kRt4 za^RYcD-V|e*JNCm<4VV+#+8KY6nOY&Tmr7QaJ`1>5U!_j?Zh<$W&R_6+N2@852GCN zd?#b#szKX+?hVf@eON#K{q^H1Hq-0ECS5v%XF9uAF}p6{bJNQVoWX!i%Q!(pS>ke5 zQ50h*Qs#SWL|}F&;|F-m!LC#!-JDYD@&_7cVw)~Ipt#=Urw}${`jP7?CDLNve<{Dy zp*}cx%g0JmO6y#%M)v0<mR8VVIgC9vqPm(0$C))F#WQ>us~hR_RXQ808M|*pbtRoO!q|=x)yrHc@2L^h z9(=VXzRh%YLT0XNxZ_v%+m6)%nm{~HfqGaC8 ziW_deVIGc0xhtsxM_*J_xt0c&EpvG*+#b(z#$HDK5M9=Qv#r42Dtl9<3ujZ|+?SWc zlzA>MHlc#Q*pXU^{jIEBQL&)1(GNl47%(;~sREmvmsQXS8jKx79#p*Ei5%W#K6Y_Z zMFohfz_D8ubV?2W-#^gh_0L+mti(mzl0jDkk0Hs?QB$HozBNL`w<}3Rya=?5F&>2Y zer>-S`c%aa#B#Aq#By+ojkn&3eeGUsot&LqK}W2C$odKwvk$$oH%O*Pay6`AuP0Sh z*W(B-&_S5%#qfcVD=U4KjjM>mzk@c^JD0l}ftcPSc=t8pST8B!$3!DBtwLm>*CgU; zU^$8cDxGt$u<)zX7c97yy(n@O)jgBt5=+^O$rY&Aa#oO15oq9{g`kbAOGVYvW$XxW zKvBhGOPEhtA%$+DI2; zs^kcyZzr4$l`gK6(Dl&-Ju~2?Q|=`CZ>VBpVq)iUr9>q33b3X8qY3gp(|uGbh1h8} z3*RUV)$q*ra5!d|1OL7pP%!$xd~vOfucLzZ4zYv%jQCMXhA%=fcQIDM)(mws)^Lqn6{|yb*9tqo(pMcGHCC`VP__i&8{@*I;9Wh?l?E#eHs&aU1R=|@kbNQl) zvB~x(WTo!QT-OR$owknd`IDT!8+g0uoum!aOs}MFO#Y;5XPwVANqb!sPu_LsE+vn? zw;Q4<@49H^kUj4@nQwTBN?|xK%z1XRp^z-$%>Ff2) z`bYJT>v!v)(Z8<$t^S1m1O3$ogCWO|ZzwXXFx+Lh+t6;tBdsS|B?k%}Zxp(A#D|d754{|$m-^x9itFVr=&a>WXt+Rf^`g7}( z*4M4atywmcZMJQRZIkVO+iu%4wpVR$*uu7yyeso2=gr8QlXr63%>}N4+JeS{=7Lbc z&k9ZyfJ0i0BJsFDXVewxYIT_0F(3~w6VHw+j~8!k4EH(qJXF%}wcG?s$TUgIj`TI1cudrg)jMS)08p z`}yoc*+;T_v){}9Fnh7N-t09unKzlgXa2tVm*x)h0dv1OE$5ry{KGlhbN1)Fkn^jY za86&&2RTzL*IO1?-nCqpyD|6C+#R`(=RTR+lY5c%GONy-ZM9kFT9;T|*5%e_>rU&_ z)`Qm5*5$T4Z7PRokLfqTd2EJw@$ZSm#V)4 zdisEVyZ#CNyZTf5RKtaaaR!qi*HB=%)3Dv}gy99lMaEf1hjEedA>#$638v+y`%I6R zcA8!{nXI>P4e?r6TJN=Pwf+P;(rx{NRcX7xw!-#xTeIyk+fQsy*pAqKZTqe5Bim`z zA~Ww+)M0nt(Y(IAk@>p(()`W&KST}Qopwz@cERF;%7U7L)`FiGJXi31!S4%t3I+?X zIL&CvEm>EstJkg7-L2cFJEZ%a?xaqkSLrVW{U*Ilf3vC4{%P15GmJE( z8=Qt}L!F@&R`zYf&kau*P8gU`Z7epHqc%;(HO3%p?T5yr#y;bq(G0s<4e75lwVG7s zspfg+Tg^+%)#f@b-8;h98Q*4?k$r5n^GfgfY^>6|B%_1Edm`h5K?{Z0B({X%`E-lK2Quh9qf z?fUQPAJhL*{}O!Cr3S6xYQwegNfyX^HoVe2!$QMSLyh5f!zx3wVT0iw!*>l^4L>q; z7@jwr0{2FMe-|3Z87CO8HcmB~j5gy8;|<{GSB*|%o$+?#N@KI}=f?fU_lyHZm1&GA z-E^tx8k63XXPRyjZG66Iv8l?m0zPb=>0Z-=rYB6DrURxIO-D_?F&&4+{lWAn(_c(i zXHUt_&t94R{p=^QpUFOu{bKfCvLoqwGjpqRTXQ$%{ut7{$a@Rqs z;LU>Wg0~B>P|1$K9;G zY+P^LY}{ph&Ug^|`iAi>;~$KFGM+Z7P2=FTrtns=BV zH}5e&Yu;}@WIkek-F)2qd$VAE7ryP3ndOYgQRiHkGcM=yoQXMK$zdD0i(yKAnkhYd zoOyv|k!6Xc%Hp;(g3nEs)t0rER?7yMru#Dd8M*B0o=KW(A&ei=KC zwqOrDUx#%+EatHFi1lQ?kl&l%2g?}9AIxVvF}Db~iMq+US-Lr}05`l?t8TjvksXYw R@laWC8~zP*;Ge{S{|}Y$$L0V4 diff --git a/Host/Source/SerialBoot/CMakeLists.txt b/Host/Source/SerialBoot/CMakeLists.txt deleted file mode 100644 index 7aea5017..00000000 --- a/Host/Source/SerialBoot/CMakeLists.txt +++ /dev/null @@ -1,82 +0,0 @@ -#**************************************************************************************** -# \file CMakeLists.txt -# \brief CMake descriptor file for SerialBoot command line demonstration program. -# \ingroup SerialBoot -# \internal -#---------------------------------------------------------------------------------------- -# C O P Y R I G H T -#---------------------------------------------------------------------------------------- -# Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -# -#---------------------------------------------------------------------------------------- -# L I C E N S E -#---------------------------------------------------------------------------------------- -# This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published by the Free -# Software Foundation, either version 3 of the License, or (at your option) any later -# version. -# -# OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -# PURPOSE. See the GNU General Public License for more details. -# -# You have received a copy of the GNU General Public License along with OpenBLT. It -# should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -# -# \endinternal -#**************************************************************************************** - -# Specify the version being used aswell as the language -cmake_minimum_required(VERSION 2.8) - -# Specify the project name -project(SerialBoot) - -# Set the port directory, which is platform specific -IF(WIN32) - set(PROJECT_PORT_DIR ${PROJECT_SOURCE_DIR}/port/windows) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPLATFORM_WIN32 -D_CRT_SECURE_NO_WARNINGS") -ELSEIF(UNIX) - set(PROJECT_PORT_DIR ${PROJECT_SOURCE_DIR}/port/linux) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPLATFORM_LINUX") -ENDIF(WIN32) - -# Build debug version by default -set(CMAKE_BUILD_TYPE "Debug") - -# Set include directories -include_directories("${PROJECT_SOURCE_DIR}" "${PROJECT_PORT_DIR}") - -# Set the output directory -set (PROJECT_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../../..) - -# Set the output directory for the generic no-config case (e.g. with mingw) -set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_OUTPUT_DIRECTORY} ) -set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_OUTPUT_DIRECTORY} ) -set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_OUTPUT_DIRECTORY} ) -# Set the output directory for multi-config builds (e.g. msvc) -foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} ) - string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG ) - set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${PROJECT_OUTPUT_DIRECTORY} ) - set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${PROJECT_OUTPUT_DIRECTORY} ) - set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${PROJECT_OUTPUT_DIRECTORY} ) -endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES ) - -# Get header files -file(GLOB_RECURSE INCS "*.h") - -# Add sources -add_executable( - SerialBoot - firmware.c - main.c - srecparser.c - xcploader.c - xcptpuart.c - ${PROJECT_PORT_DIR}/serialport.c - ${PROJECT_PORT_DIR}/timeutil.c - ${INCS} -) - - -#*********************************** end of CMakeLists.txt ****************************** \ No newline at end of file diff --git a/Host/Source/SerialBoot/firmware.c b/Host/Source/SerialBoot/firmware.c deleted file mode 100644 index 1d4e095c..00000000 --- a/Host/Source/SerialBoot/firmware.c +++ /dev/null @@ -1,125 +0,0 @@ -/************************************************************************************//** -* \file firmware.c -* \brief Firmware module source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -* -*---------------------------------------------------------------------------------------- -* L I C E N S E -*---------------------------------------------------------------------------------------- -* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published by the Free -* Software Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You have received a copy of the GNU General Public License along with OpenBLT. It -* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -* -* \endinternal -****************************************************************************************/ - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for NULL declaration */ -#include /* for assertions */ -#include "firmware.h" /* firmware module */ - - -/**************************************************************************************** -* Local data declarations -****************************************************************************************/ -/** \brief Pointer to the firmware parser that is linked. */ -static tFirmwareParser const * parserPtr = NULL; - - -/************************************************************************************//** -** \brief Initializes the firmware module. -** \param parser Pointer to the firmware parser to link. -** \return None. -** -****************************************************************************************/ -void FirmwareInit(tFirmwareParser const * const parser) -{ - /* verify parameters */ - assert(parser != NULL); - - /* link the firmware parser */ - parserPtr = parser; - /* initialize the firmware parser */ - parserPtr->Init(); -} /*** end of FirmwareInit ***/ - - -/************************************************************************************//** -** \brief Uninitializes the firmware module. -** \return None. -** -****************************************************************************************/ -void FirmwareDeinit(void) -{ - /* make sure the parser is linked */ - assert(parserPtr != NULL); - - /* uninitialize the parser */ - parserPtr->Deinit(); - /* unlink the parser */ - parserPtr = NULL; -} /*** end of FirmwareDeinit ***/ - - -/************************************************************************************//** -** \brief Loads the firmware data from the specified firmware file, using the linked -** parser. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -bool FirmwareLoadFromFile(char *firmwareFile) -{ - /* make sure the parser is linked */ - assert(parserPtr != NULL); - /* make sure the filename is valid */ - assert(firmwareFile != NULL); - - return parserPtr->LoadFromFile(firmwareFile); -} /*** end of FirmwareLoadFromFile ***/ - - -/************************************************************************************//** -** \brief Returns the number of firmware segments that were loaded by the parser. -** \return Number of firmware segments. -** -****************************************************************************************/ -uint32_t FirmwareGetSegmentCount(void) -{ - /* make sure the parser is linked */ - assert(parserPtr != NULL); - - return parserPtr->GetSegmentCount(); -} /*** end of FirmwareGetSegmentCount ***/ - - -/************************************************************************************//** -** \brief Obtains a pointer to the firmware segment at the specified index. -** \return Pointer to firmware segment if successful, NULL otherwise. -** -****************************************************************************************/ -const tFirmwareSegment *FirmwareGetSegment(uint32_t segmentIdx) -{ - /* make sure the parser is linked */ - assert(parserPtr != NULL); - - return parserPtr->GetSegment(segmentIdx); -} /*** end of FirmwareGetSegment ***/ - - -/*********************************** end of firmware.c *********************************/ - diff --git a/Host/Source/SerialBoot/firmware.h b/Host/Source/SerialBoot/firmware.h deleted file mode 100644 index a6ff7652..00000000 --- a/Host/Source/SerialBoot/firmware.h +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************************//** -* \file firmware.h -* \brief Firmware module header file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -* -*---------------------------------------------------------------------------------------- -* L I C E N S E -*---------------------------------------------------------------------------------------- -* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published by the Free -* Software Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You have received a copy of the GNU General Public License along with OpenBLT. It -* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -* -* \endinternal -****************************************************************************************/ -#ifndef FIRMWARE_H -#define FIRMWARE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for standard integer types */ -#include /* for boolean type */ - - -/**************************************************************************************** -* Type definitions -****************************************************************************************/ -/** \brief Groups information together of a firmware segments. */ -typedef struct t_firmware_segment -{ - uint32_t base; /**< Start memory address of the segment. */ - uint32_t length; /**< Number of data bytes in the segment. */ - uint8_t *data; /**< Pointer to array with the segment's data bytes. */ -} tFirmwareSegment; - -/** \brief Firmware file parser. */ -typedef struct t_firmware_parser -{ - /** \brief Initialization of the file parser. */ - void (*Init) (void); - /** \brief Uninitializes the file parser. */ - void (*Deinit) (void); - /** \brief Extract the firmware segments from the firmware file. */ - bool (*LoadFromFile) (char *firmwareFile); - /** \brief Obtains the number of segments. */ - uint32_t (*GetSegmentCount) (void); - /** \brief Obtains a segment. */ - const tFirmwareSegment * (*GetSegment) (uint32_t segmentIdx); -} tFirmwareParser; - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -void FirmwareInit(tFirmwareParser const * const parser); -void FirmwareDeinit(void); -bool FirmwareLoadFromFile(char *firmwareFile); -uint32_t FirmwareGetSegmentCount(void); -const tFirmwareSegment *FirmwareGetSegment(uint32_t segmentIdx); - -#ifdef __cplusplus -} -#endif - -#endif /* FIRMWARE_H */ -/********************************* end of firmware.h ***********************************/ - diff --git a/Host/Source/SerialBoot/main.c b/Host/Source/SerialBoot/main.c deleted file mode 100644 index fa1d9b89..00000000 --- a/Host/Source/SerialBoot/main.c +++ /dev/null @@ -1,365 +0,0 @@ -/************************************************************************************//** -* \file main.c -* \brief SerialBoot program source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -* -*---------------------------------------------------------------------------------------- -* L I C E N S E -*---------------------------------------------------------------------------------------- -* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published by the Free -* Software Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You have received a copy of the GNU General Public License along with OpenBLT. It -* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -* -* \endinternal -****************************************************************************************/ - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* standard I/O functions */ -#include /* for string library */ -#include "xcploader.h" /* XCP loader module */ -#include "xcptpuart.h" /* XCP transport layer for UART */ -#include "firmware.h" /* Firmware module */ -#include "srecparser.h" /* S-record parser */ -#include "timeutil.h" /* for time utilities module */ - - -/**************************************************************************************** -* Macro definitions -****************************************************************************************/ -/* Program return codes. */ -#define RESULT_OK (0) -#define RESULT_COMMANDLINE_ERROR (1) -#define RESULT_FIRMWARE_LOAD_ERROR (2) -#define RESULT_PROGRAM_START_ERROR (3) -#define RESULT_MEMORY_ERASE_ERROR (4) -#define RESULT_PROGRAM_STOP_ERROR (5) -#define RESULT_MEMORY_PROGRAM_ERROR (6) - - -/**************************************************************************************** -* Local data declarations -****************************************************************************************/ -/** \brief The firmware filename that is specified at the command line. */ -static char *firmwareFilename; - -/** \brief XCP loader settings. */ -static tXcpSettings xcpSettings = -{ - .timeoutT1 = 1000, - .timeoutT3 = 2000, - .timeoutT4 = 10000, - .timeoutT5 = 1000, - .timeoutT7 = 2000 -}; - -/** \brief XCP UART transport layer settings. */ -static tXcpTpUartSettings xcpTpUartSettings = -{ - .baudrate = SERIALPORT_BR57600, - .portname = "/dev/ttyS0" -}; - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -static void DisplayProgramInfo(void); -static void DisplayProgramUsage(void); -static bool ParseCommandLine(int argc, char *argv[]); - - -/************************************************************************************//** -** \brief This is the program entry point. -** \param argc Number of program arguments. -** \param argv Array with program arguments. -** \return Program return code. 0 for success, error code otherwise. -** -****************************************************************************************/ -int main(int argc, char *argv[]) -{ - int result = RESULT_OK; - uint32_t fwBaseAddress; - uint32_t fwTotalSize; - uint32_t segmentIdx; - const tFirmwareSegment *segment; - - /* -------------------- Display info ----------------------------------------------- */ - /* inform user about the program */ - DisplayProgramInfo(); - - /* -------------------- Process command line --------------------------------------- */ - /* start out by making sure program was started with the correct parameters */ - if (!ParseCommandLine(argc, argv)) - { - /* parameters invalid. inform user about how this program works */ - DisplayProgramUsage(); - return RESULT_COMMANDLINE_ERROR; - } - - /* -------------------- Initialization --------------------------------------------- */ - /* initialize the XCP loader module using the UART transport layer. */ - XcpLoaderInit(&xcpSettings, XcpTpUartGetTransport(), &xcpTpUartSettings); - /* initialize the firmware module and link the S-recorder parser */ - FirmwareInit(SRecParserGetParser()); - - /* -------------------- Parse the firmware file ------------------------------------ */ - /* attempt to load the firmware file */ - printf("Loading firmware file..."); fflush(stdout); - if (!FirmwareLoadFromFile(firmwareFilename)) - { - /* set error code and abort */ - printf("ERROR\n"); - result = RESULT_FIRMWARE_LOAD_ERROR; - goto finish; - } - printf("OK\n"); - /* determine firmware base address and total size */ - for (segmentIdx=0; segmentIdxbase; - fwTotalSize = segment->length; - } - else - { - /* update */ - if (segment->base < fwBaseAddress) - { - fwBaseAddress = segment->base; - } - fwTotalSize += segment->length; - } - } - /* display some firmware statistics */ - printf("-> Number of segments: %u\n", FirmwareGetSegmentCount()); - printf("-> Base memory address: 0x%08x\n", fwBaseAddress); - printf("-> Total data bytes: %u\n", fwTotalSize); - - /* -------------------- Connect to target ------------------------------------------ */ - printf("Connecting to bootloader..."); fflush(stdout); - if (!XcpLoaderConnect()) - { - /* no response. prompt the user to reset the system */ - printf("TIMEOUT\nReset your microcontroller..."); fflush(stdout); - /* now keep retrying until we get a response */ - while (!XcpLoaderConnect()) - { - /* delay a bit to not pump up the CPU load */ - TimeUtilDelayMs(20); - } - } - printf("OK\n"); - - /* -------------------- Start the programming session ------------------------------ */ - /* attempt to start the programming session */ - printf("Starting programming session..."); fflush(stdout); - if (!XcpLoaderStartProgrammingSession()) - { - /* set error code and abort */ - printf("ERROR\n"); - result = RESULT_PROGRAM_START_ERROR; - goto finish; - } - printf("OK\n"); - - /* -------------------- Erase memory ----------------------------------------------- */ - /* erase each segment one at a time */ - for (segmentIdx=0; segmentIdxlength, segment->base); fflush(stdout); - if (!XcpLoaderClearMemory(segment->base, segment->length)) - { - /* set error code and abort */ - printf("ERROR\n"); - result = RESULT_MEMORY_ERASE_ERROR; - goto finish; - } - printf("OK\n"); - } - - /* -------------------- Program data ----------------------------------------------- */ - /* program each segment one at a time */ - for (segmentIdx=0; segmentIdxlength, segment->base); fflush(stdout); - if (!XcpLoaderProgramData(segment->base, segment->length, segment->data)) - { - /* set error code and abort */ - printf("ERROR\n"); - result = RESULT_MEMORY_PROGRAM_ERROR; - goto finish; - } - printf("OK\n"); - } - - /* -------------------- Stop the programming session ------------------------------- */ - /* attempt to stop the programming session */ - printf("Finishing programming session..."); fflush(stdout); - if (!XcpLoaderStopProgrammingSession()) - { - /* set error code and abort */ - printf("ERROR\n"); - result = RESULT_PROGRAM_STOP_ERROR; - goto finish; - } - printf("OK\n"); - - /* -------------------- Cleanup ---------------------------------------------------- */ -finish: - /* uninitialize the firmware module */ - FirmwareDeinit(); - /* uninitialize the XCP loader module. note that this automatically disconnects the - * slave, if connected, by requesting it to perform a reset. - */ - XcpLoaderDeinit(); - /* give result back */ - return result; -} /*** end of main ***/ - - -/************************************************************************************//** -** \brief Outputs information to the user about this program. -** \return none. -** -****************************************************************************************/ -static void DisplayProgramInfo(void) -{ - printf("-------------------------------------------------------------------------\n"); - printf("SerialBoot version 2.00. Performs firmware updates via the serial port\n"); - printf("for a microcontroller based system that runs the OpenBLT bootloader.\n\n"); - printf("Copyright (c) by Feaser http://www.feaser.com\n"); - printf("-------------------------------------------------------------------------\n"); -} /*** end of DisplayProgramInfo ***/ - - -/************************************************************************************//** -** \brief Outputs information to the user about how to use this program. -** \return none. -** -****************************************************************************************/ -static void DisplayProgramUsage(void) -{ - printf("Usage: SerialBoot -d[device] -b[baudrate] [s-record file]\n\n"); -#ifdef PLATFORM_WIN32 - printf("Example: SerialBoot -dCOM4 -b57600 myfirmware.s19\n"); - printf(" -> Connects to COM4, configures a communication speed of 57600\n"); -#else - printf("Example: SerialBoot -d/dev/ttyS0 -b57600 myfirmware.s19\n"); - printf(" -> Connects to ttyS0, configures a communication speed of 57600\n"); -#endif - printf(" bits/second and programs the myfirmware.s19 file in non-\n"); - printf(" volatile memory of the microcontroller using OpenBLT.\n"); - printf(" Supported baudrates are: 9600, 19200, 38400, 57600 and\n"); - printf(" 115200 bits/second.\n"); - printf("-------------------------------------------------------------------------\n"); -} /*** end of DisplayProgramUsage ***/ - - -/************************************************************************************//** -** \brief Parses the command line arguments. A fixed amount of arguments is expected. -** The program should be called as: -** SerialBoot -d[device] -b[baudrate] [s-record file] -** \param argc Number of program parameters. -** \param argv array to program parameter strings. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static bool ParseCommandLine(int argc, char *argv[]) -{ - uint8_t paramIdx; - bool firmwareFileFound = false; - uint32_t baudrateValue; - - /* make sure that enough arguments were specified. this program needs at least 2. the - * first one is always the program name and the second one is the s-record file. - */ - if (argc < 2) - { - return false; - } - - /* loop through all the command line parameters, just skip the 1st one because this - * is the name of the program, which we are not interested in. - */ - for (paramIdx=1; paramIdx /* for NULL declaration */ -#include /* for assertions */ -#include /* UNIX standard functions */ -#include /* POSIX terminal control */ -#include /* file control definitions */ -#include /* system I/O control */ -#include "serialport.h" /* serial port module */ - - -/**************************************************************************************** -* Macro definitions -****************************************************************************************/ -/** \brief Invalid serial port device handle. */ -#define SERIALPORT_INVALID_HANDLE (-1) - - -/**************************************************************************************** -* Local data declarations -****************************************************************************************/ -static int32_t portHandle = SERIALPORT_INVALID_HANDLE; - - -/**************************************************************************************** -* Local constant declarations -****************************************************************************************/ -/** \brief Lookup table for converting this module's generic baudrate value to a value - * supported by the low level interface. - */ -static const speed_t baudrateLookup[] = -{ - B9600, /**< Index 0 = SERIALPORT_BR9600 */ - B19200, /**< Index 1 = SERIALPORT_BR19200 */ - B38400, /**< Index 2 = SERIALPORT_BR38400 */ - B57600, /**< Index 3 = SERIALPORT_BR57600 */ - B115200 /**< Index 4 = SERIALPORT_BR115200 */ -}; - - -/************************************************************************************//** -** \brief Opens the connection with the serial port configured as 8,N,1 and no flow -** control. -** \param portname The name of the serial port to open, i.e. /dev/ttyUSB0. -** \param baudrate The desired communication speed. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -bool SerialPortOpen(char *portname, tSerialPortBaudrate baudrate) -{ - struct termios options; - int32_t iFlags; - - /* check parameters */ - assert(portname != NULL); - - /* open the port */ - portHandle = open(portname, O_RDWR | O_NOCTTY | O_NDELAY); - /* check the result */ - if (portHandle == SERIALPORT_INVALID_HANDLE) - { - return false; - } - /* configure the device to block during read operations */ - if (fcntl(portHandle, F_SETFL, 0) == -1) - { - SerialPortClose(); - return false; - } - /* get the current options for the port */ - if (tcgetattr(portHandle, &options) == -1) - { - SerialPortClose(); - return false; - } - /* configure the baudrate */ - if (cfsetispeed(&options, baudrateLookup[baudrate]) == -1) - { - SerialPortClose(); - return false; - } - if (cfsetospeed(&options, baudrateLookup[baudrate]) == -1) - { - SerialPortClose(); - return false; - } - - /* input modes - clear indicated ones giving: no break, no CR to NL, - * no parity check, no strip char, no start/stop output (sic) control - */ - options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); - /* output modes - clear giving: no post processing such as NL to CR+NL */ - options.c_oflag &= ~(OPOST); - /* control modes - set 8 bit chars */ - options.c_cflag |= (CS8); - /* local modes - clear giving: echoing off, canonical off (no erase with - * backspace, ^U,...), no extended functions, no signal chars (^Z,^C) - */ - options.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); - /* configure timeouts */ - options.c_cc[VMIN] = 0; - options.c_cc[VTIME] = 1; /* in units of 1/10th of a second */ - /* set the new options for the port */ - if (tcsetattr(portHandle, TCSAFLUSH, &options) == -1) - { - SerialPortClose(); - return false; - } - /* turn on DTR */ - iFlags = TIOCM_DTR; - ioctl(portHandle, TIOCMBIS, &iFlags); - /* success */ - return true; -} /*** end of SerialPortOpen ***/ - - -/************************************************************************************//** -** \brief Closes the connection with the serial port. -** \return None. -** -****************************************************************************************/ -void SerialPortClose(void) -{ - /* close the port handle if valid */ - if (portHandle != SERIALPORT_INVALID_HANDLE) - { - close(portHandle); - } - /* invalidate handle */ - portHandle = SERIALPORT_INVALID_HANDLE; -} /*** end of SerialPortClose ***/ - - -/************************************************************************************//** -** \brief Writes data to the serial port. -** \param data Pointer to byte array with data to write. -** \param length Number of bytes to write. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -bool SerialPortWrite(uint8_t *data, uint32_t length) -{ - size_t bytesWritten; - - /* check parameters */ - assert(data != NULL); - assert(length > 0); - - /* submit the data for sending */ - bytesWritten = write(portHandle, data, length); - /* check and return the result */ - return (bytesWritten == length); -} /*** end of SerialPortWrite ***/ - - -/************************************************************************************//** -** \brief Reads data from the serial port in a blocking manner. -** \param data Pointer to byte array to store read data. -** \param length Number of bytes to read. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -bool SerialPortRead(uint8_t *data, uint32_t length) -{ - size_t bytesRead; - - /* check parameters */ - assert(data != NULL); - assert(length > 0); - - /* attempt to read the requested data */ - bytesRead = read(portHandle, data, length); - /* check and return the result */ - return (bytesRead == length); -} /*** end of SerialPortRead ***/ - - -/*********************************** end of serialport.c *******************************/ - diff --git a/Host/Source/SerialBoot/port/linux/timeutil.c b/Host/Source/SerialBoot/port/linux/timeutil.c deleted file mode 100644 index 7b0d2baa..00000000 --- a/Host/Source/SerialBoot/port/linux/timeutil.c +++ /dev/null @@ -1,69 +0,0 @@ -/************************************************************************************//** -* \file port\linux\timeutil.c -* \brief Time utility source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -* -*---------------------------------------------------------------------------------------- -* L I C E N S E -*---------------------------------------------------------------------------------------- -* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published by the Free -* Software Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You have received a copy of the GNU General Public License along with OpenBLT. It -* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -* -* \endinternal -****************************************************************************************/ - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for NULL declaration */ -#include /* UNIX standard functions */ -#include /* time definitions */ -#include "timeutil.h" /* for time utilities module */ - - -/************************************************************************************//** -** \brief Get the system time in milliseconds. -** \return Time in milliseconds. -** -****************************************************************************************/ -uint32_t TimeUtilGetSystemTimeMs(void) -{ - struct timeval tv; - - if (gettimeofday(&tv, NULL) != 0) - { - return 0; - } - - return (uint32_t)((tv.tv_sec * 1000ul) + (tv.tv_usec / 1000ul)); -} /*** end of XcpTransportClose ***/ - - -/************************************************************************************//** -** \brief Performs a delay of the specified amount of milliseconds. -** \param delay Delay time in milliseconds. -** \return none. -** -****************************************************************************************/ -void TimeUtilDelayMs(uint16_t delay) -{ - usleep(1000 * delay); -} /*** end of TimeUtilDelayMs **/ - - -/*********************************** end of timeutil.c *********************************/ - diff --git a/Host/Source/SerialBoot/port/windows/serialport.c b/Host/Source/SerialBoot/port/windows/serialport.c deleted file mode 100644 index bc2f1f9c..00000000 --- a/Host/Source/SerialBoot/port/windows/serialport.c +++ /dev/null @@ -1,260 +0,0 @@ -/************************************************************************************//** -* \file port\windows\serialport.c -* \brief Serial port source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -* -*---------------------------------------------------------------------------------------- -* L I C E N S E -*---------------------------------------------------------------------------------------- -* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published by the Free -* Software Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You have received a copy of the GNU General Public License along with OpenBLT. It -* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -* -* \endinternal -****************************************************************************************/ - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for NULL declaration */ -#include /* for windows library */ -#include /* for assertions */ -#include "serialport.h" /* serial port module */ - - -/**************************************************************************************** -* Macro definitions -****************************************************************************************/ -#define UART_TX_BUFFER_SIZE (1024) /**< transmission buffer size */ -#define UART_RX_BUFFER_SIZE (1024) /**< reception buffer size */ - - -/**************************************************************************************** -* Local data declarations -****************************************************************************************/ -static HANDLE hUart = INVALID_HANDLE_VALUE; - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -static uint32_t SerialConvertBaudrate(tSerialPortBaudrate baudrate); - - -/************************************************************************************//** -** \brief Opens the connection with the serial port configured as 8,N,1 and no flow -** control. -** \param portname The name of the serial port to open, i.e. COM4. -** \param baudrate The desired communication speed. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -bool SerialPortOpen(char *portname, tSerialPortBaudrate baudrate) -{ - COMMTIMEOUTS timeouts = { 0 }; - DCB dcbSerialParams = { 0 }; - char portStr[64] = "\\\\.\\\0"; - - /* check parameters */ - assert(portname != NULL); - - /* construct the COM port name as a string */ - strcat_s(portStr, 59, portname); - - /* obtain access to the COM port */ - hUart = CreateFile(portStr, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, 0); - - /* validate COM port handle */ - if (hUart == INVALID_HANDLE_VALUE) - { - return false; - } - - /* get current COM port configuration */ - dcbSerialParams.DCBlength = sizeof(dcbSerialParams); - if (!GetCommState(hUart, &dcbSerialParams)) - { - CloseHandle(hUart); - return false; - } - - /* configure the baudrate and 8,n,1 */ - dcbSerialParams.BaudRate = SerialConvertBaudrate(baudrate); - dcbSerialParams.ByteSize = 8; - dcbSerialParams.StopBits = ONESTOPBIT; - dcbSerialParams.Parity = NOPARITY; - dcbSerialParams.fOutX = FALSE; - dcbSerialParams.fInX = FALSE; - dcbSerialParams.fRtsControl = RTS_CONTROL_DISABLE; - dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE; - - if (!SetCommState(hUart, &dcbSerialParams)) - { - CloseHandle(hUart); - return false; - } - - /* set communication timeout parameters */ - timeouts.ReadIntervalTimeout = 0; - timeouts.ReadTotalTimeoutConstant = 0; - timeouts.ReadTotalTimeoutMultiplier = 100; - timeouts.WriteTotalTimeoutConstant = 0; - timeouts.WriteTotalTimeoutMultiplier = 100; - - if (!SetCommTimeouts(hUart, &timeouts)) - { - CloseHandle(hUart); - return false; - } - - /* set transmit and receive buffer sizes */ - if (!SetupComm(hUart, UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE)) - { - CloseHandle(hUart); - return false; - } - - /* empty the transmit and receive buffers */ - if (!FlushFileBuffers(hUart)) - { - CloseHandle(hUart); - return false; - } - /* successfully connected to the serial device */ - return true; -} /*** end of SerialPortOpen ***/ - - -/************************************************************************************//** -** \brief Closes the connection with the serial port. -** \return None. -** -****************************************************************************************/ -void SerialPortClose(void) -{ - /* close the COM port handle if valid */ - if (hUart != INVALID_HANDLE_VALUE) - { - CloseHandle(hUart); - } - - /* set handles to invalid */ - hUart = INVALID_HANDLE_VALUE; -} /*** end of SerialPortClose ***/ - - -/************************************************************************************//** -** \brief Writes data to the serial port. -** \param data Pointer to byte array with data to write. -** \param length Number of bytes to write. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -bool SerialPortWrite(uint8_t *data, uint32_t length) -{ - uint32_t dwWritten = 0; - - /* check parameters */ - assert(data != NULL); - assert(length > 0); - - /* submit the data for transmission with the serial port */ - if (!WriteFile(hUart, data, length, &dwWritten, NULL)) - { - return false; - } - /* double check that all bytes were actually transmitted */ - if (dwWritten != length) - { - return false; - } - - /* success */ - return true; -} /*** end of SerialPortWrite ***/ - - -/************************************************************************************//** -** \brief Reads data from the serial port in a blocking manner. -** \param data Pointer to byte array to store read data. -** \param length Number of bytes to read. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -bool SerialPortRead(uint8_t *data, uint32_t length) -{ - uint32_t dwRead = 0; - - /* check parameters */ - assert(data != NULL); - assert(length > 0); - - /* attempt to read data from the serial port */ - if (!ReadFile(hUart, data, length, &dwRead, NULL)) - { - return false; - } - /* double check that all bytes were actually read */ - if (dwRead != length) - { - return false; - } - - /* success */ - return true; -} /*** end of SerialPortRead ***/ - - -/************************************************************************************//** -** \brief Opens the connection with the serial port configured as 8,N,1 and no flow -** control. -** \param portname The name of the serial port to open, i.e. COM4. -** \param baudrate The desired communication speed. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static uint32_t SerialConvertBaudrate(tSerialPortBaudrate baudrate) -{ - uint32_t result; - - switch (baudrate) - { - case SERIALPORT_BR9600: - result = CBR_9600; - break; - case SERIALPORT_BR19200: - result = CBR_19200; - break; - case SERIALPORT_BR38400: - result = CBR_38400; - break; - case SERIALPORT_BR57600: - result = CBR_57600; - break; - case SERIALPORT_BR115200: - result = CBR_115200; - break; - default: - result = CBR_9600; - break; - } - return result; -} /*** end of SerialConvertBaudrate ***/ - - -/*********************************** end of serialport.c *******************************/ - diff --git a/Host/Source/SerialBoot/port/windows/timeutil.c b/Host/Source/SerialBoot/port/windows/timeutil.c deleted file mode 100644 index 714b761c..00000000 --- a/Host/Source/SerialBoot/port/windows/timeutil.c +++ /dev/null @@ -1,60 +0,0 @@ -/************************************************************************************//** -* \file port\windows\timeutil.c -* \brief Time utility source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -* -*---------------------------------------------------------------------------------------- -* L I C E N S E -*---------------------------------------------------------------------------------------- -* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published by the Free -* Software Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You have received a copy of the GNU General Public License along with OpenBLT. It -* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -* -* \endinternal -****************************************************************************************/ - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for windows library */ -#include "timeutil.h" /* for time utilities module */ - - -/************************************************************************************//** -** \brief Get the system time in milliseconds. -** \return Time in milliseconds. -** -****************************************************************************************/ -uint32_t TimeUtilGetSystemTimeMs(void) -{ - return GetTickCount(); -} /*** end of XcpTransportClose ***/ - - -/************************************************************************************//** -** \brief Performs a delay of the specified amount of milliseconds. -** \param delay Delay time in milliseconds. -** \return none. -** -****************************************************************************************/ -void TimeUtilDelayMs(uint16_t delay) -{ - Sleep(delay); -} /*** end of TimeUtilDelayMs **/ - - -/*********************************** end of timeutil.c *********************************/ - diff --git a/Host/Source/SerialBoot/serialport.h b/Host/Source/SerialBoot/serialport.h deleted file mode 100644 index e82ab8dd..00000000 --- a/Host/Source/SerialBoot/serialport.h +++ /dev/null @@ -1,70 +0,0 @@ -/************************************************************************************//** -* \file serialport.h -* \brief Serial port header file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -* -*---------------------------------------------------------------------------------------- -* L I C E N S E -*---------------------------------------------------------------------------------------- -* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published by the Free -* Software Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You have received a copy of the GNU General Public License along with OpenBLT. It -* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -* -* \endinternal -****************************************************************************************/ -#ifndef SERIALPORT_H -#define SERIALPORT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for standard integer types */ -#include /* for boolean type */ - - -/**************************************************************************************** -* Typde definitions -****************************************************************************************/ -/** \brief Enumaration of the supported baudrates. */ -typedef enum -{ - SERIALPORT_BR9600 = 0, /**< 9600 bits/sec */ - SERIALPORT_BR19200 = 1, /**< 19200 bits/sec */ - SERIALPORT_BR38400 = 2, /**< 38400 bits/sec */ - SERIALPORT_BR57600 = 3, /**< 57600 bits/sec */ - SERIALPORT_BR115200 = 4 /**< 115200 bits/sec */ -} tSerialPortBaudrate; - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -bool SerialPortOpen(char *portname, tSerialPortBaudrate baudrate); -void SerialPortClose(void); -bool SerialPortWrite(uint8_t *data, uint32_t length); -bool SerialPortRead(uint8_t *data, uint32_t length); - -#ifdef __cplusplus -} -#endif - -#endif /* SERIALPORT_H */ -/********************************* end of serialport.h *********************************/ - diff --git a/Host/Source/SerialBoot/srecparser.c b/Host/Source/SerialBoot/srecparser.c deleted file mode 100644 index d0e089cb..00000000 --- a/Host/Source/SerialBoot/srecparser.c +++ /dev/null @@ -1,751 +0,0 @@ -/************************************************************************************//** -* \file srecparser.c -* \brief S-record parser source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -* -*---------------------------------------------------------------------------------------- -* L I C E N S E -*---------------------------------------------------------------------------------------- -* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published by the Free -* Software Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You have received a copy of the GNU General Public License along with OpenBLT. It -* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -* -* \endinternal -****************************************************************************************/ - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for NULL declaration */ -#include /* for standard I/O library */ -#include /* for standard library */ -#include /* for string library */ -#include /* for character testing */ -#include /* for assertions */ -#include "srecparser.h" /* S-record parser */ - - -/**************************************************************************************** -* Macro definitions -****************************************************************************************/ -/** \brief Maximum number of characters that can be on a line in the firmware file. */ -#define SRECORD_MAX_CHARS_PER_LINE (512) - -/** \brief Maximum number of data bytes that can be on a line in the firmware file - * (S-record). - */ -#define SRECORD_MAX_DATA_BYTES_PER_LINE (SRECORD_MAX_CHARS_PER_LINE/2) - - -/**************************************************************************************** -* Type definitions -****************************************************************************************/ -/** \brief Layout of a firmware segment node in the linked list. */ -typedef struct t_segment_node -{ - /** \brief The firmware segment stored in this node. */ - tFirmwareSegment segment; - /** \brief Pointer to the next node, or NULL if it is the last one. */ - struct t_segment_node *next; -} tSegmentNode; - -/** \brief Enumeration for the different S-record line types. */ -typedef enum -{ - LINE_TYPE_S1, /**< 16-bit address line */ - LINE_TYPE_S2, /**< 24-bit address line */ - LINE_TYPE_S3, /**< 32-bit address line */ - LINE_TYPE_UNSUPPORTED /**< unsupported line */ -} tSrecordLineType; - -/** \brief Structure type for grouping the parsing results of an S-record line. */ -typedef struct -{ - uint8_t data[SRECORD_MAX_DATA_BYTES_PER_LINE]; /**< array for S1,S2 or S3 data bytes */ - uint32_t address; /**< address on S1,S2 or S3 line */ - uint16_t length; /**< number of bytes written to array */ -} tSrecordLineParseResults; - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -static void SRecParserInit(void); -static void SRecParserDeinit(void); -static bool SRecParserLoadFromFile(char *firmwareFile); -static uint32_t SRecParserGetSegmentCount(void); -static const tFirmwareSegment *SRecParserGetSegment(uint32_t segmentIdx); -static void SRecParserSegmentListInit(void); -static void SRecParserSegmentListDeinit(void); -static tSegmentNode *SRecParserSegmentListCreateNode(void); -static uint32_t SRecParserSegmentListGetNodeCount(void); -static tSegmentNode *SRecParserSegmentListGetNode(uint32_t nodeIdx); -/* S-record utility functions */ -static bool SrecordParseNextDataLine(FILE* srecordHandle, tSrecordLineParseResults *parseResults); -static tSrecordLineType SrecordGetLineType(const char *line); -static bool SrecordVerifyChecksum(const char *line); -static uint8_t SrecordHexStringToByte(const char *hexstring); -static bool SrecordReadLine(FILE *srecordHandle, char *line); - - - -/**************************************************************************************** -* Local constant declarations -****************************************************************************************/ -/** \brief XCP transport structure filled with CAN specifics. */ -static const tFirmwareParser srecParser = -{ - SRecParserInit, - SRecParserDeinit, - SRecParserLoadFromFile, - SRecParserGetSegmentCount, - SRecParserGetSegment -}; - - -/**************************************************************************************** -* Local data declarations -****************************************************************************************/ -/** \brief Linked list with firmware segments. */ -static tSegmentNode *segmentList; - - -/***********************************************************************************//** -** \brief Obtains a pointer to the parser structure, so that it can be linked to the -** firmware loader module. -** \return Pointer to firmware parser structure. -** -****************************************************************************************/ -tFirmwareParser const * const SRecParserGetParser(void) -{ - return &srecParser; -} /*** end of SRecParserGetParser ***/ - - -/************************************************************************************//** -** \brief Initializes the parser. -** \return None. -** -****************************************************************************************/ -static void SRecParserInit(void) -{ - /* initialize the segment list */ - SRecParserSegmentListInit(); -} /*** end of SRecParserInit ***/ - - -/************************************************************************************//** -** \brief Uninitializes the parser. -** \return None. -** -****************************************************************************************/ -static void SRecParserDeinit(void) -{ - /* uninitialize the segment list */ - SRecParserSegmentListDeinit(); -} /*** end of SRecParserDeinit ***/ - - -/************************************************************************************//** -** \brief Parses the data in the specified firmware file into firmware segments that -** are stored internally in this module. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -static bool SRecParserLoadFromFile(char *firmwareFile) -{ - FILE *fp; - char line[SRECORD_MAX_CHARS_PER_LINE]; - tSrecordLineParseResults lineResults; - tSegmentNode *node; - uint32_t nodeIdx; - bool matchFound; - uint32_t byteIdx; - uint32_t byteOffset; - - /* verify parameters */ - assert(firmwareFile != NULL); - - /* open the file for reading */ - fp = fopen(firmwareFile, "r"); - if (fp == NULL) - { - /* could not open the file */ - return false; - } - /* start at the beginning of the file */ - rewind(fp); - - /* -------------------------- file type validation --------------------------------- */ - /* validate S-record file. all lines should be formatted as S-records. read the first - * one to check this. - */ - if (!SrecordReadLine(fp, line)) - { - /* could not read a line. file must be empty */ - fclose(fp); - return false; - } - /* check if the line starts with the 'S' character, followed by a digit */ - if ( (toupper(line[0]) != 'S') || (isdigit(line[1]) == 0) ) - { - fclose(fp); - return false; - } - - /* -------------------------- extract segment info --------------------------------- */ - /* start at the beginning of the file */ - rewind(fp); - - /* loop through all S-records with program data to obtain segment info */ - while (SrecordParseNextDataLine(fp, &lineResults)) - { - /* reset flag that indicates that the line data was matched to an existing segment */ - matchFound = false; - /* loop through all segment nodes */ - for (nodeIdx=0; nodeIdx < SRecParserSegmentListGetNodeCount(); nodeIdx++) - { - /* get node access */ - node = SRecParserSegmentListGetNode(nodeIdx); - - /* does the line data fit at the start of this node's segment? */ - if ((lineResults.address + lineResults.length) == node->segment.base) - { - /* update the node's segment */ - node->segment.base -= lineResults.length; - node->segment.length += lineResults.length; - /* match found so continue with the next line */ - matchFound = true; - break; - } - /* does the line data fit at the end of this node's segment? */ - else if (lineResults.address == (node->segment.base + node->segment.length)) - { - /* update the node's segment */ - node->segment.length += lineResults.length; - /* match found so continue with the next line */ - matchFound = true; - break; - } - } - /* check if the line data was matched and added to an existing segment */ - if (!matchFound) - { - /* create a new segment */ - node = SRecParserSegmentListCreateNode(); - node->segment.base = lineResults.address; - node->segment.length = lineResults.length; - } - } - - /* -------------------------- allocate data memory --------------------------------- */ - /* loop through all segment nodes */ - for (nodeIdx=0; nodeIdx < SRecParserSegmentListGetNodeCount(); nodeIdx++) - { - /* get node access */ - node = SRecParserSegmentListGetNode(nodeIdx); - /* sanity check */ - assert(node->segment.length > 0); - /* allocate data */ - node->segment.data = malloc(node->segment.length); - /* check results */ - if (node->segment.data == NULL) - { - fclose(fp); - return false; - } - } - - /* -------------------------- extract segment data --------------------------------- */ - /* start at the beginning of the file */ - rewind(fp); - - /* loop through all S-records with program data to obtain segment info */ - while (SrecordParseNextDataLine(fp, &lineResults)) - { - /* loop through all segment nodes */ - for (nodeIdx=0; nodeIdx < SRecParserSegmentListGetNodeCount(); nodeIdx++) - { - /* get node access */ - node = SRecParserSegmentListGetNode(nodeIdx); - /* does the line data belong in this segment? */ - if ( (lineResults.address >= node->segment.base) && \ - ((lineResults.address+lineResults.length) <= (node->segment.base+node->segment.length)) ) - { - /* determine offset of the line data into the segment */ - byteOffset = lineResults.address - node->segment.base; - /* store bytes in this segment */ - for (byteIdx=0; byteIdxsegment.data[byteOffset + byteIdx] = lineResults.data[byteIdx]; - } - /* line data stored, so continue with the next S-record */ - break; - } - } - } - - /* close the file */ - fclose(fp); - /* s-record successfully loaded and parsed */ - return true; -} /*** end of SRecParserLoadFromFile ***/ - - -/************************************************************************************//** -** \brief Returns the number of firmware segments that were loaded by this parser. -** \return Number of firmware segments. -** -****************************************************************************************/ -static uint32_t SRecParserGetSegmentCount(void) -{ - return SRecParserSegmentListGetNodeCount(); -} /*** end of SRecParserGetSegmentCount ***/ - - -/************************************************************************************//** -** \brief Obtains a pointer to the firmware segment at the specified index. -** \return Pointer to firmware segment. -** -****************************************************************************************/ -static const tFirmwareSegment *SRecParserGetSegment(uint32_t segmentIdx) -{ - /* validate the parameter */ - assert(segmentIdx < SRecParserSegmentListGetNodeCount()); - - return &(SRecParserSegmentListGetNode(segmentIdx)->segment); -} /*** end of SRecParserGetSegment ***/ - - -/************************************************************************************//** -** \brief Initializes the linked list with firmware segments. -** \return None. -** -****************************************************************************************/ -static void SRecParserSegmentListInit(void) -{ - segmentList = NULL; -} /*** end of SRecParserSegmentListInit ***/ - - -/************************************************************************************//** -** \brief Uninitializes the linked list with firmware segments. -** \return None. -** -****************************************************************************************/ -static void SRecParserSegmentListDeinit(void) -{ - tSegmentNode *currentNode; - tSegmentNode *nodeToFree; - - /* free all nodes */ - if (segmentList != NULL) - { - currentNode = segmentList; - do - { - /* store pointer to the node that should be released for later usage */ - nodeToFree = currentNode; - /* move to the next node before freeing it */ - currentNode = currentNode->next; - /* sanity check */ - assert(nodeToFree != NULL); - /* free the node */ - if (nodeToFree->segment.data != NULL) - { - free(nodeToFree->segment.data); - } - free(nodeToFree); - } - while(currentNode != NULL); - } -} /*** end of SRecParserSegmentListDeinit ***/ - - -/************************************************************************************//** -** \brief Creates a new node in the linked list with firmware segments. -** \return Pointer to the new node. -** -****************************************************************************************/ -static tSegmentNode *SRecParserSegmentListCreateNode(void) -{ - tSegmentNode *newNode; - tSegmentNode *currentNode; - - /* allocate memory for the node */ - newNode = malloc(sizeof(tSegmentNode)); - assert(newNode != NULL); - - /* initialize the node */ - newNode->next = NULL; - newNode->segment.base = 0x00000000; - newNode->segment.length = 0; - newNode->segment.data = NULL; - - /* add the first node if the list is empty */ - if (segmentList == NULL) - { - segmentList = newNode; - } - /* add the node to the end of the list */ - else - { - /* find last entry in to list */ - currentNode = segmentList; - while(currentNode->next != NULL) - { - currentNode = currentNode->next; - } - /* add the now */ - currentNode->next = newNode; - } - - return newNode; -} /*** end of SRecParserSegmentListCreateNode ***/ - - -/************************************************************************************//** -** \brief Obtains the number of nodes in the linked list with firmware segments. -** \return Number of nodes. -** -****************************************************************************************/ -static uint32_t SRecParserSegmentListGetNodeCount(void) -{ - tSegmentNode *currentNode; - uint32_t nodeCount = 0; - - /* iterate over all nodes to determine to total count */ - if (segmentList != NULL) - { - currentNode = segmentList; - do - { - nodeCount++; - currentNode = currentNode->next; - } - while(currentNode != NULL); - } - - return nodeCount; -} /*** end of SRecParserSegmentListGetNodeCount ***/ - - -/************************************************************************************//** -** \brief Obtains the node at the specified index from the linked list with firmware -** segments. -** \return Pointer to the node. -** -****************************************************************************************/ -static tSegmentNode *SRecParserSegmentListGetNode(uint32_t nodeIdx) -{ - tSegmentNode *currentNode = NULL; - uint32_t currentIdx = 0; - - /* validate the parameter */ - assert(nodeIdx < SRecParserSegmentListGetNodeCount()); - - /* iterate until the specified index is found */ - currentNode = segmentList; - for (currentIdx=0; currentIdxnext; - } - - return currentNode; -} /*** end of SRecParserSegmentListGetNode ***/ - - -/************************************************************************************//** -** \brief Reads the next S-record with program data, parses it and returns the -** results. -** \param srecordHandle The S-record file handle. It is returned by SrecordOpen. -** \param parseResults Pointer to where the parse results should be stored. -** \return SB_TRUE is valid parse results were stored. SB_FALSE in case of end-of- -** file. -** -****************************************************************************************/ -static bool SrecordParseNextDataLine(FILE* srecordHandle, tSrecordLineParseResults *parseResults) -{ - char line[SRECORD_MAX_CHARS_PER_LINE]; - bool data_line_found = false; - tSrecordLineType lineType; - uint16_t bytes_on_line; - uint16_t i; - char *linePtr; - - /* first set the length paramter to 0 */ - parseResults->length = 0; - - while (!data_line_found) - { - /* read the next line from the file */ - if (!SrecordReadLine(srecordHandle, line)) - { - /* end-of-file encountered */ - return false; - } - /* we now have a line. check if it is a S-record data line */ - lineType = SrecordGetLineType(line); - if (lineType != LINE_TYPE_UNSUPPORTED) - { - /* check if the checksum on the line is correct */ - if (SrecordVerifyChecksum(line)) - { - /* found a valid line that can be parsed. loop will stop */ - data_line_found = true; - break; - } - } - } - - /* still here so we have a valid S-record data line. start parsing */ - linePtr = &line[0]; - /* all good so far, now read out the address and databytes for the line */ - switch (lineType) - { - /* ---------------------------- S1 line type ------------------------------------- */ - case LINE_TYPE_S1: - /* adjust pointer to point to byte count value */ - linePtr += 2; - /* read out the number of byte values that follow on the line */ - bytes_on_line = SrecordHexStringToByte(linePtr); - /* read out the 16-bit address */ - linePtr += 2; - parseResults->address = SrecordHexStringToByte(linePtr) << 8; - linePtr += 2; - parseResults->address += SrecordHexStringToByte(linePtr); - /* adjust pointer to point to the first data byte after the address */ - linePtr += 2; - /* determine how many data bytes are on the line */ - parseResults->length = bytes_on_line - 3; /* -2 bytes address, -1 byte checksum */ - /* read and store data bytes if requested */ - for (i=0; ilength; i++) - { - parseResults->data[i] = SrecordHexStringToByte(linePtr); - linePtr += 2; - } - break; - - /* ---------------------------- S2 line type ------------------------------------- */ - case LINE_TYPE_S2: - /* adjust pointer to point to byte count value */ - linePtr += 2; - /* read out the number of byte values that follow on the line */ - bytes_on_line = SrecordHexStringToByte(linePtr); - /* read out the 32-bit address */ - linePtr += 2; - parseResults->address = SrecordHexStringToByte(linePtr) << 16; - linePtr += 2; - parseResults->address += SrecordHexStringToByte(linePtr) << 8; - linePtr += 2; - parseResults->address += SrecordHexStringToByte(linePtr); - /* adjust pointer to point to the first data byte after the address */ - linePtr += 2; - /* determine how many data bytes are on the line */ - parseResults->length = bytes_on_line - 4; /* -3 bytes address, -1 byte checksum */ - /* read and store data bytes if requested */ - for (i=0; ilength; i++) - { - parseResults->data[i] = SrecordHexStringToByte(linePtr); - linePtr += 2; - } - break; - - /* ---------------------------- S3 line type ------------------------------------- */ - case LINE_TYPE_S3: - /* adjust pointer to point to byte count value */ - linePtr += 2; - /* read out the number of byte values that follow on the line */ - bytes_on_line = SrecordHexStringToByte(linePtr); - /* read out the 32-bit address */ - linePtr += 2; - parseResults->address = SrecordHexStringToByte(linePtr) << 24; - linePtr += 2; - parseResults->address += SrecordHexStringToByte(linePtr) << 16; - linePtr += 2; - parseResults->address += SrecordHexStringToByte(linePtr) << 8; - linePtr += 2; - parseResults->address += SrecordHexStringToByte(linePtr); - /* adjust pointer to point to the first data byte after the address */ - linePtr += 2; - /* determine how many data bytes are on the line */ - parseResults->length = bytes_on_line - 5; /* -4 bytes address, -1 byte checksum */ - /* read and store data bytes if requested */ - for (i=0; ilength; i++) - { - parseResults->data[i] = SrecordHexStringToByte(linePtr); - linePtr += 2; - } - break; - - default: - /* will not happen */ - break; - } - - /* parsing all done */ - return true; -} /*** end of SrecordParseNextDataLine ***/ - - -/************************************************************************************//** -** \brief Inspects a line from a Motorola S-Record file to determine its type. -** \param line A line from the S-Record. -** \return the S-Record line type. -** -****************************************************************************************/ -static tSrecordLineType SrecordGetLineType(const char *line) -{ - /* check if the line starts with the 'S' character, followed by a digit */ - if ( (toupper(line[0]) != 'S') || (isdigit(line[1]) == 0) ) - { - /* not a valid S-Record line type */ - return LINE_TYPE_UNSUPPORTED; - } - /* determine the line type */ - if (line[1] == '1') - { - return LINE_TYPE_S1; - } - if (line[1] == '2') - { - return LINE_TYPE_S2; - } - if (line[1] == '3') - { - return LINE_TYPE_S3; - } - /* still here so not a supported line type found */ - return LINE_TYPE_UNSUPPORTED; -} /*** end of SrecordGetLineType ***/ - - -/************************************************************************************//** -** \brief Inspects an S1, S2 or S3 line from a Motorola S-Record file to -** determine if the checksum at the end is corrrect. -** \param line An S1, S2 or S3 line from the S-Record. -** \return SB_TRUE if the checksum is correct, SB_FALSE otherwise. -** -****************************************************************************************/ -static bool SrecordVerifyChecksum(const char *line) -{ - uint16_t bytes_on_line; - uint8_t checksum = 0; - - /* adjust pointer to point to byte count value */ - line += 2; - /* read out the number of byte values that follow on the line */ - bytes_on_line = SrecordHexStringToByte(line); - /* byte count is part of checksum */ - checksum += bytes_on_line; - /* adjust pointer to the first byte of the address */ - line += 2; - /* add byte values of address and data, but not the final checksum */ - do - { - /* add the next byte value to the checksum */ - checksum += SrecordHexStringToByte(line); - /* update counter */ - bytes_on_line--; - /* point to next hex string in the line */ - line += 2; - } - while (bytes_on_line > 1); - /* the checksum is calculated by summing up the values of the byte count, address and - * databytes and then taking the 1-complement of the sum's least signigicant byte */ - checksum = ~checksum; - /* finally verify the calculated checksum with the one at the end of the line */ - if (checksum != SrecordHexStringToByte(line)) - { - /* checksum incorrect */ - return false; - } - /* still here so the checksum was correct */ - return true; -} /*** end of SrecordVerifyChecksum ***/ - - -/************************************************************************************//** -** \brief Helper function to convert a sequence of 2 characters that represent -** a hexadecimal value to the actual byte value. -** Example: SrecordHexStringToByte("2f") --> returns 47. -** \param hexstring String beginning with 2 characters that represent a hexa- -** decimal value. -** \return The resulting byte value. -** -****************************************************************************************/ -static uint8_t SrecordHexStringToByte(const char *hexstring) -{ - uint8_t result = 0; - char c; - uint8_t counter; - - /* a hexadecimal character is 2 characters long (i.e 0x4F minus the 0x part) */ - for (counter=0; counter < 2; counter++) - { - /* read out the character */ - c = toupper(hexstring[counter]); - /* check that the character is 0..9 or A..F */ - if ( (c < '0') || (c > 'F') || ( (c > '9') && (c < 'A') ) ) - { - /* character not valid */ - return 0; - } - /* convert character to 4-bit value (check ASCII table for more info) */ - c -= '0'; - if (c > 9) - { - c -= 7; - } - /* add it to the result */ - result = (result << 4) + c; - } - /* return the results */ - return result; -} /*** end of SrecordHexStringToByte ***/ - - -/************************************************************************************//** -** \brief Reads the next line from the S-record file handle. -** \param srecordHandle The S-record file handle. It is returned by SrecordOpen. -** \param line Destination buffer for the line characters. Should be of size -** SRECORD_MAX_CHARS_PER_LINE. -** \return SB_TRUE if successful, SB_FALSE otherwise. -** -****************************************************************************************/ -static bool SrecordReadLine(FILE *srecordHandle, char *line) -{ - /* init the line as an empty line */ - line[0] = '\0'; - - /* loop as long as we find a non-empty line or end-of-file */ - while (line[0] == '\0') - { - if (fgets(line, SRECORD_MAX_CHARS_PER_LINE, srecordHandle) == NULL) - { - /* no more lines available */ - return false; - } - /* replace the line termination with a string termination */ - line[strcspn(line, "\n")] = '\0'; - } - /* still here so not EOF and not and empty line, so success */ - return true; -} /*** end of SrecordReadLine ***/ - - -/*********************************** end of srecparser.c *******************************/ - diff --git a/Host/Source/SerialBoot/srecparser.h b/Host/Source/SerialBoot/srecparser.h deleted file mode 100644 index b38e0a2f..00000000 --- a/Host/Source/SerialBoot/srecparser.h +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************************//** -* \file srecparser.h -* \brief S-record parser header file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -* -*---------------------------------------------------------------------------------------- -* L I C E N S E -*---------------------------------------------------------------------------------------- -* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published by the Free -* Software Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You have received a copy of the GNU General Public License along with OpenBLT. It -* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -* -* \endinternal -****************************************************************************************/ -#ifndef SRECPARSER_H -#define SRECPARSER_H - -#ifdef __cplusplus -extern "C" { -#endif - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include "firmware.h" /* firmware module */ - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -tFirmwareParser const * const SRecParserGetParser(void); - -#ifdef __cplusplus -} -#endif - -#endif /* SRECPARSER_H */ -/********************************* end of srecparser.h *********************************/ - diff --git a/Host/Source/SerialBoot/timeutil.h b/Host/Source/SerialBoot/timeutil.h deleted file mode 100644 index 911b0d17..00000000 --- a/Host/Source/SerialBoot/timeutil.h +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************************//** -* \file timeutil.h -* \brief Time utility header file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -* -*---------------------------------------------------------------------------------------- -* L I C E N S E -*---------------------------------------------------------------------------------------- -* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published by the Free -* Software Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You have received a copy of the GNU General Public License along with OpenBLT. It -* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -* -* \endinternal -****************************************************************************************/ -#ifndef TIMEUTIL_H -#define TIMEUTIL_H - -#ifdef __cplusplus -extern "C" { -#endif - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for standard integer types */ - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -uint32_t TimeUtilGetSystemTimeMs(void); -void TimeUtilDelayMs(uint16_t delay); - -#ifdef __cplusplus -} -#endif - -#endif /* TIMEUTIL_H */ -/*********************************** end of timeutil.h *********************************/ diff --git a/Host/Source/SerialBoot/xcploader.c b/Host/Source/SerialBoot/xcploader.c deleted file mode 100644 index 40f63b86..00000000 --- a/Host/Source/SerialBoot/xcploader.c +++ /dev/null @@ -1,755 +0,0 @@ -/************************************************************************************//** -* \file xcploader.c -* \brief XCP Loader module source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -* -*---------------------------------------------------------------------------------------- -* L I C E N S E -*---------------------------------------------------------------------------------------- -* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published by the Free -* Software Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You have received a copy of the GNU General Public License along with OpenBLT. It -* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -* -* \endinternal -****************************************************************************************/ - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for NULL declaration */ -#include /* for assertions */ -#include "xcploader.h" /* XCP loader module */ - - -/**************************************************************************************** -* Macro definitions -****************************************************************************************/ -/* XCP command codes as defined by the protocol currently supported by this module */ -#define XCPLOADER_CMD_CONNECT (0xFF) /**< XCP connect command code. */ -#define XCPLOADER_CMD_DISCONNECT (0xFE) /**< XCP disconnect command code. */ -#define XCPLOADER_CMD_SET_MTA (0xF6) /**< XCP set mta command code. */ -#define XCPLOADER_CMD_UPLOAD (0xF5) /**< XCP upload command code. */ -#define XCPLOADER_CMD_PROGRAM_START (0xD2) /**< XCP program start command code. */ -#define XCPLOADER_CMD_PROGRAM_CLEAR (0xD1) /**< XCP program clear command code. */ -#define XCPLOADER_CMD_PROGRAM (0xD0) /**< XCP program command code. */ -#define XCPLOADER_CMD_PROGRAM_RESET (0xCF) /**< XCP program reset command code. */ -#define XCPLOADER_CMD_PROGRAM_MAX (0xC9) /**< XCP program max command code. */ - -/* XCP response packet IDs as defined by the protocol. */ -#define XCPLOADER_CMD_PID_RES (0xFF) /**< positive response */ - -/** \brief Maximum timeout for the XCP connect command. */ -#define XCPLOADER_CONNECT_TIMEOUT_MS (20) - -/** \brief Number of retries to connect to the XCP slave. */ -#define XCPLOADER_CONNECT_RETRIES (5) - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -static bool XcpLoaderSendCmdConnect(void); -static bool XcpLoaderSendCmdSetMta(uint32_t address); -static bool XcpLoaderSendCmdUpload(uint8_t *data, uint8_t length); -static bool XcpLoaderSendCmdProgramStart(void); -static bool XcpLoaderSendCmdProgramReset(void); -static bool XcpLoaderSendCmdProgram(uint8_t length, uint8_t *data); -static bool XcpLoaderSendCmdProgramMax(uint8_t *data); -static bool XcpLoaderSendCmdProgramClear(uint32_t length); -static void XcpLoaderSetOrderedLong(uint32_t value, uint8_t *data); - - -/**************************************************************************************** -* Local data declarations -****************************************************************************************/ -/** \brief Pointer to the XCP transport layer that is linked. */ -static tXcpTransport const * transportPtr = NULL; - -/** \brief The settings that should be used by the XCP loader. */ -static tXcpSettings xcpSettings; - -/** \brief Flag to keep track of the connection status. */ -static bool xcpConnected; - -/** \brief Store the byte ordering of the XCP slave. */ -static bool xcpSlaveIsIntel; - -/** \brief The max number of bytes in the command transmit object (master->slave). */ -static uint8_t xcpMaxCto; - -/** \brief The max number of bytes in the command transmit object (master->slave) during - * a programming session. - */ -static uint8_t xcpMaxProgCto; - -/** \brief The max number of bytes in the data transmit object (slave->master). */ -static uint16_t xcpMaxDto; - - -/************************************************************************************//** -** \brief Initializes the loader module. -** \param settings Pointer to settings structure. -** \param transport Pointer to the transport layer to link. -** \param tpsettings Pointer to transport layer settings structure. -** \return None. -** -****************************************************************************************/ -void XcpLoaderInit(tXcpSettings *settings, tXcpTransport const * const transport, void *tpsettings) -{ - /* verify parameters */ - assert(transport != NULL); - assert(tpsettings != NULL); - assert(settings != NULL); - - /* shallow copy the XCP settings for later usage */ - xcpSettings = *settings; - /* link the XCP transport layer */ - transportPtr = transport; - /* initialize the transport layer */ - transportPtr->Init(tpsettings); - /* init locals */ - xcpConnected = false; - xcpSlaveIsIntel = false; - xcpMaxCto = 0; - xcpMaxProgCto = 0; - xcpMaxDto = 0; -} /*** end of XcpLoaderInit ***/ - - -/************************************************************************************//** -** \brief Uninitializes the loader module. -** \return None. -** -****************************************************************************************/ -void XcpLoaderDeinit(void) -{ - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - - /* disconnect */ - XcpLoaderDisconnect(); - /* uninitialize the transport layer */ - transportPtr->Deinit(); - /* unlink the transport layer */ - transportPtr = NULL; -} /*** end of XcpLoaderDeinit ***/ - - -/************************************************************************************//** -** \brief Connect to the XCP slave. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -bool XcpLoaderConnect(void) -{ - uint8_t retryCnt; - - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - - /* make sure that we are disconnected before connecting */ - XcpLoaderDisconnect(); - - /* connect the transport layer */ - if (!transportPtr->Connect()) - { - return false; - } - - /* try to connect with a finite amount of retries */ - for (retryCnt=0; retryCntDisconnect(); - return false; -} /*** end of XcpLoaderConnect ***/ - - -/***********************************************************************************//** -** \brief Disconnect from the XCP slave. -** \return None. -** -****************************************************************************************/ -void XcpLoaderDisconnect(void) -{ - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - - /* only disconnect if actually connected */ - if (xcpConnected) - { - /* send reset command instead of the disconnect. this causes the user program on the - * slave to automatically start again if present. - */ - XcpLoaderSendCmdProgramReset(); - /* disconnect the transport layer */ - transportPtr->Disconnect(); - /* reset connection status */ - xcpConnected = false; - } -} /*** end of XcpLoaderDisconnect ***/ - - -/************************************************************************************//** -** \brief Puts a connected slave in programming session. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -bool XcpLoaderStartProgrammingSession(void) -{ - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - - /* place the slave in programming mode */ - return XcpLoaderSendCmdProgramStart(); -} /*** end of XcpLoaderStartProgrammingSession ***/ - - -/************************************************************************************//** -** \brief Stops the programming session by sending a program command with size 0 and -** then resetting the slave. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -bool XcpLoaderStopProgrammingSession(void) -{ - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - - /* stop programming by sending the program command with size 0 */ - return XcpLoaderSendCmdProgram(0, NULL); -} /*** end of XcpLoaderStopProgrammingSession ***/ - - -/************************************************************************************//** -** \brief Erases non volatile memory on the slave. -** \param addr Base memory address for the erase operation. -** \param len Number of bytes to erase. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -bool XcpLoaderClearMemory(uint32_t addr, uint32_t len) -{ - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - /* verify parameters */ - assert(len > 0); - - /* first set the MTA pointer */ - if (!XcpLoaderSendCmdSetMta(addr)) - { - return false; - } - /* now perform the erase operation */ - return XcpLoaderSendCmdProgramClear(len); -} /*** end of XcpLoaderClearMemory ***/ - - -/***********************************************************************************//** -** \brief Reads data from the slave's memory. -** \param addr Base memory address for the read operation -** \param len Number of bytes to read. -** \param data Destination buffer for storing the read data bytes. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -bool XcpLoaderReadData(uint32_t addr, uint32_t len, uint8_t *data) -{ - uint8_t currentReadCnt; - uint32_t bufferOffset = 0; - - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - /* verify parameters */ - assert(data != NULL); - assert(len > 0); - - /* first set the MTA pointer */ - if (!XcpLoaderSendCmdSetMta(addr)) - { - return false; - } - /* perform segmented upload of the data */ - while (len > 0) - { - /* set the current read length to make optimal use of the available packet data. */ - currentReadCnt = len % (xcpMaxDto - 1); - if (currentReadCnt == 0) - { - currentReadCnt = (xcpMaxDto - 1); - } - /* upload some data */ - if (!XcpLoaderSendCmdUpload(&data[bufferOffset], currentReadCnt)) - { - return false; - } - /* update loop variables */ - len -= currentReadCnt; - bufferOffset += currentReadCnt; - } - /* still here so all data successfully read from the slave */ - return true; -} /*** end of XcpLoaderReadData ***/ - - -/************************************************************************************//** -** \brief Programs data to the slave's non volatile memory. Note that it must be -** erased first. -** \param addr Base memory address for the program operation -** \param len Number of bytes to program. -** \param data Source buffer with the to be programmed bytes. -** \return True is successful, false otherwise. -** -****************************************************************************************/ -bool XcpLoaderProgramData(uint32_t addr, uint32_t len, uint8_t *data) -{ - uint8_t currentWriteCnt; - uint32_t bufferOffset = 0; - - /* make sure the XCP transport layer is linked */ - assert(transportPtr != NULL); - /* verify parameters */ - assert(data != NULL); - assert(len > 0); - - /* first set the MTA pointer */ - if (!XcpLoaderSendCmdSetMta(addr)) - { - return false; - } - /* perform segmented programming of the data */ - while (len > 0) - { - /* set the current read length to make optimal use of the available packet data. */ - currentWriteCnt = len % (xcpMaxProgCto - 1); - if (currentWriteCnt == 0) - { - currentWriteCnt = (xcpMaxProgCto - 1); - } - /* prepare the packed data for the program command */ - if (currentWriteCnt < (xcpMaxProgCto - 1)) - { - /* program data */ - if (!XcpLoaderSendCmdProgram(currentWriteCnt, &data[bufferOffset])) - { - return false; - } - } - else - { - /* program max data */ - if (!XcpLoaderSendCmdProgramMax(&data[bufferOffset])) - { - return false; - } - } - /* update loop variables */ - len -= currentWriteCnt; - bufferOffset += currentWriteCnt; - } - /* still here so all data successfully programmed */ - return true; -} /*** end of XcpLoaderProgramData ***/ - - -/************************************************************************************//** -** \brief Sends the XCP Connect command. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static bool XcpLoaderSendCmdConnect(void) -{ - tXcpPacket cmdPacket; - tXcpPacket resPacket; - - /* prepare the command packet */ - cmdPacket.data[0] = XCPLOADER_CMD_CONNECT; - cmdPacket.data[1] = 0; /* normal mode */ - cmdPacket.len = 2; - - /* send the packet */ - if (!transportPtr->SendPacket(&cmdPacket, &resPacket, XCPLOADER_CONNECT_TIMEOUT_MS)) - { - /* could not send packet or receive response within the specified timeout */ - return false; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* process response data */ - if ((resPacket.data[2] & 0x01) == 0) - { - /* store slave's byte ordering information */ - xcpSlaveIsIntel = true; - } - /* store max number of bytes the slave allows for master->slave packets. */ - xcpMaxCto = resPacket.data[3]; - xcpMaxProgCto = xcpMaxCto; - /* store max number of bytes the slave allows for slave->master packets. */ - if (xcpSlaveIsIntel) - { - xcpMaxDto = resPacket.data[4] + (resPacket.data[5] << 8); - } - else - { - xcpMaxDto = resPacket.data[5] + (resPacket.data[4] << 8); - } - - /* double check size configuration */ - assert(XCPLOADER_PACKET_SIZE_MAX >= xcpMaxCto); - assert(XCPLOADER_PACKET_SIZE_MAX >= xcpMaxDto); - - /* still here so all went well */ - return true; -} /*** end of XcpLoaderSendCmdConnect ***/ - - -/************************************************************************************//** -** \brief Sends the XCP Set MTA command. -** \param address New MTA address for the slave. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static bool XcpLoaderSendCmdSetMta(uint32_t address) -{ - tXcpPacket cmdPacket; - tXcpPacket resPacket; - - /* prepare the command packet */ - cmdPacket.data[0] = XCPLOADER_CMD_SET_MTA; - cmdPacket.data[1] = 0; /* reserved */ - cmdPacket.data[2] = 0; /* reserved */ - cmdPacket.data[3] = 0; /* address extension not supported */ - /* set the address taking into account byte ordering */ - XcpLoaderSetOrderedLong(address, &cmdPacket.data[4]); - cmdPacket.len = 8; - - /* send the packet */ - if (!transportPtr->SendPacket(&cmdPacket, &resPacket, xcpSettings.timeoutT1)) - { - /* could not send packet or receive response within the specified timeout */ - return false; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* still here so all went well */ - return true; -} /*** end of XcpLoaderSendCmdSetMta ***/ - - -/************************************************************************************//** -** \brief Sends the XCP UPLOAD command. -** \param data Destination data buffer. -** \param length Number of bytes to upload. -** \return SB_TRUE is successfull, SB_FALSE otherwise. -** -****************************************************************************************/ -static bool XcpLoaderSendCmdUpload(uint8_t *data, uint8_t length) -{ - tXcpPacket cmdPacket; - tXcpPacket resPacket; - uint8_t data_index; - - /* cannot request more data then the max rx data - 1 */ - assert(length < XCPLOADER_PACKET_SIZE_MAX); - assert(data != NULL); - - /* prepare the command packet */ - cmdPacket.data[0] = XCPLOADER_CMD_UPLOAD; - cmdPacket.data[1] = length; - cmdPacket.len = 2; - - /* send the packet */ - if (!transportPtr->SendPacket(&cmdPacket, &resPacket, xcpSettings.timeoutT1)) - { - /* could not send packet or receive response within the specified timeout */ - return false; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* now store the uploaded data */ - for (data_index=0; data_indexSendPacket(&cmdPacket, &resPacket, xcpSettings.timeoutT3)) - { - /* could not send packet or receive response within the specified timeout */ - return false; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* store max number of bytes the slave allows for master->slave packets during the - * programming session - */ - xcpMaxProgCto = resPacket.data[3]; - - /* still here so all went well */ - return true; -} /*** end of XcpLoaderSendCmdProgramStart ***/ - - -/************************************************************************************//** -** \brief Sends the XCP PROGRAM RESET command. Note that this command is a bit -** different as in it does not require a response. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static bool XcpLoaderSendCmdProgramReset(void) -{ - tXcpPacket cmdPacket; - tXcpPacket resPacket; - - /* prepare the command packet */ - cmdPacket.data[0] = XCPLOADER_CMD_PROGRAM_RESET; - cmdPacket.len = 1; - - /* send the packet, assume the sending itself is ok and check if a response was - * received. - */ - if (!transportPtr->SendPacket(&cmdPacket, &resPacket, xcpSettings.timeoutT5)) - { - /* probably no response received within the specified timeout, but that is allowed - * for the reset command. - */ - return true; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* still here so all went well */ - return true; -} /*** end of XcpLoaderSendCmdProgramReset ***/ - - -/************************************************************************************//** -** \brief Sends the XCP PROGRAM command. -** \param length Number of bytes in the data array to program. -** \param data Array with data bytes to program. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static bool XcpLoaderSendCmdProgram(uint8_t length, uint8_t *data) -{ - tXcpPacket cmdPacket; - tXcpPacket resPacket; - uint8_t cnt; - - /* verify that this number of bytes actually first in this command */ - assert(length <= (xcpMaxProgCto-2) && (xcpMaxProgCto <= XCPLOADER_PACKET_SIZE_MAX)); - if (length > 0) - { - assert(data != NULL); - } - - /* prepare the command packet */ - cmdPacket.data[0] = XCPLOADER_CMD_PROGRAM; - cmdPacket.data[1] = length; - for (cnt=0; cntSendPacket(&cmdPacket, &resPacket, xcpSettings.timeoutT5)) - { - /* could not send packet or receive response within the specified timeout */ - return false; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* still here so all went well */ - return true; -} /*** end of XcpLoaderSendCmdProgram ***/ - - -/************************************************************************************//** -** \brief Sends the XCP PROGRAM MAX command. -** \param data Array with data bytes to program. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static bool XcpLoaderSendCmdProgramMax(uint8_t *data) -{ - tXcpPacket cmdPacket; - tXcpPacket resPacket; - uint8_t cnt; - - /* verify that this number of bytes actually first in this command */ - assert(xcpMaxProgCto <= XCPLOADER_PACKET_SIZE_MAX); - assert(data != NULL); - - /* prepare the command packet */ - cmdPacket.data[0] = XCPLOADER_CMD_PROGRAM_MAX; - for (cnt=0; cnt<(xcpMaxProgCto-1); cnt++) - { - cmdPacket.data[cnt+1] = data[cnt]; - } - cmdPacket.len = xcpMaxProgCto; - - /* send the packet */ - if (!transportPtr->SendPacket(&cmdPacket, &resPacket, xcpSettings.timeoutT5)) - { - /* could not send packet or receive response within the specified timeout */ - return false; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* still here so all went well */ - return true; -} /*** end of XcpLoaderSendCmdProgramMax ***/ - - -/************************************************************************************//** -** \brief Sends the XCP PROGRAM CLEAR command. -** \param length Number of elements to clear starting at the MTA address. -** \return True if successful, false otherwise. -** -****************************************************************************************/ -static bool XcpLoaderSendCmdProgramClear(uint32_t length) -{ - tXcpPacket cmdPacket; - tXcpPacket resPacket; - - /* prepare the command packet */ - cmdPacket.data[0] = XCPLOADER_CMD_PROGRAM_CLEAR; - cmdPacket.data[1] = 0; /* use absolute mode */ - cmdPacket.data[2] = 0; /* reserved */ - cmdPacket.data[3] = 0; /* reserved */ - /* set the erase length taking into account byte ordering */ - XcpLoaderSetOrderedLong(length, &cmdPacket.data[4]); - cmdPacket.len = 8; - - /* send the packet */ - if (!transportPtr->SendPacket(&cmdPacket, &resPacket, xcpSettings.timeoutT4)) - { - /* could not send packet or receive response within the specified timeout */ - return false; - } - - /* still here so a response was received. check if the reponse was valid */ - if ( (resPacket.len == 0) || (resPacket.data[0] != XCPLOADER_CMD_PID_RES) ) - { - /* not a valid or positive response */ - return false; - } - - /* still here so all went well */ - return true; -} /*** end of XcpLoaderSendCmdProgramClear ***/ - - -/************************************************************************************//** -** \brief Stores a 32-bit value into a byte buffer taking into account Intel -** or Motorola byte ordering. -** \param value The 32-bit value to store in the buffer. -** \param data Array to the buffer for storage. -** \return None. -** -****************************************************************************************/ -static void XcpLoaderSetOrderedLong(uint32_t value, uint8_t *data) -{ - if (xcpSlaveIsIntel) - { - data[3] = (uint8_t)(value >> 24); - data[2] = (uint8_t)(value >> 16); - data[1] = (uint8_t)(value >> 8); - data[0] = (uint8_t)value; - } - else - { - data[0] = (uint8_t)(value >> 24); - data[1] = (uint8_t)(value >> 16); - data[2] = (uint8_t)(value >> 8); - data[3] = (uint8_t)value; - } -} /*** end of XcpLoaderSetOrderedLong ***/ - - -/*********************************** end of xcploader.c ********************************/ - diff --git a/Host/Source/SerialBoot/xcploader.h b/Host/Source/SerialBoot/xcploader.h deleted file mode 100644 index da586aee..00000000 --- a/Host/Source/SerialBoot/xcploader.h +++ /dev/null @@ -1,108 +0,0 @@ -/************************************************************************************//** -* \file xcploader.h -* \brief XCP Loader module header file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -* -*---------------------------------------------------------------------------------------- -* L I C E N S E -*---------------------------------------------------------------------------------------- -* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published by the Free -* Software Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You have received a copy of the GNU General Public License along with OpenBLT. It -* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -* -* \endinternal -****************************************************************************************/ -#ifndef XCPLOADER_H -#define XCPLOADER_H - -#ifdef __cplusplus -extern "C" { -#endif - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for standard integer types */ -#include /* for boolean type */ - - -/**************************************************************************************** -* Macro definitions -****************************************************************************************/ -/** \brief Total number of bytes in a master<->slave data packet. It should be at least - * equal or larger than that configured on the slave. - */ -#define XCPLOADER_PACKET_SIZE_MAX (255) - - -/**************************************************************************************** -* Type definitions -****************************************************************************************/ -/** \brief XCP protocol specific settings. */ -typedef struct t_xcp_settings -{ - uint16_t timeoutT1; /**< Command response timeout in milliseconds. */ - uint16_t timeoutT3; /**< Start programming timeout in milliseconds. */ - uint16_t timeoutT4; /**< Erase memory timeout in milliseonds. */ - uint16_t timeoutT5; /**< Program memory and reset timeout in milliseonds. */ - uint16_t timeoutT7; /**< Busy wait timer timeout in milliseonds. */ -} tXcpSettings; - - -/** \brief XCP packet type. */ -typedef struct t_xcp_packet -{ - uint8_t data[XCPLOADER_PACKET_SIZE_MAX]; /**< Packet data. */ - uint8_t len; /**< Packet length. */ -} tXcpPacket; - - -/** \brief XCP transport layer. */ -typedef struct t_xcp_transport -{ - /** \brief Initialization of the XCP transpor layer. */ - void (*Init) (void *settings); - /** \brief Uninitializes the XCP transpor layer. */ - void (*Deinit) (void); - /** \brief Connects the XCP transpor layer. */ - bool (*Connect) (void); - /** \brief Disconnects the XCP transpor layer. */ - void (*Disconnect) (void); - /** \brief Sends an XCP packet and waits for the response to come back. */ - bool (*SendPacket) (tXcpPacket *txPacket, tXcpPacket *rxPacket, uint16_t timeout); -} tXcpTransport; - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -void XcpLoaderInit(tXcpSettings *settings, tXcpTransport const * const transport, void *tpsettings); -void XcpLoaderDeinit(void); -bool XcpLoaderConnect(void); -void XcpLoaderDisconnect(void); -bool XcpLoaderStartProgrammingSession(void); -bool XcpLoaderStopProgrammingSession(void); -bool XcpLoaderClearMemory(uint32_t addr, uint32_t len); -bool XcpLoaderReadData(uint32_t addr, uint32_t len, uint8_t *data); -bool XcpLoaderProgramData(uint32_t addr, uint32_t len, uint8_t *data); - -#ifdef __cplusplus -} -#endif - -#endif /* XCPLOADER_H */ -/********************************* end of xcploader.h **********************************/ - diff --git a/Host/Source/SerialBoot/xcptpuart.c b/Host/Source/SerialBoot/xcptpuart.c deleted file mode 100644 index d3347d55..00000000 --- a/Host/Source/SerialBoot/xcptpuart.c +++ /dev/null @@ -1,255 +0,0 @@ -/************************************************************************************//** -* \file xcptpuart.c -* \brief XCP transport layer module for UART source file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -* -*---------------------------------------------------------------------------------------- -* L I C E N S E -*---------------------------------------------------------------------------------------- -* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published by the Free -* Software Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You have received a copy of the GNU General Public License along with OpenBLT. It -* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -* -* \endinternal -****************************************************************************************/ - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include /* for NULL declaration */ -#include /* for standard library */ -#include /* for string library */ -#include /* for assertions */ -#include "xcptpuart.h" /* XCP transport layer for UART */ -#include "timeutil.h" /* for time utilities module */ - - -/**************************************************************************************** -* Macro definitions -****************************************************************************************/ -/** \brief Maximum amount of data bytes that this module supports for XCP packets. */ -#define XCP_TP_UART_MAX_DATA_LEN (256) - - -/**************************************************************************************** -* Function prototypes -****************************************************************************************/ -static void XcpTpUartInit(void *settings); -static void XcpTpUartDeinit(void); -static bool XcpTpUartConnect(void); -static void XcpTpUartDisconnect(void); -static bool XcpTpUartSendPacket(tXcpPacket *txPacket, tXcpPacket *rxPacket, uint16_t timeout); - - -/**************************************************************************************** -* Local constant declarations -****************************************************************************************/ -/** \brief XCP transport structure filled with UART specifics. */ -static const tXcpTransport uartTransport = -{ - XcpTpUartInit, - XcpTpUartDeinit, - XcpTpUartConnect, - XcpTpUartDisconnect, - XcpTpUartSendPacket -}; - - -/**************************************************************************************** -* Local data declarations -****************************************************************************************/ -/** \brief The settings to use in this transport layer. */ -static tXcpTpUartSettings tpUartSettings; - - -/***********************************************************************************//** -** \brief Obtains a pointer to the XCP UART transport structure, so that it can -** be linked to the XCP loader module. -** \return Pointer to XCP UART transport structure. -** -****************************************************************************************/ -tXcpTransport const * const XcpTpUartGetTransport(void) -{ - return &uartTransport; -} /*** end of XcpTpUartGetTransport ***/ - - -/************************************************************************************//** -** \brief Initializes the transport layer. -** \param settings Pointer to settings structure. -** \return None. -** -****************************************************************************************/ -static void XcpTpUartInit(void *settings) -{ - /* verify parameters */ - assert(settings != NULL); - - /* shallow copy the transport layer settings for layer usage */ - tpUartSettings = *((tXcpTpUartSettings *)settings); - /* the portname is a pointer and it is not gauranteed that it stays valid so we need - * to deep copy this one. note the +1 for '\0' in malloc. - */ - tpUartSettings.portname = malloc(strlen(((tXcpTpUartSettings *)settings)->portname) + 1); - strcpy(tpUartSettings.portname, ((tXcpTpUartSettings *)settings)->portname); -} /*** end of XcpTpUartInit ***/ - - -/************************************************************************************//** -** \brief Uninitializes the transport layer. -** \return None. -** -****************************************************************************************/ -static void XcpTpUartDeinit(void) -{ - /* release memory that was allocated for storing the port name */ - if (tpUartSettings.portname != NULL) - { - free(tpUartSettings.portname); - } -} /*** end of XcpTpUartDeinit ***/ - - -/************************************************************************************//** -** \brief Connects to the transport layer. -** \return True is connected, false otherwise. -** -****************************************************************************************/ -static bool XcpTpUartConnect(void) -{ - /* connect to the serial port */ - return SerialPortOpen(tpUartSettings.portname, tpUartSettings.baudrate); -} /*** end of XcpTpUartConnect ***/ - - -/************************************************************************************//** -** \brief Disconnects from the transport layer. -** \return None. -** -****************************************************************************************/ -static void XcpTpUartDisconnect(void) -{ - /* disconnect from the serial port */ - SerialPortClose(); -} /*** end of XcpTpUartDisconnect ***/ - - -/************************************************************************************//** -** \brief Transmits an XCP packet on the transport layer and attempts to receive the -** response packet within the specified timeout. -** \return True is successful and a response packet was received, false otherwise. -** -****************************************************************************************/ -static bool XcpTpUartSendPacket(tXcpPacket *txPacket, tXcpPacket *rxPacket, uint16_t timeout) -{ - static uint8_t uartBuffer[XCP_TP_UART_MAX_DATA_LEN + 1]; /* static to lower stack load */ - uint8_t byteIdx; - uint32_t responseTimeoutTime; - bool packetReceptionComplete; - - /* verify parameters */ - assert(txPacket != NULL); - assert(txPacket->len <= XCP_TP_UART_MAX_DATA_LEN); - assert(rxPacket != NULL); - assert(timeout > 0); - - - /* prepare the XCP packet for transmission on UART. this is basically the same as the - * xcp packet data but just the length of the packet is added to the first byte. - */ - uartBuffer[0] = txPacket->len; - for (byteIdx=0; byteIdxlen; byteIdx++) - { - uartBuffer[byteIdx + 1] = txPacket->data[byteIdx]; - } - - /* transmit the packet */ - if (!SerialPortWrite(uartBuffer, txPacket->len + 1)) - { - return false; - } - - /* determine timeout time for the response packet */ - responseTimeoutTime = TimeUtilGetSystemTimeMs() + timeout; - - /* initialize packet reception length */ - uartBuffer[0] = 0; - /* poll with timeout detection to receive the first byte. this one contains the - * packet length and cannot be zero. - */ - while (TimeUtilGetSystemTimeMs() < responseTimeoutTime) - { - if (SerialPortRead(&uartBuffer[0], 1)) - { - /* length received. validate it before accepting it */ - if (uartBuffer[0] > 0) - { - /* start of packet received. stop this loop to continue with the - * reception of the packet. - */ - break; - } - } - } - /* check if a valid start of packet was received */ - if (uartBuffer[0] == 0) - { - /* no valid start of packet received, so a timeout occurred. */ - return false; - } - - /* continue with reception of the packet */ - packetReceptionComplete = false; - byteIdx = 1; - /* poll with timeout detection to receive the full packet */ - while (TimeUtilGetSystemTimeMs() < responseTimeoutTime) - { - /* check if the next byte was received */ - if (SerialPortRead(&uartBuffer[byteIdx], 1)) - { - /* check if the packet reception is now complete */ - if (byteIdx == uartBuffer[0]) - { - /* set flag and stop the loop */ - packetReceptionComplete = true; - break; - } - /* increment indexer to the next byte */ - byteIdx++; - } - } - - /* check if a timeout occurred */ - if (!packetReceptionComplete) - { - return false; - } - - /* still here so a full packet was received. copy its contents except the length info - * which is stored in the first byte - */ - for (byteIdx=0; byteIdxdata[byteIdx] = uartBuffer[byteIdx + 1]; - } - rxPacket->len = uartBuffer[0]; - - return true; -} /*** end of XcpTpUartSendPacket ***/ - - -/*********************************** end of xcptpuart.c ********************************/ - diff --git a/Host/Source/SerialBoot/xcptpuart.h b/Host/Source/SerialBoot/xcptpuart.h deleted file mode 100644 index b227dc93..00000000 --- a/Host/Source/SerialBoot/xcptpuart.h +++ /dev/null @@ -1,66 +0,0 @@ -/************************************************************************************//** -* \file xcptpuart.h -* \brief XCP transport layer module for UART header file. -* \ingroup SerialBoot -* \internal -*---------------------------------------------------------------------------------------- -* C O P Y R I G H T -*---------------------------------------------------------------------------------------- -* Copyright (c) 2017 by Feaser http://www.feaser.com All rights reserved -* -*---------------------------------------------------------------------------------------- -* L I C E N S E -*---------------------------------------------------------------------------------------- -* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published by the Free -* Software Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -* PURPOSE. See the GNU General Public License for more details. -* -* You have received a copy of the GNU General Public License along with OpenBLT. It -* should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. -* -* \endinternal -****************************************************************************************/ -#ifndef XCPTPUART_H -#define XCPTPUART_H - -#ifdef __cplusplus -extern "C" { -#endif - -/**************************************************************************************** -* Include files -****************************************************************************************/ -#include "xcploader.h" /* XCP loader module */ -#include "serialport.h" /* serial port module */ - - -/*************************************************************************************** -* Type definitions -****************************************************************************************/ -/** \brief Layout of structure with settings specific to the XCP transport layer module - * for UART. - */ -typedef struct t_xcp_tp_uart_settings -{ - tSerialPortBaudrate baudrate; /**< UART communication speed. */ - char *portname; /**< interface port name, i.e. /dev/ttyUSB0. */ -} tXcpTpUartSettings; - - -/*************************************************************************************** -* Function prototypes -****************************************************************************************/ -tXcpTransport const * const XcpTpUartGetTransport(void); - -#ifdef __cplusplus -} -#endif - -#endif /* XCPTPUART_H */ -/********************************* end of xcptpuart.h **********************************/ -