From 7dca426da44f57ee03210126bb5b49e32e58a7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Sun, 20 Mar 2022 23:15:40 -0600 Subject: [PATCH 01/36] Update article draft --- .../06.memory-guide/assets/arm_mkrwan1310.png | Bin 0 -> 73615 bytes .../06.memory-guide/assets/arm_portentah7.png | Bin 0 -> 68939 bytes .../06.memory-guide/assets/avr_nano.png | Bin 0 -> 73635 bytes .../06.memory-guide/memory-guide.md | 180 +++++++++++++++++- 4 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 content/learn/03.programming/06.memory-guide/assets/arm_mkrwan1310.png create mode 100644 content/learn/03.programming/06.memory-guide/assets/arm_portentah7.png create mode 100644 content/learn/03.programming/06.memory-guide/assets/avr_nano.png diff --git a/content/learn/03.programming/06.memory-guide/assets/arm_mkrwan1310.png b/content/learn/03.programming/06.memory-guide/assets/arm_mkrwan1310.png new file mode 100644 index 0000000000000000000000000000000000000000..8a8761a16ffe5db42a0b732d2e866f51cfdbb6a9 GIT binary patch literal 73615 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 literal 0 HcmV?d00001 diff --git a/content/learn/03.programming/06.memory-guide/assets/arm_portentah7.png b/content/learn/03.programming/06.memory-guide/assets/arm_portentah7.png new file mode 100644 index 0000000000000000000000000000000000000000..8ec56ab6ea4b16f5879c26fb65f12be55aa63edf GIT binary patch literal 68939 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�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

;E!z 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

5jQ?3a1ouI1r;L?&jw#0>{%LTL9 z0?R3W8Rwrd>kQp_Z{19erARv#nRmItCX*%X`mV-*{$aoqp9|LC607zKEj!$eXM_7G zD;@4iGNZR1F20}VN<9ZtmaR4uAbD#Y9c((Pv;4?K;jV!Bm5Hb9r7NKxwIFSKVubS*+c??vjfXwp*oH zu4YYuFBg?vYvuUtyC4lQGb}+NGiB{RPh;w{GNbfuYkCGu4F}rLY$>P#?l$;lP2%+! zqi7{YSM*tDe(tQ2QunSa-nED5zX6$jes;j1XH4u$CD9HmB38o#^MAhKI)s{q{`R;{^tdq0x+WM)Z5m0mcru%1fPyR`kwaZSqNUcUndt^jK znyB@|4|TX_n>xvUhNhqA!rM0seef0_WWUeP`~b%gNlE~{-=Xw`KVhBzy`j%dP4|-B z3J`YmQ%z^L%BEM+N+^D`iatl5&&|6d|B-X=7rS22M4x0#=yr~*R{VmNgJ``4T8E_B zIX}2#@bJlk`ByG`U`5|7l! zU%8*np1ADZl$!LTUCt#0aHlbcNy|2pW3fwVZ3o#w$kRelqjpRN&n7) zRk4M|wGbQX%R5)KJ?`3Fn2JPK9Z@gudwE!f!0sz%jt7xiHFFlBds^1JJA?I=4VGrU>H;j$`ooyhFc zJzvAzLmv+nJc;3`U9{Ctd<5n6H!uz?vC(>~>56GZ4BJE5EbGxDO((68ZVUVIPNZ;^ t8UV4U-5LO4uD0IzM@;sAF>>@kmhb#VcWCBy8U{l5@|o(>VtJ#0{{i5(xvc;I literal 0 HcmV?d00001 diff --git a/content/learn/03.programming/06.memory-guide/assets/avr_nano.png b/content/learn/03.programming/06.memory-guide/assets/avr_nano.png new file mode 100644 index 0000000000000000000000000000000000000000..f08c1438bf8f77eaeb241a7ccd4b7b2f5f319b73 GIT binary patch literal 73635 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%0A(y`x`4gu`Gm2 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%0DFp%b`GQYU5~xET|_gH8O&-TTss;e5QHh79@3N z7wBcCsvPP^;VZ^b#|AFze%7lVgkIbqXlj)uR)$yY{~^haFPBny5l4g}V=lRpos!aH zhw;JcdtQT(vt@>n|yI~UPP zX;(A-$NjaW5^t|@{JjSpqB|VBJ!D@r#hPOE>gtsEpmnd-q+cB$;C%Sy< z?A=+Xil{WOKntP(wq)jvFh0%3uYIzDBY*G+yT>c#cO5QD|Kb8CO<`gOly)wV0v-(C zpPjVlY!u96a$nAARHZA!HHC#q_hgeEgvGLL2(t*TZ^VpO$bx;=BUw{Zp$QmmO#xnO zu@uFL@zI;mX`dfhHn=J9a-h*&aNNjE>7NjCF$1`N!x*`5x$S>Kyh0|}cIp5hAi?j> zc)_H{9UDo8619&L`o_`Qx!?DIFvjo3jj*ag^aC2Xv4hVist32!DaM{uYwWF^O*MQu zaO1C+-YQ7AW8PDvrjvrC|Az{}5{C?RPuAA4-~D!kM&y8CaIzL_T<#gz@xBjbs3&gw z$o_N;-?@{C;0yY4e#4b{^*o?U16lD?Y?ye~tSr(o$x%vZSlAGCva$;@oXzh>CYN3f zj8>DQoL2NWpf5_e3dLUGiW9rpus>Y4`NtP&PdPV1wH~%^KHf*}yF9($zCMFYug<(^c=*0Ze72v4G4krq?K*S7v-CxZS!y#ARtl8ExHp}8 zB265`W}8kWS``0~%ReXX>o&m}d z1wcmg+21+C7RE7tz{Z(aRFTHU8TFs`Xvle-gkirG!b> zn+NiWg{H#di*{N$+2=I!O4f93xP47Xm^k}MoBc3yCEOPT%zMrM(_iWdK!wc_I5_`8 zXW!q_)O`~Q2@P;4cS!n#_&v7%Cm=N*3^$a2Y5x*G4gDW z!JS-O%zbp$(?tMm<)Y(59vU$iV37iDur+lLd^)DVVM9^OF}>-^s<@Kbx*k8eNa>m4 z9oyJ!Am_Q7d>aV)rdat5nEQxk`i^cK|NSLc8UOZKy{>TRL~c*{XK&)c4&De~;FJX_ zplV)3f9ta&;Yn)X^TOuH$Nyi4l>#Zj{QUar#@^B$5)5!bA6&+1Q5;p7rrgTt5`#7M z*AvyhathoThVML35JK`VA#HHO`X-+-P_lbP))(1_P3i#U+iDW#3iUjP)`7%Twp zS?s{5Z6Qe4ZB69krR={LIdLp!$Po9bCc|yKdQGYf9-FjI(+*uJAYqa#KL);Td-U8lbZ-=^(PRy9i zE01Zagx5b@*Xc~Ux+MV%5hB5&T*SmI<8xq?=$Pa3)0XB9&~w#}CMR1M#co!ai0MBl7?fIpNGR8#PBi zFmhkdc&Fob>&CFP>x)O-=DBK>7{k7~Qqloox;*@*YaLGA>=x9^NF3=0JgiKTUs&TM ze`eRuf9F4qH4L+HYat(5t3mUZ4849{lW{+_w&$RGyqGgHuguDq-e30kIF1?7$;qhd zTsRT<%pHLWX&0-av#iyz7#++i#_IN4m9Ja{R7|W^%JG_4eyrhyr39*bb*mz*MAU~p z_-T*w=1l0xpuck`)gI|ftJyJM?}T>%CbQtSFJHr;=4wn0U}EaOm3QI6+u-r>=>FklwO$L`1UKg-pst^o3TR3Uyo< z>(QxW99?cC?nhL@QEk<2*ge|BS&14C%2$yf*LR4% za1z5Fur4~ZA@qmlUc~DFPE-=qJ%1!>+Md0uL>L`St2TGeJe&6jzreHEx0?WahAyqp zDLle5Vd|b8u;neY{=*hJ_NT2vi5rp<2u*HDA)-7vkhc6tJ#y_-@I4Px_I;CabjQHs zl05`#<&%KS_0t}ig?sK7j>~hy&wool+tCOSFDI6XpF2HriP~>$vs(~&JTB*TUh-%- zlNHzeA&VAVP#r(kEN|;be!M<1`02}YS>_;WL_9wR@u^HJCrXoEZXz{;!;{2gFh~lud+bdT#A9s1`^o~=f1^e9_Sbm*MgVe zRZ}(Kum>xla#EcI?9UmPGP~V4t2u_+^S9gPmh}Pd(JXV|$3|aQ#Uk^aUvv!LWfmR$ z+g*}HzYQCZWM0A$_c}iI$Zfc=1$lk{#NBSlpLnG|v*Y67$TLgxh}R1ZUEc?*W3Nc2We&(cIef zQT`6a+>eGlC)j}R|IO4oH2SaZT-+JfFw8BOme~ydpOSnkG35Ukt<&4HV|fN1r18J80^NF zadG=`nlPyg3gM%D{&{SwCLdoYcw{JGJJhvLTcoCd1LDNZJ6;Li@@btIxfrR-GHxH` zC0a?I(J=0M6UoZ)x+8Yj0<^wRe(HupTwA#^$iptDH!--C4A`OlU@KJH#IyHsGkJ!% z=RpW6@$R^v2VM~f{@HQdA?I89>^5_AWp#6$SCdbC9Zi==-{wJx8D@IhuMw;GFL^wn zshhmj@+L6;BzJw}&MPl?tU+1;O%e>^H7(TsrY^?syW3#sk#_sGqzm-z2B)dnyGHrgz>&O?F50RmGjO^=1|}3 zyOXc4fsHS&fHt-8m~196iI=>uQvMyP&>-@_uZ5C7Utb{6XU~q5sZ20wgT23@wQ-$uwV4%RR8b z)pglByvrE}CWeG`Liv2_A-7g_uk01I%)}1k!ikATzz~&8SIP%NoB_Sh*Zw0*)vhxM zU3PO+Z>nY5uTK;FYiUHV1%Sx_ai)-bx1Qs@f^(;?&E`|Fi?({r&q)Q9 z$u@&Di}RIT?c)NI>^GLnKHfF9p?ANaTz>p9abocs33U{kEytxIf}B?*Z}x1R4q306 zo(`tnWdS)=_Bra$ru>4*Pp(eu3}=-Cp7<#)#RVy-WQ02RlOkjK?U2FbPpJNqYZL*6 zbM*jo#~wC*N495mBz+*Ut9(A6$Jn7R6l z?1{+Wqg8-a{Toqtz@H_i8EcS^Uztk&4Bst|R``e&OjtDUFmMl!f^9>&&C%IM&QOIo zS~jv~76{2HY&dJ%2$Oc>`6cy5Z4z)bX`0O z*KgT!l2xAZadk~>P*+>{TiZnXyj3q>DT;@tAl7Ya3!(V_0k;`bR&$-Tvv*^FgD%tF z*o~m$TEpn2d?#PP+VX74T+t@q8I!Q>trl9x?Nam5l13CG_PzY=JMh-7M}!A}9s3K1 zXFenQF>@Y=_h(?XYSQ!L7Ya0r!6@2TLKGy1A6~0FOQ&cYwN$~EK7)LPgLHY=wv~H? zo0$ZHu9PpoH#%M^%X?i0?sUbj#2Ld69178(fwrXbx0OX#7#Vv74*(HZvm^fH=Fy(s ze!9W&&4<1eLbFu*+KYR2q9-YB2{YPB;SkJXWw*EuU%ZZ6I4%=VJsuvkA%pQD~* zH98n@N!Lx`58KZ5>2y9b0yI9zf4(mo4{GybWv&d|sVfgXm#_8?%L>mK3G~C})Tyb@ zF2~*h_{e{Tr~EoM*`=FOkl21tQ&hfkVzGAVlX};#_%=qNBN-LguSvpp#m1j-D`r#| z=9gwOGO^x#+UTi!W_@e}Z)bg%k9Pt)k z3G5`g4W!qxcs-IQ(Z#Vg5m{QfAhl#+ep+j7LYc4`--2+F$65PA7=c6E*CSlQ(HIBT zYn0mO>18mz{S@Q~lgm|ug74q4D%@v+Q<=f|dV{T$mE2BKLbfbpr+P;y;E9i83P9Yp zfW9BzCCG}$xNuys{*I_y?}F+=1F!nz`1$>sUI?ATNXTKiK$>U-54&PxMdck*lHzqdzXU z9;2^TkKNZAZf$0TAiF46b94}zl$60sgQ3?h z4MGV$RiV|@16uoptxZ7>v{&LpqFWA&em40rlRD!ir~|t_3{LzNIw8{U2Ti;dzeK0K z`yTM1xUOn!-dubfxtINxRq~P3I>fFfQMVLc`~OOgcZWqaW5$^4uQ2<(_f6*qiGU#$troOazlUEo^ zcHl&*g`d?{pUI$G$8yt&HbavQoGffs$=XqtI6CPLD5@h)T%Xk|PYd-ZEvLsN2hXah zEn10$g1*d5eD)F0F6HKEauVnqtkQUVqNX-L6$!j;R|vx%_Ijc%*b$O>;nFLZz%;t) z@vZzT&#Q$T^I>)`4_z>oU93*eo+!+GB~g0y6IX+cl0hf(-Adm^0$3{6PX?nyL2n(< zt5%*kRu<1m@Bb^Xf zlG5A2y%i<~>oSkbGYAM%P2ph@eb)=;cu+r~kAJ1w^1?@~swZtCU9SpVMY4tz8tyom zms1DP>e}3`uD!)eTVr7EU4+n44T)%1oj*Y-*@?;ojUbYu6Qb0f#lvS5PV||&J+gn( zwmA{Ydz(q=BLW*lLy0^XApJD2Ix*d%tip2{`Y}$ zdbEYlfoHzc8Wr~jA?`$9GlH8JLo6>Ei393KJJhdo06B~E>+ENr4vhap7geQt9 zAv}VG*i?l~I?=tz0N>l$T)X#{!bd2HN?gc&Dpqc~g-I6Uv&y>@62;ujTjZl7ESzQI z_1;}}*rXYu^Aysf`0YrsSkFLgT(%n60;D9_({L;Mw}IeO8KD5VKc`Ja(3(O7lRq0z zBGv~vQu5Lc9ZmXtqFIR&+97=ZfpMI%J7HSsT6D0apatltWuEiBy}sBpYZhNSjX-Dp z;7m;I+bKs72TWFY4XkCvXfx{kt-kM>C_yop;ZNGZWfH>V?mBTX?wBC9 zh_14}0Cw3S>Wi z_a8uV2vQi?Gg{L*zU?@^Qhs&s3!^F+Lr^~RfIxrZog z6+NF*EK#qQ8SYCztkz={2`WrUh9;7iB|%(8)R!>jl|_6k(~VjD9^3E@tVZ{fWsPDe zt%Ay64cqoOP#GJ;fVDqlLK~Q&4W)(t!eA<;~AkTjTK^mA_r|}ZIXMX zmT*dc7nED^D|!lnuj{+4T;!sXvemQBP5cHv1g#9;wMg?*GPZzO7u@hTB6SM)wC3Ht}rcma2U4oA?fox$&>7j#j$6~W40=&1tCZ}^7=s}02 zm2vS-sgh;RTs37F72RGuv?8d5KRLs4qt%#L+SlIq<%G{aM14WhXU}2URlALW zn-D!X|MP~hrzomx-#_)F_;x5tsJj_sVlnq@P$Xb4te88$;6}>(>}WEtHSCZ{zpHs( zh1<6dr=D7S%KjrRfr6>gU6;FfjoN<>?)ySZgmA%>UOWxeM*MzcL{d^W{|afXB~Pl- z{hEY9e=jDlrG{Y8W^U1k7K$A17TK2ZPcjp@b(zAZJ0F>^mAbfniY5b3qi3Gx6KH-7 z0l=5kwCLvrNL&TNzV0pD|7bPEJ7DnudOhLGdEAV?hb~WVbvH)0Ei1wYZc-N_7thED zVrO$;v4DR8rubSNuv@N8(MQeqqiYGov33k!=DI(cZ8vk$E$+{Y+c(1EV0qk$Wm)Ap z%aU?HVku`1Mn;k2mStPRp`JC$Ff-DPyMazYJEyvTfS7(`V!_~_8~NTP+7=mImDvRE zEF)?utLNoXnmdB3XN}R%p_yH?6kB_i@VD@nRYPk=J9eZy<<1FhH+*&B8p9_f3r1BLR~IFpX;_Y>q__Pd_(Tj{3#Va<#o?(;lz90o9WDXeA8QS z$I<1K4wb!x6y47yL!8L>*HeaI>YDUei@AAjpcSi_{h zsP!Am?YN(^xM|+o(qKdEH1e0_Uw(pVbtgd!wNqYiKUFp~k2#0)mxvp*rMG zc9hIY;uMvFb{H&iqm`JP3)Lt7++h0}cHp3$Vfmd!9Yzmv|MD0=!(7@lO*!y;Kk9*E z%;P@kPar-JLNRG)*N?$>h@Wn}OR>lY-(|*xzups$L1j7l0YmR#R(S~uwV(!jk*q_J z2X=Q<4$~MMZotq>Hoc)t9Y4rtnrzg1PCZisx7wUn^o``;OkPT_VL)S%m3 zrKiZC%3!=kTTSwRbxMH4l32%F>{3EyjZ52Cp)Q76#av^HD{Pim_Nj;g*8|Z><%m-@ zqfg!488*J4MhP!&lN70xJEEo77jIXp zB?IlqyyRrRbv$HXo~EzAGz&Gu#F{cGngMK5;R^O-fkDTh^Z6O>mk_3`6HoiJxg_Ii z`f=${RUO=CGw;^tjBuX@-{B$%tp3vgrv8Yucl=K3EQ_|s-*Ce|=GMJT=bPLjBqhyr z4L`^u_mYfo#Coje%SzI_>%-~Lc5e$UTu@+|P%R|xkSR%#UGnU|)zo(lx=!){i!dW_ zG;^e%KgyxwVog zcr`zCOEw9joL0&f`t0|}Pln=ydt=m6BSki;leR=6qsJAW5Yl}|82ZLv>GP*(alJTj z%Wm_&C`714jOt;*P1l>b?=-$U2_C-xE9;L3yG(P6!xabGlZ2i;m>G0-&#&Js;mc~M zjWQ1&zxyoF%4TVymtm*(j2N}wWLN8|GomIj!WgXB=t>esUKSxKeooP3F2~99s`V3o zp{u|Nlx67+8iarrtx5Zyh!8}dFWU>+OkJ+J4J(JA1$|mRhM6V&X}n9}tqHzY=>nmy z!PkVT<&}=G9+xLGPVna|CP8zre)DI2=B$xEjZT@*t5Q#wbdqHn zU{B7Oo<{tk)IRIS@Wr&I)pV4#-LK7_uG?B-%c1K+MijX#K!lbrI8Sv!uenOYGnKW@ zaY-!=LM*lN!kbq{SQl$@-)2qQN>pH|mSb2R+UpM`&&$*$e`53{o$Q$^HlAD8Nwm*# zSC88PEmR?##OUi(XXLN;^_OE0FlQXnyuYbx?+aMEV~6=OzlhiBWMJLFEjjW|HJM48 zn-J3>W@3^fqM?p@gg^4QZ~`#TR7+4d%L24|gDGzFNJ;mr37U0A7j6uVRR2{~X9eW* z2XPU7s`-waH)YcV$C{iK-92Oc^#yvOOrK2Dx1I|g%^X@#i{1krM-n~py?x0uruevK~PH8P$~?P=JJ9+nC-Z96u3^@ zOH+FUg)z*?MOlcbEm^Sh)C1Y-+)Ect@ZR?j7HkL@H=8LIo3^`vq>qnm3@n#LfKK*E zX);LAAMS=VYZySpgjCNf`i)+gbZg@$J}uhwUhq1{l)WdT5dvR7GZO9$NM{9fx6}OQ zclGqUpmnZ~h2V$h5j5qG2RDu!zr-K5s;w2wNS(jbvRH?~NAJE8nI`B3Gi2#$9l2+5 z6Ba1QH|36)f&O&OA}EA%a19z21TiO7Z@j_4(yl% zw(Q#Sp@n%yAwL~{-%5uiXr8Wq?M2IVNjolTb$o8X(ruN~h;9^{eB9HVz_049r>kEu zJg+JkvJ%VBw!3g|$RcF!FN8LIc?7OniyIruWctdo+94hvY4g1`h?do3Oj zhJx6>SN$;o=12a{&z()pqhS^bm@z^Yz+hu#CnpwItv|794XT~DRGnuR#Yf2VA~D%U z5>ZBztPhKgg@gR9BsB23!FF_P0seelv(Yxdu0X!d2@cDM{b`Jz(9Tae_Ow}ROgjx`Pb9mY6CE${%A4uEauC!0{g@_e)OtW z+;4R00B9?YV$;#rl+=_0C3QGlmr&k*cN3zZl-$xb4TD;G;$llWv0y ztWXejrm%0QAT+H9o1FRza>TxP6YX14_q1N_nLw5?Z0c`VWTbPGd_2(VE!`U#b> zf0TSpmXHURq&)54*(kZfE@kQS(K5K&la7b!+MM*_k~fmq;9O3*pet|7I5+LSu()i>AVm}eLJ56S^ZwPg;6J#xYhPZpOXpBVryV(N^b-Gl zKE1&Jb!2m*Gc6}Meaq~Q0Y@G=+gsw0+Ox~YsfX__b+v7cn2_GFhQz`tZk65Hi*;lj zZ7jH+ZU`iOW8CU*ImKCw`L#ok(_7wa77+&96C)b>GX`Zq!WGzBg1yLCtna5<6JWXP zX;*4_*6Lx&3aS;g!vW`0u0V-rn}s@ zo)YWj6H)`)*Vl0NSB_>qb?I`pF=JG<`nGzF*FlQ*V(<3%=>^Q!WWRpKnp`);t(l+D z$Sg;5cD2&Vw0nWw&GI85&TP6db9=2#ueg?D@XwnEE6Y9(*3y6p4zz6~?27Ure(~$DMfRVe8_Z%3~9>mLmc&G85H?Dq2~H z$S?&K9*KZK3Hhq%Zg_LWN{IUjA2I?2)^-!ONR5ws2tXCDKgGgLZyr|F(s^<)EC+pc zVSyA(vJxAg>u#5kKK(wzb}@1+611AcZ@kznhNx0Hs+~;nps1HU)~?!2Jfl4$QTVje z&5MVCUWA<}tzF(n{#jok-y(uEGgptb&^JA zVL{;G4$T;xtQ0Ea3yr-}FY?e<(ny*pwNPVKnx!jCs2UkH4OaQQ^c!KujC(z0#`v4+ zF<)@2edyX#37sJXe@p$jUA+nPdt{P*TQeqaBwB~*R%u0LI6}l_~MY`^F0!`PXiCUmL0F70Vso6rK#nQ zHXn*sZUsto^rPofhQ(f*JQ5=9IST9*9nELpFT7txv<#bp0o!UGxA4oL$1~UJV$}oo z_(g5D6?SJJA>A4vJN#s__lQO^F1nJ_s>;}sYOU}AJ=SD=Y1o+0_z}ISd10Pc?9K=p zS7Ec?Aa|(u;A;DQRQK<1Kn@>By3#1u#`R%)XzmPJI7H)NgY&QVK z$z!MkjBnX}w2c;3-O5P;>l7n$Ml5r!JtbFeFEreUrw-imxE2&*^tKrU@HX0nQ=`Nk z@p3A?k0~BJc&_v2F_4QT@$_1r^#id_GWLbRU27_EmhDy_&e-R+G@Rv=*lLF>TCH2< zw^&p92j7;$A=f2^dH9}BD1RwNk{fCR(I>|&W=D6YqFikA?>7)~ekbI4uuhbfd~; zYbV?IK|s>JFagL2fK~$FkE@T)E-&)UEyuh-9s&jPPIBq#dnNgfzsUws5jnea2EP%X*vBQLZ;{W-BEyT>=tS?u<4gn2|&2rOmsPg;MI?pNbqAN4n&R*r4IkaC9EZ}Eu!07%5WZ31qU_Wh=0 zx0IW$VEhd>A4dKbfpL^UK56XwUz~&n6*TtuYjXKjLT$zGwcznPC6D8;AFzD7QIu`@ zHuevs;SPnrL!b4XSWB4>-hndN%w8x%*)SO68fuV18u7VMww%DGcA=suJJM6i4~&e) zWQ#w2(jFIH@R8TbR_Ob!%!i5zh4_@n{n)`-;Rin>tafv%DVzj(vY-02%6YzC^oXc8 z7brd?cB|KD$yRgo6&fObeS5+pxZC!FTHimN>4@y^lI7&UD0e{1*w>+`IbHS#jXCr9 z7n314;h7Sb21z_ZwY$SeS=Xof?i%+7^;LSc?}s*Jq2A`yzWZ`si>6)N?UE&n>C+fyrhCm?*VhNX#cr zp4HhApKImdhD!><>5^FqK*1zEv_X2GgUtNWK!;2aHLuL*;`{6@?KELVt%+(Ru=AFY ze^U|`(b3neV~11sGd$AL zRq4}YJVdedt&Lj{MXu)u8k^6nims=&j}=20-Q zQ|%cQ*OP~E_8&6=?LWz4Nfs`AHfSVXQSz@CBfD5>qHGn^DQZ5V{nR{G49Y{5jjdlM z;=CEYe)Ur{J~o_1eYq0$&DbGI%bPPB!f!NQJb}-kaTkqip#PvvS9l?=Y)TzVkhjU9 zAt=Z(UE3=iD-Pa+-1>d5JGZz;J%_H83Bxt;&B3TtNTNz_upkbZH~fgQiWhcI`=bOU zELDpxXc@|J9-s@1Z|J)Hi1!9PB=pE47A3s{?sFfRIA0Ppc~o@oyw3;RC8?GxYUV2Y2qv^{5oO(^ULFN{GD$>U?K!oFLq)(p6A*V@<&HMCdWI`NE+bmN~Z1Z?5_4CG# zvbO&S-B|eWFX)B^dH2{AoyjJ1_N3gPWFBF#7kQgIw_s2r>x(M}6x>(i#73riV*nm< zHtM(41Yn!7>l;{$TwU<%%0u*mYfV;=y0bG8nPstJle$izI;)Iv+&n6H_Q^EI^JUc_ z4WXjAm6)oowe`xK$TS#Hj7_U&5wyP|OX2<4;se&pGJY;as8WM+##M!5jdo_ngCG|6 z$gNtQ3#HD7&6g-2+~PTFZ-~n8iLC`tI0I^d09~!YI+bFy_pGSkPa?f%wwFsxrhM}$ zX`vm52yYIMVRKSJz}iVeu-W4BqhgKZRo<>V(qCN*A%zF;^J^WiZMR=<=_unQJSgVL zL;}SJu2KIv}o0D!e)Xt;TJu>n&?!ZkN5eAs|Lx z?8d<7a#S9uVe2NotLgprLIsvak*nBRoZIi3e7N^4NB0^5C>()I3~Ohh^N;pE!FFG- zU(gWLOTsy}i&+w|6{xHJ2^vIN!mpQ2d%p~6&I=}LRx6}wPsf?qnWKNCZhK=0soQNs zyFf^-{uc;xJyKtSq7aOyI-Yz}c^^+J*Sby@ZEzt>5V%N%_k zFfAtkFA$J;cwN${O@*pBUYiGH&fSs{S$niUcHC=__TlQEl2N7iF%w$W`V;qz!yJ{Dbl9Vk4Z?}72Z8u~& zJBqTlJnBTppP$%q9M4H=`ZW?%rp8dPARHh7S?bw#wS8|RR7EcwA)uxM0#G3m7YdE2 z)frz^26hWxZgwr-jdBz$^64|~&^}Y}&_zcPzT4HX;ZQM%G~jsqYD``peW;XwqDj1@ z#;mINoeVZNS=UsvWzEf%CgZ&SQ1@OwdXQsN%c!Y-89rT~68nur#g6f%((6CF^`h^2 zpRLQ4#Z9w46B%l$ziLB38+}xFe%bd>Jm5}7lddK{8T!R!r2k6Jg=bpZBYg-g*TNG) zq0Rb55(!oyv_qD`XE}QN@qp|3k~m9Z0{7+vH-%BO-@0$#YXA|lF^QHAV5b*!TOaSd zlcE`+UDwrgO*bAH4dS9WFQUmqIH?K2AZ9^79k}AtJ<47#q8MN3zUcphCghQ+WVqF? zbM}Q_HV2_92MHGp4H>2{w#u_abiMu+^6Jj{6Y$3BxiM-i*)_V8@a3e$<&6}r#V_D4 z(h_OY3F(iND=zWwoWd0Sc58XR0WiQZ+1|=_%(z2b$HQ#)xCyML^d&=5S=!`{37aM4 z?cy4vbz`*jP5vudCuMSn_YciO+phvQXa0BoP11s5Nc(^}(A%d+^M7Ir0J{F8fGq5Imf0(>QSnb{s3zyz)2aD- zQZvlx-i>pr{WpX1rM4ukXS0Lc!%4rKgjdHuxUGlRzII76925 ztq`Wo453)`Q22uJ^>+`NKTv%7Ti@bBv$|FWGq%9%?rA{rffGRV#P&C{ zwUA=%wBXdA+Ea`7!=`OIM`)&;i!K!$k2p-HXD5C&KGdO{8J+j04||L7Dc!0Dyh)w_ zXrPQ8_yFoFLF^}F63wc)Uc6hup8f;reE))S-E;^3L8un9R4RGF)q1NQZPc^3siHB3 zx^aE+LHg_*6{x+>+3_*iOK{HLAkEeHYTvp}3SOKe?>Psg&-6qE28}MNw|=KE{L7HW z+72ZB4MrQysP=1?N&#iSJi4Jk^v~BOeddEy5acA=^CX0VRN#C8WH3GIH9;u#SFk<- z6IDO0HhVP@ku7FWWD8ef*a;*8c8o&SH?=#%U6IEt958;_!pQk#N3 zBp$QL>hFsR3LMxcxtEenGn4YD2HHI-SKmzm!o#*+LTTdR#%;yC9CxR$M7PuO^mSyH;7+-$s$xBMu)GxH=w*lxOED9et6wCBeX zY@$W|cU3qt4*M*RGrfpG$G3eCtLVu~IJkSe^)*>__Ym}ohv8nn-C^@!_M{C?L4&yL4JtvD2};yY%uB#P;B$0xxFPWPpR~= z(C&BCMlDtEp0C|7+J$tpI~*3uy{m%NW<_IJCFzYF>vm!VzuaVp4+qLBC6XU?3NR(=@* zuO#29v=w6w)ZaV@jfwP8)N3fz$JEZXD7)Bj!B%t~qzAWuKK*SpeUx*t_K=OT)+2u# zFWkq6)jLQe+o;N)#@H|gkNfNGcJp=Cb9Rnrk}VKLKp>)A3vq~SN9?XFWZ%z9WphF? zm*zOk*GFQWU11nk_(>%DTq`$dbJ1?ApE=%t4Qsjb3W|;koFa!TG1j@tAJblxTd4y{gX4p2!~+P5pkC^Fn82; zVRxE7>;-Z=_oAl9E@kwN*Uhnqv(PRd>4qY`x1hfJzLHZO`zBkhkxm-db!)*#UGDA! zj6N-wFQK1fw^6mDSN5tXJCl)*<}b(|FMA^6>jk=naW0do{8w+KIZ8eU$ql_2n~JQr zsZxKWzMp5scdisGe!#Ko^A*er-(GLRYNM3;<$sG=csB4zZbb-;ty%SY`siKKOURNf z*1}8s7L0BSG)s!pRvZn~LX>|ZdPhC9wu$R7E9WI^U}Lo(ysZvo;lhuCV4b8I;`WAN z@CN!ucHg_4W1cOQeXs`hk$RV8)y9l-Fo-g~zR%{oC5jXn%QN)!Rm;P!V)upBURQ5N zh{p;WSAQ1hujc7spe6N2=XX1_h+?Ckcz6t{DHB_<-DW%;L8Uvj0-ru3%t+k06*?l- z{3^3G-K*t`e2xtE#eKED)ZHxwyL?si1a;=CATREt6bM$HXqFDeA2H9WYwTD0sX7%u zC(R*`>JL+elze8kAzX+7gdysVw`~J>zMdsv|Js+p?O%NZ2xC+M2JG4|zM)6U0@MuW zxv2;SvO?;_Jq?S8BN{aITo+*}2%P zFy`9VjR$$AQ8-1}*w)VGd_BhTIM^x0L+a!XAV#P(&umS0mqOTUc6o6R!%9%lHwg*a zTMcuRtJ0y}>lS6M8otmGJE0OUnY80_y&qL3*eH*6seQ)nI{H<5GJ&ZsQGL;^cJbJ- zH+03#o%(zd?c902#cr!C?EBKaDy#KRVc`Xs-*9*9IumTz{J!GRbGkx-MV1aWUvDLA z?A!Ne-m7Wpxl|r1Z#ybg4moSjhfZkPLWhqUG3txDp4lS$J`d@4V5yvaGhmx6{d!=) z{3@l`^>T{53(1yKe6{_NOY=|guqwezS~K#<#)S#}XwNEQdddJjH-eK973jECaVt8k z`qmcYeZvM7b-#rE#_TM(M_ccHzteFoAE@8MK;7rCkm`qD{}l>?xKSEM-c@XIwyfEF zI0@27cO%1K;eB0LVaK#=DwE^l*-qx)^w7PUp5;chZvq@(S)}NBNIm#~*|&Un_-OQI z?sIIpaB(alAj}=3wk5HzvM*fOk9SJuJIDC8Jm2d5YqMbS0iy*ew?4%#THnGC+_YEo z%=CzC_|&Bw<9uk!bGQOGlkTJXZ;!jSA+{IP;SCbVFV7k+&@P;z+UgfA_gT8`bK2~F z8`mAhFc)xL5a0T-f2)#v)YsXM(_x?Xv09k;uGKG+3qUuiUuH$h=n(F3bO_A%T%;Yd zLU0O?yjk!i_#ezo^hS+I2|m;=z!azE`?{-MbX(lsO>~X<#a7i>evE~8;++z-aywLt zd%6`+x6-(dXU(LD3PP1qRrw6{Hdx=sJTDDgOA$7O9dVp8QyiJn;rSyxskT8*lSMEs zC-{W>(w!SPL}Y%l-o(Te-(%5z?R|!QIKY6Cb@-glvTp0)oj@%iE?@jG-F~e?SV5Jj zHjnQrOlPl8yepE&H}r5S5}2;pkXRO7Tnr9-r!ILtv(BN1i3KFD`v?-f;Cpowd3XIx z0eyi@&LXY7WF2|C1C$|b2sm4x_Ho_*SM*A?)Bz}Fk1JAm*i(A_tT1GC&Ck# zDU2r5`QatmrCl7KAe@9qTPun#_TF7{81(jQ_}vzmKOaOnEWBKnuV>~Ism3}fjC^q1 zUO$uZ+V0Peq~ZR0V1 zFsU#a1yvCvG+{gMrv{{E7x#3er+T7gpxmG@1F3*~;d_O2-BZa8*1bc$iAS>udCLy! zL1KE&i{QAe^JeoKvXZZeLdV{khvQ4KRSQ?V4Z^hN6HtT_tk#33?;EMMn(2ceDHwd* zXrVr9jjL79O`^c2P8)Pwde~b{R7%@W^JJj4MeXO=vxXWM*yDRJX`%+MYez)=eu1UQ zi4mv3uhtvq-HnkoQ7?mgc)C5-fBLVRY#m8Aa*q6#Zb#X=u6gS;AlG@PCJLWLU$JUi zv#|>27@JHz2lS(ro9e8yge&Bz6%T8y#>CT*=r8WZ*5fK2W@#Hip4hz-#}>7QqAJE0 zi)#2zs^h0zDCk1?mZ*EG4)Kfo7gyC3&+5(*S9n2~rWb(@D=7YWQE#ld;cEeXPj0)s zCw|QjGrJS@#MYa@@?!{_)O2&1T*phDCyj94-R1R*Oy`*pDzUrw^>sI@^O=h=NKGu( z6Lsg{W=$QTpr~PpzTrpi10K(5?yXne$9)2_g_@exYRC;1VpxZ-SEMn@N`FFKztd$g z4nsCSf1U~kp6|uWK*~v78(t{UBkl4@7mANniHBI*DE(|@s^k!6Y4oRc**gI@%?e-% zP7X7q2}Os>XARI6`@8iA#Y>%$oRQtMld1U#E5>NZPDB9=_^U9cY zZm-114ySk=!nRl4`y5An_IA;}Y*ggHkevae+QR4=%lt)`1pBXr9PYJ?R}l$gMv

  • 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�)3)0v;nXA5k*5JC4$}UST&lZ9P8xq+QQ5c^ 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 bFTegX$|#?Y3gm3e1gZ3N^>bP0l+XkK>FgfT literal 0 HcmV?d00001 diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 8a50042fa3..49366ab748 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -1,9 +1,31 @@ --- -title: 'Memory Allocation on Arduino Boards' -description: 'Learn how the memory on Arduino boards work.' -tags: [Flash, SRAM, EEPROM, ] +title: 'Arduino Memory Guide' +description: 'Learn about the built-in memory blocks of Arduino® boards in this article.' +tags: + - ROM + - RAM + - Flash + - SRAM + - EEPROM +author: 'José Bagur, Taddy Chung' --- +A microcontroller (usually called MCU) is an integrated circuit (IC) typically used for specific applications or tasks. Usually, this type of IC gathers information from its surroundings, process it, and generates specific outputs according to input data. Microcontrollers are everywhere; they are an essential part of modern embedded systems. + +## What is Memory? + +Memory blocks are essential and fundamental in modern computing systems, especially microcontroller-based embedded systems. Memory blocks are electronic devices, usually semiconductor devices, that store and retrieve information or data; the CPU of the microcontroller uses and processes data stored in memory blocks for acting in a certain way. + +## Memory Architectures 101 + +**NEEDS REVISION** + +The name Harvard Architecture comes from the Harvard Mark I relay-based computer. The most obvious characteristic of the Harvard Architecture is that it has physically separate signals and storage for code and data memory. It is possible to access program memory and data memory simultaneously. Typically, code (or program) memory is read-only and data memory is read-write. Therefore, it is impossible for program contents to be modified by the program itself. + +The von Neumann Architecture is named after the mathematician and early computer scientist John von Neumann. von Neumann machines have shared signals and memory for code and data. Thus, the program can be easily modified by itself since it is stored in read-write memory. + +## Types of Memories + There are three potential pools of memory in the microcontrollers used on Arduino boards: - Flash memory (program space), is where the Arduino sketch is stored. @@ -14,6 +36,156 @@ There are three potential pools of memory in the microcontrollers used on Arduin Flash memory and EEPROM memory are non-volatile (the information persists after the power is turned off). SRAM is volatile and will be lost when the power is cycled. +## Arduino Board Memory Allocation +Arduino boards processor vary by family, depending on the necessity of the user. Arduino has two big roots that can be differed by processor architecture. The boards are either powered by **AVR** or **ARM** architecture. The Arduino boards such as MKR WAN 1310, Nano 33 BLE Sense, and Portenta H7 are powered by ARM architecture using Cortex-M family. The Arduino Nano is for example powered by AVR architecture using Atmega328. +​ +### AVR-based Boards +​ +AVR architecture microcontrollers has the Flash Program Memory and Static Random Access Memory +on a separate bus. There are 2 existing bus in which handles all the data and the other line handling Input and Output with limited access. The memory architecture is allocated briefly in following manner: +​ +- Program Memory (Flash) +- EEPROM Memory (Data) +- SRAM Memory (Data) +- I/O Memory +​ +Each memory type serves different role that handles the function of the AVR architecture microcontrollers. It is good to know what does each memory class manages, to comprehend what is about to be detailed in the continuing section. +​ +#### Program Memory +​ +The Program Memory is the reprogrammable memory found on the system. This is the Flash memory that serves as a storage, and the memory divides into two different section due to security measure. A Boot-loader section is where all the crucial code is stored to intialize peripherals and essential components. While the application section is where the composed code is uploaded. +​ +#### EEPROM Memory +​ +This type of memory is Read-Only memory that is electrically eraseable and reprogrammable. The memory module is designed usually with minimal resource available on the table. Commonly the memory is used to save small amounts of data and store even if when the device powers down. EEPROM registers are to access this memory department and during rewrite process, the memory removes everything in order to reprogram. +​ +#### SRAM Memory +​ +The Static Random Access Memory is accessed via standard data bus, and the data is retained while it has power feed. This data memory stores different memory units that are from registers, Input/Ouput memory, and its internal SRAM. All this is to have general purpose 8-Bit registers, control registers to address peripheral components, and volatile storage location to temporarily manage the data generated from the code. +​ +### ARM-based Boards +​ +ARM architecture implements **Memory Organization** or **Memory Map**, built depending on the width of the address map that goes from 32-Bit to 40-Bit structure. It uses Virtual and Physical addresses while the Memory Management Unit (MMU) interfaces in between to correct operation of memory system. +​ +The **Translation Tables** are injected by virtual addresses, composed of Kernel and application in blocks of data and code; then translated into physical addresses composed by peripherals, Flash, SRAM, and ROM. The present architecture uses its Memory Map, predefined accordingly depending on the ARM chip family, to ease the access. +​ +## Heap & Stack +STAND_BY +​ +## Measuring Memory Usage in Arduino Boards +Memory usage stadistics will help you understand the resource management affected by the designed code. It is an important factor to consider, as the resources are finite. In fact, it should run without always reaching maximum load capacity. This is one stadistic that will tell you how efficient the code is designed. +​ +### Flash Memory Measurement +​ +The Flash memory on Arduino boards can be measured with the help of the Arduino IDE. As the Flash memory is where the Application code will be stored, the Arduino IDE will report through output log to let the developer know how much resource is being used. +​ +This is the output log format for Arduino Nano. +​ +![Flash Memory Usage - Arduino Nano [AVR]](assets/avr_nano.png) +​ +This is the output log format for Arduino MKR WAN 1310. +​ +![Flash Memory Usage - Arduino MKR WAN 1310 [ARM]](assets/arm_mkrwan1310.png) +​ +This is the output log format for Arduino Portenta H7. +​ +![Flash Memory Usage - Arduino Portenta H7 (ABX00042) [ARM]](assets/arm_portentah7.png) +​ +Each image of Arduino IDE is based of three different Arduino boards, one based on AVR and the other two based of ARM architecture. The compiler will output a log where how much Flash resource is used when uploading the code. +​ +The purpose of three images for different boards is to how that for each Arduino board family, the output log format is little different from one another; but it will show you the required information regarding the code that is to be uploaded to the board. +​ +***If it is required to handle the Flash memory within the code, please read more about in [this](https://docs.arduino.cc/tutorials/portenta-h7-lite/por-ard-flash) using Arduino Portenta H7*** +​ +### SRAM Memory Measurement +​ +The code may upload and run. However, there may be situations in which the program will suffer from sudden operation halt. Moments like this can be due to memory resource hogging. To solve this, it will require to understand in which sector of the code, the memory demand is going beyond the available resources. Following code fragment will help you measure the SRAM usage while the code is running. +​ +```cpp +void display_freeram(){ + Serial.print(F("SRAM left")); + Serial.println(freeRam()); +} +​ +int freeRam() { + extern int __heap_start,*__brkval; + int v; + return (int)&v - (__brkval == 0 + ? (int)&__heap_start : (int) __brkval); +} +``` +​ +In the code, `__heap_start` and `__brkval` are as following: +- **`__heap_start`**: Refers to beginning of the Heap. +- **`__brkval`**: Last memory address pointer used by Heap. It is pointing towards the Stack. +​ +### EEPROM Memory Measurement +​ +To be able to use EEPROM features, it is already included with the Arduino IDE platform so it does not require additional step to install any library. +​ +EEPROM memory measurement can be done through use of the following simple code fragment. The code is simplified to write a byte to know exactly which address it is reading from. It can be modified to read everything from every possible address. +​ +```cpp +#include +​ +EEPROM.write(address, value); +EEPROM.read(address); +``` +​ +On the other hand, it is possible to clear the entire EEPROM memory to set it to 0. +​ +```cpp +#include +​ +... +​ +for (int i = 0 ; i < EEPROM.length() ; i++) { + EEPROM.write(i, 0); +} +​ +... +``` +​ +The complete example codes can be found in our guide to EEPROM found below the following code. +​ +***For more information on how to manage the EEPROM memory, please read [here](https://docs.arduino.cc/learn/programming/eeprom-guide)*** +​ +## Optimizing Memory Usage in Arduino-based Systems +To know how the code utilizes the memory resources is one matter, but to optimize the memory is a whole different task. As the term development may infer, the requirements may change or be adjusted depending on external factors such as reduced device capacity due to inavailability of the components. Thus the code architecture may require optimization to be able to run on the reduced limited memory resources. +​ +The optimization process also implies reduced computational complexities, trimming down extra time required to process the tasks. The memory optimization process may help the overall optimization process, as it will handle how the memory is managed in a more suitable manner. +​ +### Flash Memory Optimization +​ +One of the memory sources to begin optimization with is the Flash memory. As the Flash memory is where the size itself of the code can be reduced greatly by considering some details. +​ +1. Detach Unused Sources +Detaching unused sources include unused libraries, and code residues. Code residues can be composed of functions that are no longer used and floating variables that takes up the unnecessary space in memory. This will vastly improve the compiled code size and make more clear compilation process. +​ +2. Modular Tasks +Modular tasks mean functions that wraps the code which will be used in a repetitive or continuous manner by receiving different parameters. It is a great way to maintain clean code structure and performance, while reducing the memory space required for additional tasks that might need to be implemented. +​ +This leads to compact code structure, that is much easier to understand when debugging process is required, and demand developer to considerate compute complexity while designing the code structure. +​ +### SRAM Memory Optimization +​ +1. Literal String Reduction - F() +​ +2. PROGMEM +​ +3. RESERVE() +​ +4. Buffer Size Control +​ +5. Non Dynamic Memory Allocation +Dynamic allocations cause Heap fragmentation. Although, when dynamic allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the Heap Size. +​ +6. Corrective Data Type Usage +​ +### EEPROM Memory Optimization + +TDB! + ## Memory on Arduino Nano boards The nRF52840 ([datasheet](https://content.arduino.cc/assets/Nano_BLE_MCU-nRF52840_PS_v1.1.pdf?_gl=1*x4s7j8*_ga*Mjk5OTAxNjU5LjE2MzkyMTU1MDg.*_ga_NEXN8H46L5*MTYzOTQ5NzYzMS44LjEuMTYzOTQ5ODc4Ny4w)) chip found on the [Nano 33 BLE Sense](https://store.arduino.cc/collections/boards/products/arduino-nano-33-ble-sense) and [Nano 33 BLE](https://store.arduino.cc/collections/boards/products/arduino-nano-33-ble) has the following amounts of memory: @@ -141,4 +313,4 @@ If you run out of SRAM, your program may fail in unexpected ways; it will appear - If you have lookup tables or other large arrays, use the smallest data type necessary to store the values you need; for example, an [int](/en/Reference/Int) takes up two bytes, while a [byte](arduino.cc/en/Reference/Byte) uses only one (but can store a smaller range of values). -- If you don't need to modify the strings or data while your sketch is running, you can store them in flash (program) memory instead of SRAM; to do this, use the [PROGMEM](arduino.cc/en/Reference/PROGMEM) keyword. +- If you don't need to modify the strings or data while your sketch is running, you can store them in flash (program) memory instead of SRAM; to do this, use the [PROGMEM](arduino.cc/en/Reference/PROGMEM) keyword. \ No newline at end of file From 26e8912db81f84e257b45476489324139a902aac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Tue, 22 Mar 2022 09:28:56 -0600 Subject: [PATCH 02/36] Update introduction and what is memory draft --- .../learn/03.programming/06.memory-guide/memory-guide.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 49366ab748..e1b9db6a6e 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -10,11 +10,15 @@ tags: author: 'José Bagur, Taddy Chung' --- -A microcontroller (usually called MCU) is an integrated circuit (IC) typically used for specific applications or tasks. Usually, this type of IC gathers information from its surroundings, process it, and generates specific outputs according to input data. Microcontrollers are everywhere; they are an essential part of modern embedded systems. +A microcontroller unit (also known as MCU) is an integrated circuit (IC) typically used to perform specific applications or tasks. Usually, this type of IC gathers information or data from its surroundings, process it, and generates specific outputs according to the gathered data. Microcontrollers today are everywhere; they are an essential part of modern embedded systems that can be found practically everywhere in our world, from smartwatches to electric vehicles; they are even on the Martian surface right now. + +One essential part of a microcontroller is its **memory**; memory stores information temporarily or permanently in microcontrollers and can be used for several purposes. This article talks about memory organization in microcontrollers, focusing on those present in Arduino® boards. Also, several ways to manage, measure, and optimize memory usage in Arduino-based systems are discussed in the article. ## What is Memory? -Memory blocks are essential and fundamental in modern computing systems, especially microcontroller-based embedded systems. Memory blocks are electronic devices, usually semiconductor devices, that store and retrieve information or data; the CPU of the microcontroller uses and processes data stored in memory blocks for acting in a certain way. +Memory blocks are essential parts of modern embedded systems, especially microcontroller-based ones. **Memory blocks are semiconductor devices that store and retrieve information or data**; a microcontroller central processing unit (CPU) uses and processes data stored in memory blocks to perform specific tasks. + +As shown in the image below, memory blocks in microcontrollers are usually described as **arrays**. Memory arrays are divided into **cells** that can store data and be accessed using a unique identifier representing its **address** or position relative to the memory array. Information in memory cells is stored using binary digits (bits), usually organized in bytes (8-bits); it can also be retrieved later by the MCU or other components of a microcontroller-based system. ## Memory Architectures 101 From 7a96336c319e0747c31bcce469d19531bb15ae9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Tue, 22 Mar 2022 13:05:23 -0600 Subject: [PATCH 03/36] Update Memory Architectures 101 section --- .../06.memory-guide/memory-guide.md | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index e1b9db6a6e..7bcd92aa2f 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -7,7 +7,7 @@ tags: - Flash - SRAM - EEPROM -author: 'José Bagur, Taddy Chung' +author: 'José Bagur, Taddy Chung, Luca Osti' --- A microcontroller unit (also known as MCU) is an integrated circuit (IC) typically used to perform specific applications or tasks. Usually, this type of IC gathers information or data from its surroundings, process it, and generates specific outputs according to the gathered data. Microcontrollers today are everywhere; they are an essential part of modern embedded systems that can be found practically everywhere in our world, from smartwatches to electric vehicles; they are even on the Martian surface right now. @@ -18,15 +18,23 @@ One essential part of a microcontroller is its **memory**; memory stores informa Memory blocks are essential parts of modern embedded systems, especially microcontroller-based ones. **Memory blocks are semiconductor devices that store and retrieve information or data**; a microcontroller central processing unit (CPU) uses and processes data stored in memory blocks to perform specific tasks. -As shown in the image below, memory blocks in microcontrollers are usually described as **arrays**. Memory arrays are divided into **cells** that can store data and be accessed using a unique identifier representing its **address** or position relative to the memory array. Information in memory cells is stored using binary digits (bits), usually organized in bytes (8-bits); it can also be retrieved later by the MCU or other components of a microcontroller-based system. +As shown in the image below, memory blocks in microcontrollers are usually described as **arrays**. Memory arrays are divided into **cells** that can store data and be accessed using a unique identifier representing its **address** or position relative to the memory array. Information in memory cells is stored using binary digits (bits), usually organized in bytes (8-bits); it can also be retrieved later by the MCU or other components of a microcontroller-based system. + +Memory in computing systems can be **volatile** or **non-volatile**. **Volatile memory is a temporary memory**, this means that data is stored while the system is running, but it is lost forever when the system is turned off. **Non-volatile memory is permanent memory**; data is not lost even if the system is turned off. ## Memory Architectures 101 -**NEEDS REVISION** +Computer architecture is a vast topic; we will focus on a general picture that will let us understand how memory is organized in the microcontrollers used in Arduino® boards. + +In the early days of computing, two computer architectures, i.e., the organization of the components inside a computing system, emerged: **von Neumann** and **Harvard**. + +### Von Neumann Architecture + +The von Neumann architecture, named after the mathematician, physicist, and computer scientist John von Neumann, was first introduced in the mid-'40s; it is also known as the Princeton architecture. This architecture stores program data and instructions in the same memory unit; both are accessed by the CPU using the same communications bus, as shown below. Von Neumann's architecture is fundamental since nearly all digital computers design have been based on this architecture. -The name Harvard Architecture comes from the Harvard Mark I relay-based computer. The most obvious characteristic of the Harvard Architecture is that it has physically separate signals and storage for code and data memory. It is possible to access program memory and data memory simultaneously. Typically, code (or program) memory is read-only and data memory is read-write. Therefore, it is impossible for program contents to be modified by the program itself. +### Harvard Architecture -The von Neumann Architecture is named after the mathematician and early computer scientist John von Neumann. von Neumann machines have shared signals and memory for code and data. Thus, the program can be easily modified by itself since it is stored in read-write memory. +The Harvard architecture, named after the Harvard Mark I relay-based computer, was first introduced in the mid-'40s. This architecture's main characteristic is that it uses two separate memory units, one for storing program instructions and one for storing program data. Both memory units in the Harvard architecture are accessed by the CPU using different communication buses. ## Types of Memories @@ -57,7 +65,7 @@ Each memory type serves different role that handles the function of the AVR arch ​ #### Program Memory ​ -The Program Memory is the reprogrammable memory found on the system. This is the Flash memory that serves as a storage, and the memory divides into two different section due to security measure. A Boot-loader section is where all the crucial code is stored to intialize peripherals and essential components. While the application section is where the composed code is uploaded. +The Program Memory is the reprogrammable memory found on the system. This is the Flash memory that serves as a storage, and the memory divides into two different section due to security measure. A Boot-loader section is where all the crucial code is stored to initialize peripherals and essential components. While the application section is where the composed code is uploaded. ​ #### EEPROM Memory ​ @@ -65,7 +73,7 @@ This type of memory is Read-Only memory that is electrically eraseable and repro ​ #### SRAM Memory ​ -The Static Random Access Memory is accessed via standard data bus, and the data is retained while it has power feed. This data memory stores different memory units that are from registers, Input/Ouput memory, and its internal SRAM. All this is to have general purpose 8-Bit registers, control registers to address peripheral components, and volatile storage location to temporarily manage the data generated from the code. +The Static Random Access Memory is accessed via standard data bus, and the data is retained while it has power feed. This data memory stores different memory units that are from registers, Input/Output memory, and its internal SRAM. All this is to have general purpose 8-Bit registers, control registers to address peripheral components, and volatile storage location to temporarily manage the data generated from the code. ​ ### ARM-based Boards ​ @@ -309,7 +317,7 @@ Notice that with boards that do not have a lot of SRAM available, like the UNO. char message[] = "I support the Cape Wind project."; ``` -puts 33 bytes into SRAM (each character takes a byte, plus the '\0' terminator). This might not seem like a lot, but it doesn't take long to get to 2048, especially if you have a large amount of text to send to a display, or a large lookup table, for example. +puts 33 bytes into SRAM (each character ta|kes a byte, plus the '\0' terminator). This might not seem like a lot, but it doesn't take long to get to 2048, especially if you have a large amount of text to send to a display, or a large lookup table, for example. If you run out of SRAM, your program may fail in unexpected ways; it will appear to upload successfully, but not run, or run strangely. To check if this is happening, you can try commenting out or shortening the strings or other data structures in your sketch (without changing the code). If it then runs successfully, you're probably running out of SRAM. There are a few things you can do to address this problem: From 7b6f563502f466f737d645ac9e2bf4fed5a5ba1c Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Tue, 22 Mar 2022 19:11:15 -0600 Subject: [PATCH 04/36] Content Update: Extended Technical Content Add-On --- .../06.memory-guide/memory-guide.md | 170 ++++++++++++------ 1 file changed, 120 insertions(+), 50 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 7bcd92aa2f..cce3451c75 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -87,38 +87,41 @@ STAND_BY ## Measuring Memory Usage in Arduino Boards Memory usage stadistics will help you understand the resource management affected by the designed code. It is an important factor to consider, as the resources are finite. In fact, it should run without always reaching maximum load capacity. This is one stadistic that will tell you how efficient the code is designed. ​ +### SRAM & DRAM: Quick Differentiation Specification +STAND_BY + ### Flash Memory Measurement -​ + The Flash memory on Arduino boards can be measured with the help of the Arduino IDE. As the Flash memory is where the Application code will be stored, the Arduino IDE will report through output log to let the developer know how much resource is being used. -​ + This is the output log format for Arduino Nano. -​ + ![Flash Memory Usage - Arduino Nano [AVR]](assets/avr_nano.png) -​ + This is the output log format for Arduino MKR WAN 1310. -​ + ![Flash Memory Usage - Arduino MKR WAN 1310 [ARM]](assets/arm_mkrwan1310.png) -​ + This is the output log format for Arduino Portenta H7. -​ + ![Flash Memory Usage - Arduino Portenta H7 (ABX00042) [ARM]](assets/arm_portentah7.png) -​ + Each image of Arduino IDE is based of three different Arduino boards, one based on AVR and the other two based of ARM architecture. The compiler will output a log where how much Flash resource is used when uploading the code. -​ + The purpose of three images for different boards is to how that for each Arduino board family, the output log format is little different from one another; but it will show you the required information regarding the code that is to be uploaded to the board. -​ + ***If it is required to handle the Flash memory within the code, please read more about in [this](https://docs.arduino.cc/tutorials/portenta-h7-lite/por-ard-flash) using Arduino Portenta H7*** -​ + ### SRAM Memory Measurement -​ + The code may upload and run. However, there may be situations in which the program will suffer from sudden operation halt. Moments like this can be due to memory resource hogging. To solve this, it will require to understand in which sector of the code, the memory demand is going beyond the available resources. Following code fragment will help you measure the SRAM usage while the code is running. -​ + ```cpp void display_freeram(){ Serial.print(F("SRAM left")); Serial.println(freeRam()); } -​ + int freeRam() { extern int __heap_start,*__brkval; int v; @@ -126,73 +129,140 @@ int freeRam() { ? (int)&__heap_start : (int) __brkval); } ``` -​ + In the code, `__heap_start` and `__brkval` are as following: - **`__heap_start`**: Refers to beginning of the Heap. - **`__brkval`**: Last memory address pointer used by Heap. It is pointing towards the Stack. -​ + ### EEPROM Memory Measurement -​ + To be able to use EEPROM features, it is already included with the Arduino IDE platform so it does not require additional step to install any library. -​ + EEPROM memory measurement can be done through use of the following simple code fragment. The code is simplified to write a byte to know exactly which address it is reading from. It can be modified to read everything from every possible address. -​ + ```cpp #include -​ + EEPROM.write(address, value); EEPROM.read(address); ``` -​ + On the other hand, it is possible to clear the entire EEPROM memory to set it to 0. -​ + ```cpp #include -​ + ... -​ + for (int i = 0 ; i < EEPROM.length() ; i++) { EEPROM.write(i, 0); } -​ + ... ``` -​ + The complete example codes can be found in our guide to EEPROM found below the following code. -​ + ***For more information on how to manage the EEPROM memory, please read [here](https://docs.arduino.cc/learn/programming/eeprom-guide)*** -​ + ## Optimizing Memory Usage in Arduino-based Systems To know how the code utilizes the memory resources is one matter, but to optimize the memory is a whole different task. As the term development may infer, the requirements may change or be adjusted depending on external factors such as reduced device capacity due to inavailability of the components. Thus the code architecture may require optimization to be able to run on the reduced limited memory resources. -​ + The optimization process also implies reduced computational complexities, trimming down extra time required to process the tasks. The memory optimization process may help the overall optimization process, as it will handle how the memory is managed in a more suitable manner. -​ + ### Flash Memory Optimization -​ + One of the memory sources to begin optimization with is the Flash memory. As the Flash memory is where the size itself of the code can be reduced greatly by considering some details. -​ -1. Detach Unused Sources + +1. **Detach Unused Sources** Detaching unused sources include unused libraries, and code residues. Code residues can be composed of functions that are no longer used and floating variables that takes up the unnecessary space in memory. This will vastly improve the compiled code size and make more clear compilation process. -​ -2. Modular Tasks + +2. **Modular Tasks** Modular tasks mean functions that wraps the code which will be used in a repetitive or continuous manner by receiving different parameters. It is a great way to maintain clean code structure and performance, while reducing the memory space required for additional tasks that might need to be implemented. -​ + This leads to compact code structure, that is much easier to understand when debugging process is required, and demand developer to considerate compute complexity while designing the code structure. -​ + ### SRAM Memory Optimization -​ -1. Literal String Reduction - F() -​ -2. PROGMEM -​ -3. RESERVE() -​ -4. Buffer Size Control -​ -5. Non Dynamic Memory Allocation -Dynamic allocations cause Heap fragmentation. Although, when dynamic allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the Heap Size. -​ -6. Corrective Data Type Usage + +1. **String Wrapper - F()** +It is convenient to use `Serial.println("Something");` to display the literals. This is used usally to understand where the code is going and to observe certain conditionals. However, doing this so will hog up the Static Random Access Memory (SRAM) space, which is something not desirable as the content is a simple literal string that is not used under the hood. + +The ideal way to use the Print Line command is to use the `F()` String Wrapper around the literals. This will lead us to following piece of code. + +```cpp +Serial.println(F("Something")); +``` + +By wrapping the String with `F()`, will move the Strings to Flash memory only rather than to use SRAM space also. It can be observed as offloading such data to Flash memory instead of SRAM. + +Flash memory is much more spacious than SRAM size, so it is possible to use the Flash space than using SRAM which will use Heap. This does not mean, the memory space will always be available as Flash memory does too have limited space. It is not recommendable to spam the code structure with Print Line, but to use them where they most matter for such applications with minimized implementation. + +2. **PROGMEM** +It is not always with the literal String that occupies the SRAM space, but also using Global Variables which also takes up quite good amount of SRAM. As Global and Static variables are streamed to SRAM space, and pushes the Heap towards the Stack. The space occupied by this variables streamed to SRAM space will be saved at its location and will not be changing, meaning more of these variables are created, they will use more space and consequently, system failure due to low and poor memory management. + +PROGMEM stands simply for Program Memory. We will use Program memory to store variable data offloading to Flash Memory space. As it goes same as to String Wrapper F(), PROGMEM uses Flash Memory space for its usage. The only disadvantage presented using PROGMEM is the Read Speed. Using RAM will provide much faster Read Speed, but PROGMEM, as it uses Flash Memory, it will be slower than RAM, given the same data size read. Thus, it is important to design the software knowing which variables are crucial and others has lower priority. It is one of the many factors that needs to be considered when developing the software, but this will lead to have nicely designed code architecture. + +To use the PROGMEM, it can begin with following code fragment. + +```cpp +#include + +// Basic PROGMEM Define Structure +const PROGMEM DataType Variable_Name[] = {var0, var1, var2 ...}; + +// Unsigned 16 Bit int +const PROGMEM uint16_t NumSet[] = {0, 1, 1, 2, 3, 5, 8 ...}; + +// Storing Char +const char greetMessage[] PROGMEM = {"Hello There"}; +``` + +***For In-Depth detail about PROGMEM, please read [here](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/)*** + +3. **RESERVE()** +STAND_BY + +4. **Buffer Size Control** +STAND_BY + +5. **Non Dynamic Memory Allocation** +Dynamic Memory Allocation usually is a good method if the given RAM size is big enough to get around with, from MegaBytes and so on. However, for embedded devices counting every Byte of the RAM, the process becomes hostile for RAM. + +Dynamic Memory Allocations cause Heap fragmentation. With heap fragmentation, many areas of the RAM affected by it cannot reused again, leaving dead Byte that can be taken as an advantage for other tasks. On top of it, when dynamic allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the Heap Size. So to avoid Heap or RAM fragmentation as much as possible, you can follow following rules to apply into code architecture design. + +- Prioritize using **Stack** than **Heap** if possible to do so. + - Stack memory is fragmentation free and can be freed up completely when the function returns. Heap in contrast ma not free up the space even though it was instructed to do so. Using Local Variables will help to do this and try not to use dynamic memory allocation, composed of different calls: `malloc, calloc, realloc`. + +- Reduced Global and Static Data if possible to do so. + - Meantime the code is running, memory area occupied by these data will not be freed up. Meaning the data won't be modified as it is constant data taking up the precious space. + +- Short Strings / Literals + - It is good practice to keep the literal Strings as short as possible. Single char takes **One** Byte of RAM, so shorter the better memory space usage. This does not mean, keeping it short and using it in several different areas of the code is possible. Use it when it is absolutely required and keep as short as possible to spare RAM space for other task functions. + + Arrays are also recommended to be at a minimum size. If it requires to resize the array, you can always re-set the array size in the code. + +6. **Corrective Data Type Usage** +Implementation of adequate data type leads to a good overall code architecture. It may be desirable for the developer to use easiest or the most accessible data type to handle the data stream. However, it is important to consider the amount of memory space that it takes up when using certain data types. + +The Data Types exist to ease data stream format and to be handled without making illegal access. The illegal access in terms of data types are meant when the data is handled in the code with incompatible format. So it is a good practice to not to abuse the the data type and use only convenient types for every data bits. Rather, design and allocate memory carefully according to the requirements, which will help to reserve some memory space if further designed tasks needs extra space. + +Following table shows some of the existing data types to opt out for more options. + +| Data Type | Byte Size | Range | Format Specifier | +| :--------------------: | :---------: | :-----------------------------------: | :-----------------: | +| **char, signed char** | 1 | -128 ~ 127 | %c | +| **unsigned char** | 1 | 0 ~ 255 | %c | +| **int, signed int** | 2 , 4 | -32,768 ~ 32,767 | %d, %i | +| **unsigned int** | 2 , 4 | 0 ~ 65,535 | %u | +| **signed short int** | 2 | -32,768 ~ 32,767 | %hd | +| **unsigned short int** | 2 | 0 ~ 65,535 | %hu | +| **long int** | 4 | -2,147,483,648 ~ 2,147,483,647 | %ld, %li | +| **long long int** | 8 | -(2^63-1) ~ 2^63-1 (C99 Standard) | %lld, %lli | +| **unsigned long int** | 4 | 0 to 4,294,967,295 | %lu | +| **unsigned long long int** | 8 | 2^64-1 (C99 standard) | %llu | +| **float** | 4 | 1E-37 ~ 1E+37 + 6 Digit Precision | %f | +| **double** | 8 | 1E-37 ~ 1E+37 + 10 Digit Precision | %lf | +| **long double** | 10 | 1E-37 ~ 1E+37 + 10 Digit Precision | %Lf | ​ ### EEPROM Memory Optimization From 9b5082dab40f99a96d77d7d1ab1e24d8b049b266 Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Tue, 22 Mar 2022 19:14:57 -0600 Subject: [PATCH 05/36] Typo Fix - Previous Commit --- content/learn/03.programming/06.memory-guide/memory-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index cce3451c75..fd927f3487 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -185,7 +185,7 @@ This leads to compact code structure, that is much easier to understand when deb ### SRAM Memory Optimization 1. **String Wrapper - F()** -It is convenient to use `Serial.println("Something");` to display the literals. This is used usally to understand where the code is going and to observe certain conditionals. However, doing this so will hog up the Static Random Access Memory (SRAM) space, which is something not desirable as the content is a simple literal string that is not used under the hood. +It is convenient to use `Serial.println("Something");` to display the literals. This is used usually to understand where the code is going and to observe certain conditionals. However, doing this so will hog up the Static Random Access Memory (SRAM) space, which is something not desirable as the content is a simple literal string that is not used under the hood. The ideal way to use the Print Line command is to use the `F()` String Wrapper around the literals. This will lead us to following piece of code. From 74cc1850253b2301ee7bb6ffd29eb2b7e42031b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Wed, 23 Mar 2022 09:56:36 -0600 Subject: [PATCH 06/36] Update Memory Architectures 101 section --- .../06.memory-guide/memory-guide.md | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index fd927f3487..cca33424fb 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -30,11 +30,48 @@ In the early days of computing, two computer architectures, i.e., the organizati ### Von Neumann Architecture -The von Neumann architecture, named after the mathematician, physicist, and computer scientist John von Neumann, was first introduced in the mid-'40s; it is also known as the Princeton architecture. This architecture stores program data and instructions in the same memory unit; both are accessed by the CPU using the same communications bus, as shown below. Von Neumann's architecture is fundamental since nearly all digital computers design have been based on this architecture. +The von Neumann architecture, named after the mathematician, physicist, and computer scientist John von Neumann, was first introduced in the mid-'40s; it is also known as the Princeton architecture. T**his architecture stores program data and instructions in the same memory unit**; **both are accessed by the CPU using the same communications bus**, as shown below. Von Neumann's architecture is fundamental since nearly all digital computers design have been based on this architecture. ### Harvard Architecture -The Harvard architecture, named after the Harvard Mark I relay-based computer, was first introduced in the mid-'40s. This architecture's main characteristic is that it uses two separate memory units, one for storing program instructions and one for storing program data. Both memory units in the Harvard architecture are accessed by the CPU using different communication buses. +The Harvard architecture, named after the Harvard Mark I relay-based computer, was first introduced in the mid-'40s. **This architecture's main characteristic is that it uses two separate memory units**, **one for storing program instructions and one for storing program data**. Both memory units in the Harvard architecture are accessed by the CPU using different communication buses. + +### Modern Architectures: Hybrids + +Modern computing systems use **hybrid architectures** models that maximize performance using the best of both worlds, the von Neumann and the Harvard models. + +Microcontrollers are usually used in embedded applications. They must perform defined tasks reliably and efficiently, with low or constrained resources; this is why the **Harvard architecture model is mainly used in microcontrollers**: microcontrollers have a small program and data memory that needs to be accessed simultaneously. However, Harvard architecture is not always used in microcontrollers; some microcontroller families use hybrid or Von Neumann architecture models. + +### Arduino® Boards Architectures + +Arduino® boards are mainly based on two families of microcontrollers: **AVR®** and **ARM®**. While AVR® family microcontrollers are based on the Harvard architecture model, ARM® family microcontrollers can be based on either von Neuman or Harvard architectures models. The following table summarizes Arduino boards microcontrollers architectures: + +**Board**|**Microcontroller**|**Family**|**Architecture** +:-----:|:-----:|:-----:|:-----: +UNO Mini|ATmega328P|AVR|Harvard +UNO Rev3|ATmega328P|AVR|Harvard +UNO WiFi Rev2|ATmega4809|AVR|Harvard +UNO Rev3 SMD|ATmega328P|AVR|Harvard +Leonardo|ATmega32u4|AVR|Harvard +Mega 2560 Rev3|ATmega2560|AVR|Harvard +Micro|ATmega32u4|AVR|Harvard +Zero|ATSAMD21G18|ARM Cortex M0+|Von Neumann +Portenta H7|STM32H747|ARM Cortex M4/M7|Harvard +Nicla Sense ME|nRF52832|ARM Cortex M4|Harvard +Nano RP2040 Connect|RP2040|ARM Cortex M0+|Von Neumann +MKR FOX 1200|ATSAMD21G18|ARM Cortex M0+|Von Neumann +MKR NB 1500|ATSAMD21G18|ARM Cortex M0+|Von Neumann +MKR Vidor 4000|ATSAMD21G18|ARM Cortex M0+|Von Neumann +MKR WiFi 1010|ATSAMD21G18|ARM Cortex M0+|Von Neumann +MKR Zero|ATSAMD21G18|ARM Cortex M0+|Von Neumann +MKR1000 WIFI|ATSAMW25H18|ARM Cortex M0+|Von Neumann +MKR WAN 1300|ATSAMD21G18|ARM Cortex M0+|Von Neumann +MKR WAN 1310|ATSAMD21G18|ARM Cortex M0+|Von Neumann +Nano|ATmega328P|AVR|Harvard +Nano Every|ATmega4809|AVR|Harvard +Nano 33 IoT|ATSAMD21G18|ARM Cortex M0+|Von Neumann +Nano 33 BLE|nRF52840|ARM Cortex M4|Harvard +Nano 33 BLE Sense|nRF52840|ARM Cortex M4|Harvard ## Types of Memories From b0c48c5fd9ec33e5c0cc4d69432088bece738d28 Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Wed, 23 Mar 2022 18:52:36 -0600 Subject: [PATCH 07/36] Content Update: Extended Technical Info Add-On --- .../06.memory-guide/memory-guide.md | 62 ++++++++++++++----- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index cca33424fb..4837715285 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -119,13 +119,25 @@ ARM architecture implements **Memory Organization** or **Memory Map**, built dep The **Translation Tables** are injected by virtual addresses, composed of Kernel and application in blocks of data and code; then translated into physical addresses composed by peripherals, Flash, SRAM, and ROM. The present architecture uses its Memory Map, predefined accordingly depending on the ARM chip family, to ease the access. ​ ## Heap & Stack -STAND_BY +It is good to know a little bit about what is **Heap** and **Stack** when we discuss about Random Access Memory (RAM), as it will be mentioned sometimes to explain its behaviour. + +- Heap: Dynamic memory sector, in which if the new allocation is made, it can grow; but also reduce in size with some possibility depending on the requirement. It is where `malloc` is found. + +- Stack: This memory sector is used for functions calls and local variable storage. When the function finishes the job, the local variables that wad holding the memory pool is freed up. The memory sector will grow towards the Heap, and it is positioned at the end of the RAM, at the side of External RAM. ​ ## Measuring Memory Usage in Arduino Boards Memory usage stadistics will help you understand the resource management affected by the designed code. It is an important factor to consider, as the resources are finite. In fact, it should run without always reaching maximum load capacity. This is one stadistic that will tell you how efficient the code is designed. ​ ### SRAM & DRAM: Quick Differentiation Specification -STAND_BY +Embedded devices has **Static Random Access Memory (SRAM)** and **Dynamic Random Access Memory (DRAM)**. These are 2 different derivatives that forms Random Access Memory (RAM) inside the embedded devices. Both RAM types hass trade-off in between them, and it is based on speed, physical size and cost. + +- SRAM is much faster than DRAM has to propose. In Read, Write and Access speed. +- SRAM is mucho more expensive in terms of manufacturing cost than DRAM. +- DRAM offers more friendly physical size than SRAM. + +While these are 2 types of RAM that exists for embedded devices, optimization process that will be stated in the following are applicable as a whole. No matter which type of RAM is on-board, it can be managed efficiently with careful design factors in mind. + +Ultimately, it should not be abused whatsoever, because even if the code might run, the device may have a lot of holes to be filled and fixed to run in a stable manner. And the fix or patch that has to be applied later, might cost entire code architecture re-design. ### Flash Memory Measurement @@ -211,17 +223,17 @@ The optimization process also implies reduced computational complexities, trimmi One of the memory sources to begin optimization with is the Flash memory. As the Flash memory is where the size itself of the code can be reduced greatly by considering some details. -1. **Detach Unused Sources** +#### Detach Unused Sources Detaching unused sources include unused libraries, and code residues. Code residues can be composed of functions that are no longer used and floating variables that takes up the unnecessary space in memory. This will vastly improve the compiled code size and make more clear compilation process. -2. **Modular Tasks** +#### Modular Tasks Modular tasks mean functions that wraps the code which will be used in a repetitive or continuous manner by receiving different parameters. It is a great way to maintain clean code structure and performance, while reducing the memory space required for additional tasks that might need to be implemented. This leads to compact code structure, that is much easier to understand when debugging process is required, and demand developer to considerate compute complexity while designing the code structure. ### SRAM Memory Optimization -1. **String Wrapper - F()** +#### String Wrapper - F() It is convenient to use `Serial.println("Something");` to display the literals. This is used usually to understand where the code is going and to observe certain conditionals. However, doing this so will hog up the Static Random Access Memory (SRAM) space, which is something not desirable as the content is a simple literal string that is not used under the hood. The ideal way to use the Print Line command is to use the `F()` String Wrapper around the literals. This will lead us to following piece of code. @@ -234,7 +246,7 @@ By wrapping the String with `F()`, will move the Strings to Flash memory only ra Flash memory is much more spacious than SRAM size, so it is possible to use the Flash space than using SRAM which will use Heap. This does not mean, the memory space will always be available as Flash memory does too have limited space. It is not recommendable to spam the code structure with Print Line, but to use them where they most matter for such applications with minimized implementation. -2. **PROGMEM** +#### PROGMEM It is not always with the literal String that occupies the SRAM space, but also using Global Variables which also takes up quite good amount of SRAM. As Global and Static variables are streamed to SRAM space, and pushes the Heap towards the Stack. The space occupied by this variables streamed to SRAM space will be saved at its location and will not be changing, meaning more of these variables are created, they will use more space and consequently, system failure due to low and poor memory management. PROGMEM stands simply for Program Memory. We will use Program memory to store variable data offloading to Flash Memory space. As it goes same as to String Wrapper F(), PROGMEM uses Flash Memory space for its usage. The only disadvantage presented using PROGMEM is the Read Speed. Using RAM will provide much faster Read Speed, but PROGMEM, as it uses Flash Memory, it will be slower than RAM, given the same data size read. Thus, it is important to design the software knowing which variables are crucial and others has lower priority. It is one of the many factors that needs to be considered when developing the software, but this will lead to have nicely designed code architecture. @@ -256,13 +268,7 @@ const char greetMessage[] PROGMEM = {"Hello There"}; ***For In-Depth detail about PROGMEM, please read [here](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/)*** -3. **RESERVE()** -STAND_BY - -4. **Buffer Size Control** -STAND_BY - -5. **Non Dynamic Memory Allocation** +#### Non Dynamic Memory Allocation Dynamic Memory Allocation usually is a good method if the given RAM size is big enough to get around with, from MegaBytes and so on. However, for embedded devices counting every Byte of the RAM, the process becomes hostile for RAM. Dynamic Memory Allocations cause Heap fragmentation. With heap fragmentation, many areas of the RAM affected by it cannot reused again, leaving dead Byte that can be taken as an advantage for other tasks. On top of it, when dynamic allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the Heap Size. So to avoid Heap or RAM fragmentation as much as possible, you can follow following rules to apply into code architecture design. @@ -276,9 +282,35 @@ Dynamic Memory Allocations cause Heap fragmentation. With heap fragmentation, ma - Short Strings / Literals - It is good practice to keep the literal Strings as short as possible. Single char takes **One** Byte of RAM, so shorter the better memory space usage. This does not mean, keeping it short and using it in several different areas of the code is possible. Use it when it is absolutely required and keep as short as possible to spare RAM space for other task functions. - Arrays are also recommended to be at a minimum size. If it requires to resize the array, you can always re-set the array size in the code. + - Arrays are also recommended to be at a minimum size. If it requires to resize the array, you can always re-set the array size in the code. It may be a tedious, also non-efficient method to hard-code the array sizes. But if the code utilizes small array sizes and less than 3 arrays, it may be suffice via manual resizing, knowing the requirements. A smart way to do this is resizeable array with limited size. In which the tasks will use the array without going over the size boundary, thus it is suitable for extensive code size. Although, the limit of the array size must be analyzed and kept as small as possible. + +#### RESERVE() +If the tasks work with the Strings, that changes in its size depending on the operation outcome, `RESERVE()` is way to go. This function will help to reserve buffer space and pre-allocate for String variable, which changes in its size, and avoid fragmentation. String variable that changes in its size could be a result of `int` type variable wrapped to be used as a `String` for example. + +To use the `RESERVE()` function, it is possible to begin usage with following code piece. + +```cpp +// String_Variable is variable of String type +// Alloc_Size is memory to be pre-allocated in number of Bytes with unsigned int type +String_Variable.reserve(Alloc_Size); +``` + +***For more information about the `RESERVE()` function, please check out [here](https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/reserve/)*** + +#### Buffer Size Control +Backend processes also requires memory pool for its processing purpose. It is something in which the machine will work on according to the size of the memory pool defined. This Buffer size can be user defined, meaning it can be can reduced to allocate lower memory size. It is similar to defining Array size, in which it is important not to allocate excessive size when it will use only third portion of the defined size. + +In between backend services, Serial communication defines the needed memory pool as Serial Buffer Size. Bigger serial buffer assists in establishing high speed communication, relative to the device that is interchanging data stream. If high speed communication is not part of the requiremente, the buffer size can be redefined to save some memory consumption. This is possible to do so by modifying the `HardwareSerial.h` that comes with Arduino IDE compiler, searching the following line. + +```cpp +#define SERIAL_TX_BUFFER_SIZE 64 + +#define SERIAL_RX_BUFFER_SIZE 64 +``` + +Libraries, or external modules that involve in code architecture development, also uses Buffer pool for better computing performance. Although, depending on the requirement, smooth performance might be cherry on top for the code architecture that is being developed. It is feasible to modify the buffer size that is designated in the library code. -6. **Corrective Data Type Usage** +#### Corrective Data Type Usage Implementation of adequate data type leads to a good overall code architecture. It may be desirable for the developer to use easiest or the most accessible data type to handle the data stream. However, it is important to consider the amount of memory space that it takes up when using certain data types. The Data Types exist to ease data stream format and to be handled without making illegal access. The illegal access in terms of data types are meant when the data is handled in the code with incompatible format. So it is a good practice to not to abuse the the data type and use only convenient types for every data bits. Rather, design and allocate memory carefully according to the requirements, which will help to reserve some memory space if further designed tasks needs extra space. From 890aea6a7e773983bfa47e82b8e4e83023ca8e2b Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Wed, 23 Mar 2022 21:59:46 -0600 Subject: [PATCH 08/36] Typo Fix - Based Previous Commit --- content/learn/03.programming/06.memory-guide/memory-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 4837715285..6e999af1ed 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -129,7 +129,7 @@ It is good to know a little bit about what is **Heap** and **Stack** when we dis Memory usage stadistics will help you understand the resource management affected by the designed code. It is an important factor to consider, as the resources are finite. In fact, it should run without always reaching maximum load capacity. This is one stadistic that will tell you how efficient the code is designed. ​ ### SRAM & DRAM: Quick Differentiation Specification -Embedded devices has **Static Random Access Memory (SRAM)** and **Dynamic Random Access Memory (DRAM)**. These are 2 different derivatives that forms Random Access Memory (RAM) inside the embedded devices. Both RAM types hass trade-off in between them, and it is based on speed, physical size and cost. +Embedded devices has **Static Random Access Memory (SRAM)** and **Dynamic Random Access Memory (DRAM)**. These are 2 different derivatives that forms Random Access Memory (RAM) inside the embedded devices. Both RAM types has trade-off in between them, and it is based on speed, physical size and cost. - SRAM is much faster than DRAM has to propose. In Read, Write and Access speed. - SRAM is mucho more expensive in terms of manufacturing cost than DRAM. From 3ba541e8883e1e6402ceb91ed187a7a048ea4e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Sat, 26 Mar 2022 16:34:23 -0500 Subject: [PATCH 09/36] Update boards architectures section --- .../06.memory-guide/memory-guide.md | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 6e999af1ed..54a661ef30 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -46,33 +46,32 @@ Microcontrollers are usually used in embedded applications. They must perform de Arduino® boards are mainly based on two families of microcontrollers: **AVR®** and **ARM®**. While AVR® family microcontrollers are based on the Harvard architecture model, ARM® family microcontrollers can be based on either von Neuman or Harvard architectures models. The following table summarizes Arduino boards microcontrollers architectures: -**Board**|**Microcontroller**|**Family**|**Architecture** -:-----:|:-----:|:-----:|:-----: -UNO Mini|ATmega328P|AVR|Harvard -UNO Rev3|ATmega328P|AVR|Harvard -UNO WiFi Rev2|ATmega4809|AVR|Harvard -UNO Rev3 SMD|ATmega328P|AVR|Harvard -Leonardo|ATmega32u4|AVR|Harvard -Mega 2560 Rev3|ATmega2560|AVR|Harvard -Micro|ATmega32u4|AVR|Harvard -Zero|ATSAMD21G18|ARM Cortex M0+|Von Neumann -Portenta H7|STM32H747|ARM Cortex M4/M7|Harvard -Nicla Sense ME|nRF52832|ARM Cortex M4|Harvard -Nano RP2040 Connect|RP2040|ARM Cortex M0+|Von Neumann -MKR FOX 1200|ATSAMD21G18|ARM Cortex M0+|Von Neumann -MKR NB 1500|ATSAMD21G18|ARM Cortex M0+|Von Neumann -MKR Vidor 4000|ATSAMD21G18|ARM Cortex M0+|Von Neumann -MKR WiFi 1010|ATSAMD21G18|ARM Cortex M0+|Von Neumann -MKR Zero|ATSAMD21G18|ARM Cortex M0+|Von Neumann -MKR1000 WIFI|ATSAMW25H18|ARM Cortex M0+|Von Neumann -MKR WAN 1300|ATSAMD21G18|ARM Cortex M0+|Von Neumann -MKR WAN 1310|ATSAMD21G18|ARM Cortex M0+|Von Neumann -Nano|ATmega328P|AVR|Harvard -Nano Every|ATmega4809|AVR|Harvard -Nano 33 IoT|ATSAMD21G18|ARM Cortex M0+|Von Neumann -Nano 33 BLE|nRF52840|ARM Cortex M4|Harvard -Nano 33 BLE Sense|nRF52840|ARM Cortex M4|Harvard - +| **Board** | **Microcontroller** | **Family** | **Architecture** | +|:-------------------:|:-------------------:|:----------------:|:----------------:| +| UNO Mini | ATmega328P | AVR | Harvard | +| UNO Rev3 | ATmega328P | AVR | Harvard | +| UNO WiFi Rev2 | ATmega4809 | AVR | Harvard | +| UNO Rev3 SMD | ATmega328P | AVR | Harvard | +| Leonardo | ATmega32u4 | AVR | Harvard | +| Mega 2560 Rev3 | ATmega2560 | AVR | Harvard | +| Micro | ATmega32u4 | AVR | Harvard | +| Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| Portenta H7 | STM32H747 | ARM Cortex M4/M7 | Harvard | +| Nicla Sense ME | nRF52832 | ARM Cortex M4 | Harvard | +| Nano RP2040 Connect | RP2040 | ARM Cortex M0+ | Von Neumann | +| MKR FOX 1200 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| MKR NB 1500 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| MKR Vidor 4000 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| MKR WiFi 1010 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| MKR Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| MKR1000 WIFI | ATSAMW25H18 | ARM Cortex M0+ | Von Neumann | +| MKR WAN 1300 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| MKR WAN 1310 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| Nano | ATmega328P | AVR | Harvard | +| Nano Every | ATmega4809 | AVR | Harvard | +| Nano 33 IoT | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| Nano 33 BLE | nRF52840 | ARM Cortex M4 | Harvard | +| Nano 33 BLE Sense | nRF52840 | ARM Cortex M4 | Harvard | ## Types of Memories There are three potential pools of memory in the microcontrollers used on Arduino boards: From 140acdfaa0b1e19725d519624ba68cbaa7f49387 Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Mon, 28 Mar 2022 16:55:58 -0600 Subject: [PATCH 10/36] Content Update: Technical EEPROM Information & Reference Support --- .../03.programming/06.memory-guide/memory-guide.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 6e999af1ed..7d86372d8b 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -335,7 +335,19 @@ Following table shows some of the existing data types to opt out for more option ​ ### EEPROM Memory Optimization -TDB! +EEPROM memory optimization usually is not required, as it will be used mainly to store external module tuning constant. The data which are to be used by EEPROM space are the ones does not really need Flash memory as storage source. On top of it, it is not a good practice to offload SRAM data on EEPROM space. SRAM data are placed within volatility in mind, so offloading to EERPOM space, which is non-volatile memory, will mean the offloaded data will be engraved into EEPROM space. As result, the it is impractical use of storage and the variable will change in its value, making the old data unuseable. + +One thing to consider with EEPROM is the read and write operation cycles. With EEPROM, it is crucial to know that write operation is limited. The read operation is unlimited for EEPROM. However, the write operation is finite and capped to 100,000 cycles of operation usually. Thus, it is important to save only parameters that are absolutely important for sensors or modules to work with mostly unchanging data. Additionally avoid implementing in a loop code, to avoid constant write operation, as it will wipe out, most likely in instant. + +### EEPROM Emulation with Flash Memory. + +As EEPROM is limited with write operatin cycle, it also applies same to Flash memory. Both of them are subjected to loss of data retention after the manufacturer's defined life cycle. EEPROM is based of NOR type memory, while the Flash memory is NAND type, making the EEPROM more costly than Flash memory. EEPROM works by accessing the data byte-wise, whereas Flash memory accesses block by block. + +Sometimes the developer would have to use the EEPROM as an alternative storage for task operations, but we clearly know that it will be impractical coding due to its size and behaviour properties. To solve this, it is possible to use Flash memory to emulate the EEPROM. Thanks to `FlashStorage` library created by Chrisitan Maglie, it is possible to emulate the EEPROM by using Flash memory. + +***`FlashStorage` library by Christian Maglie can be accessed by [here](https://github.com/cmaglie/FlashStorage)*** + +Above library will help you to use the Flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As it is for EEPROM, te Flash memory is also limited in write operation cycle. With two new additional functions stated in the library, one of them being `EEPROM.commit()` should not be called inside a loop function. Otherwise, it will wipe out the Flash memory's write operation cycles, thus loss of data retention ability. ## Memory on Arduino Nano boards From 2d52aa0a331774366f747b4235399dd6a53b6d04 Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Mon, 28 Mar 2022 17:00:26 -0600 Subject: [PATCH 11/36] Based on Previous Commit: Typo Fix --- content/learn/03.programming/06.memory-guide/memory-guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 7d86372d8b..a4fb6b0c64 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -335,7 +335,7 @@ Following table shows some of the existing data types to opt out for more option ​ ### EEPROM Memory Optimization -EEPROM memory optimization usually is not required, as it will be used mainly to store external module tuning constant. The data which are to be used by EEPROM space are the ones does not really need Flash memory as storage source. On top of it, it is not a good practice to offload SRAM data on EEPROM space. SRAM data are placed within volatility in mind, so offloading to EERPOM space, which is non-volatile memory, will mean the offloaded data will be engraved into EEPROM space. As result, the it is impractical use of storage and the variable will change in its value, making the old data unuseable. +EEPROM memory optimization usually is not required, as it will be used mainly to store external module tuning constant. The data which are to be used by EEPROM space are the ones does not really need Flash memory as storage source. On top of it, it is not a good practice to offload SRAM data on EEPROM space. SRAM data are placed within volatility in mind, so offloading to EERPOM space, which is non-volatile memory, will mean the offloaded data will be engraved into EEPROM space. As result, the it is impractical use of storage and the variable will change in its value, making the old data unusable. One thing to consider with EEPROM is the read and write operation cycles. With EEPROM, it is crucial to know that write operation is limited. The read operation is unlimited for EEPROM. However, the write operation is finite and capped to 100,000 cycles of operation usually. Thus, it is important to save only parameters that are absolutely important for sensors or modules to work with mostly unchanging data. Additionally avoid implementing in a loop code, to avoid constant write operation, as it will wipe out, most likely in instant. @@ -347,7 +347,7 @@ Sometimes the developer would have to use the EEPROM as an alternative storage f ***`FlashStorage` library by Christian Maglie can be accessed by [here](https://github.com/cmaglie/FlashStorage)*** -Above library will help you to use the Flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As it is for EEPROM, te Flash memory is also limited in write operation cycle. With two new additional functions stated in the library, one of them being `EEPROM.commit()` should not be called inside a loop function. Otherwise, it will wipe out the Flash memory's write operation cycles, thus loss of data retention ability. +Above library will help you to use the Flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As it is for EEPROM, the Flash memory is also limited in write operation cycle. With two new additional functions stated in the library, one of them being `EEPROM.commit()` should not be called inside a loop function. Otherwise, it will wipe out the Flash memory's write operation cycles, thus loss of data retention ability. ## Memory on Arduino Nano boards From 959f94c63d3c9e668896a016d05f8f166aababe6 Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Tue, 29 Mar 2022 16:24:58 -0600 Subject: [PATCH 12/36] Minor Struct Update --- .../03.programming/06.memory-guide/memory-guide.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index a4fb6b0c64..1140a6eb8e 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -349,7 +349,11 @@ Sometimes the developer would have to use the EEPROM as an alternative storage f Above library will help you to use the Flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As it is for EEPROM, the Flash memory is also limited in write operation cycle. With two new additional functions stated in the library, one of them being `EEPROM.commit()` should not be called inside a loop function. Otherwise, it will wipe out the Flash memory's write operation cycles, thus loss of data retention ability. -## Memory on Arduino Nano boards +## Memory Specification on Arduino Boards + +Memory specification of Arduino board families are briefly described within their available sizes as following. + +### Memory on Arduino Nano boards The nRF52840 ([datasheet](https://content.arduino.cc/assets/Nano_BLE_MCU-nRF52840_PS_v1.1.pdf?_gl=1*x4s7j8*_ga*Mjk5OTAxNjU5LjE2MzkyMTU1MDg.*_ga_NEXN8H46L5*MTYzOTQ5NzYzMS44LjEuMTYzOTQ5ODc4Ny4w)) chip found on the [Nano 33 BLE Sense](https://store.arduino.cc/collections/boards/products/arduino-nano-33-ble-sense) and [Nano 33 BLE](https://store.arduino.cc/collections/boards/products/arduino-nano-33-ble) has the following amounts of memory: @@ -397,7 +401,7 @@ The ATmega328 ([datasheet](http://ww1.microchip.com/downloads/en/DeviceDoc/ATmeg |EEPROM| 1kb| -## Memory on Arduino MKR boards +### Memory on Arduino MKR boards The SAMD21G18A ([datasheet](https://content.arduino.cc/assets/mkr-microchip_samd21_family_full_datasheet-ds40001882d.pdf)) chip found on the [MKR WiFi 1000](https://store.arduino.cc/collections/boards/products/arduino-mkr1000-wifi), [MKR FOX 1200](https://store.arduino.cc/collections/boards/products/arduino-mkr-fox-1200), [MKR GSM 1400](https://store.arduino.cc/collections/boards/products/arduino-mkr-gsm-1400), [MKR NB 1500](https://store.arduino.cc/collections/boards/products/arduino-mkr-nb-1500), [MKR Vidor 4000](https://store.arduino.cc/collections/boards/products/arduino-mkr-vidor-4000), [MKR WAN 1300](https://store.arduino.cc/products/arduino-mkr-wan-1300-lora-connectivity?pr_prod_strat=description&pr_rec_pid=5517873053847&pr_ref_pid=5517874233495&pr_seq=uniform), [MKR WAN 1310](https://store.arduino.cc/collections/boards/products/arduino-mkr-wan-1310), [MKR WiFi 1010](https://store.arduino.cc/collections/boards/products/arduino-mkr-wifi-1010) and [MKR Zero](https://store.arduino.cc/collections/boards/products/arduino-zero) has the following amounts of memory: @@ -407,7 +411,7 @@ The SAMD21G18A ([datasheet](https://content.arduino.cc/assets/mkr-microchip_samd |SRAM |32kb| -## Memory on Arduino Pro boards +### Memory on Arduino Pro boards The ST STM32H747XI ([datasheet](https://content.arduino.cc/assets/Arduino-Portenta-H7_Datasheet_stm32h747xi.pdf?_gl=1*14nfrmx*_ga*Mjk5OTAxNjU5LjE2MzkyMTU1MDg.*_ga_NEXN8H46L5*MTYzOTQ5NzYzMS44LjEuMTYzOTQ5OTE2NS4w)) chip found on the [Portenta H7](https://store.arduino.cc/collections/boards/products/portenta-h7), [Portenta H7 Lite](https://store.arduino.cc/collections/boards/products/portenta-h7-lite) and [Portenta H7 Lite Connected](https://store.arduino.cc/collections/boards/products/portenta-h7-lite-connected) has the following amounts of memory: @@ -417,7 +421,7 @@ The ST STM32H747XI ([datasheet](https://content.arduino.cc/assets/Arduino-Porten |SRAM |1mb| -## Memory on Arduino Classic boards +### Memory on Arduino Classic boards The ATmega328P ([datasheet](https://content.arduino.cc/assets/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf?_gl=1*if3eoe*_ga*Mjk5OTAxNjU5LjE2MzkyMTU1MDg.*_ga_NEXN8H46L5*MTYzOTQ5NzYzMS44LjEuMTYzOTQ5OTIyMS4w)) chip found on the [UNO R3](https://store.arduino.cc/collections/boards/products/arduino-uno-rev3) and [UNO Mini](https://store.arduino.cc/collections/boards/products/uno-mini-le) has the following amounts of memory: @@ -462,6 +466,7 @@ The ATmega2560 ([datasheet](https://content.arduino.cc/assets/ATmega640-1280-128 |SRAM |8kb| |EEPROM| 4kb| +## Tips & Troubleshooting Notice that with boards that do not have a lot of SRAM available, like the UNO. It's easy to use it all up by having lots of strings in your program. For example, a declaration like: ```arduino From e7b92cd7e033aed82f6ab00d0d7e530f47136cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Wed, 30 Mar 2022 00:11:19 -0400 Subject: [PATCH 13/36] Update tutorial content --- .../06.memory-guide/memory-guide.md | 181 ++++++------------ 1 file changed, 55 insertions(+), 126 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index ca54e49b29..a6b2a0e1fd 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -7,7 +7,7 @@ tags: - Flash - SRAM - EEPROM -author: 'José Bagur, Taddy Chung, Luca Osti' +author: 'José Bagur, Taddy Chung' --- A microcontroller unit (also known as MCU) is an integrated circuit (IC) typically used to perform specific applications or tasks. Usually, this type of IC gathers information or data from its surroundings, process it, and generates specific outputs according to the gathered data. Microcontrollers today are everywhere; they are an essential part of modern embedded systems that can be found practically everywhere in our world, from smartwatches to electric vehicles; they are even on the Martian surface right now. @@ -72,21 +72,62 @@ Arduino® boards are mainly based on two families of microcontrollers: **AVR®** | Nano 33 IoT | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | Nano 33 BLE | nRF52840 | ARM Cortex M4 | Harvard | | Nano 33 BLE Sense | nRF52840 | ARM Cortex M4 | Harvard | + ## Types of Memories -There are three potential pools of memory in the microcontrollers used on Arduino boards: +Now, let us talk about the different memory units present on microcontrollers. All the different memory units inside a microcontroller can be divided into two main types: **RAM** and **ROM**. RAM (from Random-Access Memory) in microcontroller-based systems is a volatile memory used to store temporary data such as the system's firmware variables. ROM (from Read-Only Memory) in microcontroller-based systems is non-volatile memory used to store permanent data such as the system's firmware. -- Flash memory (program space), is where the Arduino sketch is stored. +RAM and ROM in microcontroller-based systems are organized into three main categories: -- SRAM (static random access memory) is where the sketch creates and manipulates variables when it runs. +* Flash. +* RAM. +* EEPROM. -- EEPROM is memory space that programmers can use to store long-term information. +Let us talk more about these types of memories. -Flash memory and EEPROM memory are non-volatile (the information persists after the power is turned off). SRAM is volatile and will be lost when the power is cycled. +### Flash + +Flash memory in microcontroller-based systems is part of its ROM. The **Flash memory is where the system's firmware is stored to be executed**. For example, think of the famous `Blink.ino` example sketch, when we compile this sketch, we create a binary file that is later stored into the Flash memory of an Arduino board and executed when power on. + +### RAM + +**RAM** in microcontroller-based systems **is where the system's temporary data or run-time data is stored**. A microcontroller's RAM usually is SRAM; this is a type of RAM that uses a flip-flop to store one bit of data. For example, the variables created by functions. + +### EEPROM + +In microcontroller-based systems, Erasable Programmable Read-Only Memory, or EEPROM, is also part of its ROM; actually, Flash memory is a type of EEPROM. **The main difference between Flash memory and EEPROM is how they are managed**; EEPROM can be managed at the byte level (write or erased) while Flash can be managed at the block level. + +## Arduino® Boards Memory Allocation + +The following table summarizes Arduino® boards memory allocation: + +| **Board** | **Microcontroller** | **Family** | **Architecture** | **Flash** | **SRAM** | **EEPROM** | +|:-------------------:|:-------------------:|:----------------:|:----------------:|:---------:|:--------:|:----------:| +| UNO Mini | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | +| UNO Rev3 | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | +| UNO WiFi Rev2 | ATmega4809 | AVR | Harvard | 48kB | 6kB | 256B | +| UNO Rev3 SMD | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | +| Leonardo | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | +| Mega 2560 Rev3 | ATmega2560 | AVR | Harvard | 256kB | 8kB | 4kB | +| Micro | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | +| Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | +| Portenta H7 | STM32H747 | ARM Cortex M4/M7 | Harvard | | | | +| Nicla Sense ME | nRF52832 | ARM Cortex M4 | Harvard | | | | +| Nano RP2040 Connect | RP2040 | ARM Cortex M0+ | Von Neumann | - | 264kB | - | +| MKR FOX 1200 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | +| MKR NB 1500 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | +| MKR Vidor 4000 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | +| MKR WiFi 1010 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | +| MKR Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | +| MKR1000 WIFI | ATSAMW25H18 | ARM Cortex M0+ | Von Neumann | | | | +| MKR WAN 1300 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | +| MKR WAN 1310 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | +| Nano | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | +| Nano Every | ATmega4809 | AVR | Harvard | 48kB | 6kB | 256B | +| Nano 33 IoT | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | +| Nano 33 BLE | nRF52840 | ARM Cortex M4 | Harvard | | | | +| Nano 33 BLE Sense | nRF52840 | ARM Cortex M4 | Harvard | | | | -## Arduino Board Memory Allocation -Arduino boards processor vary by family, depending on the necessity of the user. Arduino has two big roots that can be differed by processor architecture. The boards are either powered by **AVR** or **ARM** architecture. The Arduino boards such as MKR WAN 1310, Nano 33 BLE Sense, and Portenta H7 are powered by ARM architecture using Cortex-M family. The Arduino Nano is for example powered by AVR architecture using Atmega328. -​ ### AVR-based Boards ​ AVR architecture microcontrollers has the Flash Program Memory and Static Random Access Memory @@ -107,9 +148,14 @@ The Program Memory is the reprogrammable memory found on the system. This is the ​ This type of memory is Read-Only memory that is electrically eraseable and reprogrammable. The memory module is designed usually with minimal resource available on the table. Commonly the memory is used to save small amounts of data and store even if when the device powers down. EEPROM registers are to access this memory department and during rewrite process, the memory removes everything in order to reprogram. ​ + #### SRAM Memory ​ The Static Random Access Memory is accessed via standard data bus, and the data is retained while it has power feed. This data memory stores different memory units that are from registers, Input/Output memory, and its internal SRAM. All this is to have general purpose 8-Bit registers, control registers to address peripheral components, and volatile storage location to temporarily manage the data generated from the code. + +#### EEPROM + +In microcontroller-based systems, erasable Programmable Read Only Memory, or EEPROM, is also part of its ROM; actually, Flash memory is a type of EEPROM. The main difference between Flash memory and EEPROM that EEPROM can be managed at byte-level (write or erased), while Flash can be managed at block-level. ​ ### ARM-based Boards ​ @@ -348,123 +394,6 @@ Sometimes the developer would have to use the EEPROM as an alternative storage f Above library will help you to use the Flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As it is for EEPROM, the Flash memory is also limited in write operation cycle. With two new additional functions stated in the library, one of them being `EEPROM.commit()` should not be called inside a loop function. Otherwise, it will wipe out the Flash memory's write operation cycles, thus loss of data retention ability. -## Memory Specification on Arduino Boards - -Memory specification of Arduino board families are briefly described within their available sizes as following. - -### Memory on Arduino Nano boards - -The nRF52840 ([datasheet](https://content.arduino.cc/assets/Nano_BLE_MCU-nRF52840_PS_v1.1.pdf?_gl=1*x4s7j8*_ga*Mjk5OTAxNjU5LjE2MzkyMTU1MDg.*_ga_NEXN8H46L5*MTYzOTQ5NzYzMS44LjEuMTYzOTQ5ODc4Ny4w)) chip found on the [Nano 33 BLE Sense](https://store.arduino.cc/collections/boards/products/arduino-nano-33-ble-sense) and [Nano 33 BLE](https://store.arduino.cc/collections/boards/products/arduino-nano-33-ble) has the following amounts of memory: - -|Memory Type|Size| -|--|--| -|Flash|1mb| -|SRAM |256kb| - - - -The SAMD21G18A ([datasheet](https://content.arduino.cc/assets/mkr-microchip_samd21_family_full_datasheet-ds40001882d.pdf)) chip found on the [Nano 33 IoT](https://store.arduino.cc/collections/boards/products/arduino-nano-33-iot) has the following amounts of memory: - -|Memory Type|Size| -|--|--| -|Flash|1mb| -|SRAM |256kb| - - - -The SAMD21G18A ([datasheet](https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf)) chip found on the [Nano RP2040 Connect](https://store.arduino.cc/collections/boards/products/arduino-nano-rp2040-connect) has the following amounts of memory: - -|Memory Type|Size| -|--|--| -|Flash|16mb| -|SRAM |264kb| - - - -The ATmega4809 ([datasheet](https://content.arduino.cc/assets/Nano-Every_processor-48-pin-Data-Sheet-megaAVR-0-series-DS40002016B.pdf)) chip found on the [Nano Every](https://store.arduino.cc/collections/boards/products/arduino-nano-every) has the following amounts of memory: - -|Memory Type|Size| -|--|--| -|Flash|48kb| -|SRAM |6kb| -|EEPROM| 256 bytes| - - - -The ATmega328 ([datasheet](http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf)) chip found on the [Nano](https://store.arduino.cc/collections/boards/products/arduino-nano) has the following amounts of memory: - -|Memory Type|Size| -|--|--| -|Flash|32kb| -|SRAM |2kb| -|EEPROM| 1kb| - - -### Memory on Arduino MKR boards - -The SAMD21G18A ([datasheet](https://content.arduino.cc/assets/mkr-microchip_samd21_family_full_datasheet-ds40001882d.pdf)) chip found on the [MKR WiFi 1000](https://store.arduino.cc/collections/boards/products/arduino-mkr1000-wifi), [MKR FOX 1200](https://store.arduino.cc/collections/boards/products/arduino-mkr-fox-1200), [MKR GSM 1400](https://store.arduino.cc/collections/boards/products/arduino-mkr-gsm-1400), [MKR NB 1500](https://store.arduino.cc/collections/boards/products/arduino-mkr-nb-1500), [MKR Vidor 4000](https://store.arduino.cc/collections/boards/products/arduino-mkr-vidor-4000), [MKR WAN 1300](https://store.arduino.cc/products/arduino-mkr-wan-1300-lora-connectivity?pr_prod_strat=description&pr_rec_pid=5517873053847&pr_ref_pid=5517874233495&pr_seq=uniform), [MKR WAN 1310](https://store.arduino.cc/collections/boards/products/arduino-mkr-wan-1310), [MKR WiFi 1010](https://store.arduino.cc/collections/boards/products/arduino-mkr-wifi-1010) and [MKR Zero](https://store.arduino.cc/collections/boards/products/arduino-zero) has the following amounts of memory: - -|Memory Type|Size| -|--|--| -|Flash|256kb| -|SRAM |32kb| - - -### Memory on Arduino Pro boards - -The ST STM32H747XI ([datasheet](https://content.arduino.cc/assets/Arduino-Portenta-H7_Datasheet_stm32h747xi.pdf?_gl=1*14nfrmx*_ga*Mjk5OTAxNjU5LjE2MzkyMTU1MDg.*_ga_NEXN8H46L5*MTYzOTQ5NzYzMS44LjEuMTYzOTQ5OTE2NS4w)) chip found on the [Portenta H7](https://store.arduino.cc/collections/boards/products/portenta-h7), [Portenta H7 Lite](https://store.arduino.cc/collections/boards/products/portenta-h7-lite) and [Portenta H7 Lite Connected](https://store.arduino.cc/collections/boards/products/portenta-h7-lite-connected) has the following amounts of memory: - -|Memory Type|Size| -|--|--| -|Flash|2mb| -|SRAM |1mb| - - -### Memory on Arduino Classic boards - -The ATmega328P ([datasheet](https://content.arduino.cc/assets/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf?_gl=1*if3eoe*_ga*Mjk5OTAxNjU5LjE2MzkyMTU1MDg.*_ga_NEXN8H46L5*MTYzOTQ5NzYzMS44LjEuMTYzOTQ5OTIyMS4w)) chip found on the [UNO R3](https://store.arduino.cc/collections/boards/products/arduino-uno-rev3) and [UNO Mini](https://store.arduino.cc/collections/boards/products/uno-mini-le) has the following amounts of memory: - -|Memory Type|Size| -|--|--| -|Flash|32kb| -|SRAM |2kb| -|EEPROM| 1kb| - - -The ATmega4809 ([datasheet](http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega4808-4809-Data-Sheet-DS40002173A.pdf)) chip found on the [UNO WiFi Rev2](https://store.arduino.cc/collections/boards/products/arduino-uno-wifi-rev2) has the following amounts of memory: - -|Memory Type|Size| -|--|--| -|Flash|48kb| -|SRAM |6kb| -|EEPROM| 256 bytes| - - -The ATmega32U4 ([datasheet](http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf)) chip found on the [Yún Rev2](https://store.arduino.cc/collections/boards/products/arduino-yun-rev-2), [Leonardo](https://store.arduino.cc/collections/boards/products/arduino-leonardo-with-headers) and [Micro](https://store.arduino.cc/collections/boards/products/arduino-micro) has the following amounts of memory: - -|Memory Type|Size| -|--|--| -|Flash|32kb| -|SRAM |2.5kb| -|EEPROM| 1kb| - - -The Atmel SAM3X8E ([datasheet](http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf)) chip found on the [Due](https://store.arduino.cc/collections/boards/products/arduino-due) has the following amounts of memory: - -|Memory Type|Size| -|--|--| -|Flash|512kb| -|SRAM |96kb| - - -The ATmega2560 ([datasheet](https://content.arduino.cc/assets/ATmega640-1280-1281-2560-2561-Datasheet-DS40002211A.pdf?_gl=1*l6g5au*_ga*Mjk5OTAxNjU5LjE2MzkyMTU1MDg.*_ga_NEXN8H46L5*MTYzOTQ5NzYzMS44LjEuMTYzOTQ5OTMzMy4w)) chip found on the [Mega 2560 Rev3](https://store.arduino.cc/collections/boards/products/arduino-mega-2560-rev3) has the following amounts of memory: - -|Memory Type|Size| -|--|--| -|Flash|256kb| -|SRAM |8kb| -|EEPROM| 4kb| - ## Tips & Troubleshooting Notice that with boards that do not have a lot of SRAM available, like the UNO. It's easy to use it all up by having lots of strings in your program. For example, a declaration like: From 9aa94686800c0b387feff815e13155f70c0534dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Wed, 30 Mar 2022 08:29:08 -0400 Subject: [PATCH 14/36] Update tutorial content --- .../06.memory-guide/memory-guide.md | 88 +++++++------------ 1 file changed, 33 insertions(+), 55 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index a6b2a0e1fd..d1dd635dfc 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -79,9 +79,9 @@ Now, let us talk about the different memory units present on microcontrollers. A RAM and ROM in microcontroller-based systems are organized into three main categories: -* Flash. -* RAM. -* EEPROM. +* Flash +* RAM +* EEPROM Let us talk more about these types of memories. @@ -99,6 +99,24 @@ In microcontroller-based systems, Erasable Programmable Read-Only Memory, or EEP ## Arduino® Boards Memory Allocation +As stated before, Arduino® boards are mainly based on two families of microcontrollers, AVR® and ARM®; **memory allocation differs in both architectures**. In Harvard-based AVR architecture, memory is organized as shown in the image below: + +Something important to mention about AVR-based Arduino boards is how their SRAM is organized into different sections: + +- `Text` +- `Data` +- `BSS` +- `Stack` +- `Heap` + +The `text` section contains instructions loaded into the flash memory; `data` section contains variables initialized in the sketch, `BSS` section contains uninitialized data, `stack` section stores data of functions and interrupts, and `heap` section stores variables created during run time. + +In hybid ARM architectures, memory is organized as shown in the image below: + +Something important to mention about ARM architecture is that it implements **Memory Organization** or **Memory Map**, built depending on the width of the address map that goes from 32-Bit to 40-Bit structure. It uses Virtual and Physical addresses while the Memory Management Unit (MMU) interfaces in between to correct operation of memory system. +​ +The **Translation Tables** are injected by virtual addresses, composed of Kernel and application in blocks of data and code; then translated into physical addresses composed by peripherals, Flash, SRAM, and ROM. The present architecture uses its Memory Map, predefined accordingly depending on the ARM chip family, to ease the access. + The following table summarizes Arduino® boards memory allocation: | **Board** | **Microcontroller** | **Family** | **Architecture** | **Flash** | **SRAM** | **EEPROM** | @@ -110,70 +128,30 @@ The following table summarizes Arduino® boards memory allocation: | Leonardo | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | | Mega 2560 Rev3 | ATmega2560 | AVR | Harvard | 256kB | 8kB | 4kB | | Micro | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | -| Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | +| Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | | Portenta H7 | STM32H747 | ARM Cortex M4/M7 | Harvard | | | | | Nicla Sense ME | nRF52832 | ARM Cortex M4 | Harvard | | | | | Nano RP2040 Connect | RP2040 | ARM Cortex M0+ | Von Neumann | - | 264kB | - | -| MKR FOX 1200 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | -| MKR NB 1500 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | -| MKR Vidor 4000 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | -| MKR WiFi 1010 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | -| MKR Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | -| MKR1000 WIFI | ATSAMW25H18 | ARM Cortex M0+ | Von Neumann | | | | -| MKR WAN 1300 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | -| MKR WAN 1310 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | +| MKR FOX 1200 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR NB 1500 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR Vidor 4000 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR WiFi 1010 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR1000 WIFI | ATSAMW25H18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR WAN 1300 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR WAN 1310 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | | Nano | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | | Nano Every | ATmega4809 | AVR | Harvard | 48kB | 6kB | 256B | -| Nano 33 IoT | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | | | | +| Nano 33 IoT | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | | Nano 33 BLE | nRF52840 | ARM Cortex M4 | Harvard | | | | | Nano 33 BLE Sense | nRF52840 | ARM Cortex M4 | Harvard | | | | -### AVR-based Boards -​ -AVR architecture microcontrollers has the Flash Program Memory and Static Random Access Memory -on a separate bus. There are 2 existing bus in which handles all the data and the other line handling Input and Output with limited access. The memory architecture is allocated briefly in following manner: -​ -- Program Memory (Flash) -- EEPROM Memory (Data) -- SRAM Memory (Data) -- I/O Memory -​ -Each memory type serves different role that handles the function of the AVR architecture microcontrollers. It is good to know what does each memory class manages, to comprehend what is about to be detailed in the continuing section. -​ -#### Program Memory -​ -The Program Memory is the reprogrammable memory found on the system. This is the Flash memory that serves as a storage, and the memory divides into two different section due to security measure. A Boot-loader section is where all the crucial code is stored to initialize peripherals and essential components. While the application section is where the composed code is uploaded. -​ -#### EEPROM Memory -​ -This type of memory is Read-Only memory that is electrically eraseable and reprogrammable. The memory module is designed usually with minimal resource available on the table. Commonly the memory is used to save small amounts of data and store even if when the device powers down. EEPROM registers are to access this memory department and during rewrite process, the memory removes everything in order to reprogram. -​ - -#### SRAM Memory -​ -The Static Random Access Memory is accessed via standard data bus, and the data is retained while it has power feed. This data memory stores different memory units that are from registers, Input/Output memory, and its internal SRAM. All this is to have general purpose 8-Bit registers, control registers to address peripheral components, and volatile storage location to temporarily manage the data generated from the code. - -#### EEPROM - -In microcontroller-based systems, erasable Programmable Read Only Memory, or EEPROM, is also part of its ROM; actually, Flash memory is a type of EEPROM. The main difference between Flash memory and EEPROM that EEPROM can be managed at byte-level (write or erased), while Flash can be managed at block-level. -​ -### ARM-based Boards -​ -ARM architecture implements **Memory Organization** or **Memory Map**, built depending on the width of the address map that goes from 32-Bit to 40-Bit structure. It uses Virtual and Physical addresses while the Memory Management Unit (MMU) interfaces in between to correct operation of memory system. -​ -The **Translation Tables** are injected by virtual addresses, composed of Kernel and application in blocks of data and code; then translated into physical addresses composed by peripherals, Flash, SRAM, and ROM. The present architecture uses its Memory Map, predefined accordingly depending on the ARM chip family, to ease the access. -​ -## Heap & Stack -It is good to know a little bit about what is **Heap** and **Stack** when we discuss about Random Access Memory (RAM), as it will be mentioned sometimes to explain its behaviour. - -- Heap: Dynamic memory sector, in which if the new allocation is made, it can grow; but also reduce in size with some possibility depending on the requirement. It is where `malloc` is found. - -- Stack: This memory sector is used for functions calls and local variable storage. When the function finishes the job, the local variables that wad holding the memory pool is freed up. The memory sector will grow towards the Heap, and it is positioned at the end of the RAM, at the side of External RAM. -​ ## Measuring Memory Usage in Arduino Boards + Memory usage stadistics will help you understand the resource management affected by the designed code. It is an important factor to consider, as the resources are finite. In fact, it should run without always reaching maximum load capacity. This is one stadistic that will tell you how efficient the code is designed. ​ ### SRAM & DRAM: Quick Differentiation Specification + Embedded devices has **Static Random Access Memory (SRAM)** and **Dynamic Random Access Memory (DRAM)**. These are 2 different derivatives that forms Random Access Memory (RAM) inside the embedded devices. Both RAM types has trade-off in between them, and it is based on speed, physical size and cost. - SRAM is much faster than DRAM has to propose. In Read, Write and Access speed. From f3aa8edf3da129cf96fdfeb3337583239563e952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Wed, 30 Mar 2022 08:34:16 -0400 Subject: [PATCH 15/36] Update tutorial content --- content/learn/03.programming/06.memory-guide/memory-guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index d1dd635dfc..72debc4a83 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -113,9 +113,9 @@ The `text` section contains instructions loaded into the flash memory; `data` se In hybid ARM architectures, memory is organized as shown in the image below: -Something important to mention about ARM architecture is that it implements **Memory Organization** or **Memory Map**, built depending on the width of the address map that goes from 32-Bit to 40-Bit structure. It uses Virtual and Physical addresses while the Memory Management Unit (MMU) interfaces in between to correct operation of memory system. +Something important to mention about ARM architecture is that it implements a memory map, built depending on the width of the address map that goes from 32-bit to a 40-bit structure. This memory map uses virtual and physical addresses while the Memory Management Unit (MMU) interfaces check the correct operation of the memory system. ​ -The **Translation Tables** are injected by virtual addresses, composed of Kernel and application in blocks of data and code; then translated into physical addresses composed by peripherals, Flash, SRAM, and ROM. The present architecture uses its Memory Map, predefined accordingly depending on the ARM chip family, to ease the access. +The translation tables are injected by virtual addresses, composed of Kernel and application in blocks of data and code; then translated into physical addresses composed of peripherals, Flash, SRAM, and ROM. The present architecture uses its Memory Map, predefined accordingly depending on the ARM chip family, to ease access. The following table summarizes Arduino® boards memory allocation: From d03004a4d738e576a7f980f17fe8e6623fdc4e6a Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Wed, 30 Mar 2022 17:56:09 -0600 Subject: [PATCH 16/36] Readjusted Memory Allocation section content --- .../03.programming/06.memory-guide/memory-guide.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 72debc4a83..044316988f 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -99,7 +99,7 @@ In microcontroller-based systems, Erasable Programmable Read-Only Memory, or EEP ## Arduino® Boards Memory Allocation -As stated before, Arduino® boards are mainly based on two families of microcontrollers, AVR® and ARM®; **memory allocation differs in both architectures**. In Harvard-based AVR architecture, memory is organized as shown in the image below: +As stated before, Arduino® boards are mainly based on two families of microcontrollers, AVR® and ARM®; it is important to know that **memory allocation differs in both architectures**. In Harvard-based AVR architecture, memory is organized as shown in the image below: Something important to mention about AVR-based Arduino boards is how their SRAM is organized into different sections: @@ -113,9 +113,11 @@ The `text` section contains instructions loaded into the flash memory; `data` se In hybid ARM architectures, memory is organized as shown in the image below: -Something important to mention about ARM architecture is that it implements a memory map, built depending on the width of the address map that goes from 32-bit to a 40-bit structure. This memory map uses virtual and physical addresses while the Memory Management Unit (MMU) interfaces check the correct operation of the memory system. -​ -The translation tables are injected by virtual addresses, composed of Kernel and application in blocks of data and code; then translated into physical addresses composed of peripherals, Flash, SRAM, and ROM. The present architecture uses its Memory Map, predefined accordingly depending on the ARM chip family, to ease access. +Arduino Pro Family's Portenta H7 is built with ARM architecture microcontroller. This architecture is renowned for implementation of so called **Memor map**, with different address map configuration of 32-bit, 36-bit, and 40-bit that depends on the requirement of System On a Chip (SoC) address space with extra DRAM. The Memory Map grants interface with SoC design, while having most system control on a high level coding. Memory access instructions can be used on high level code to manage interrupt modules and built-in peripherals. All of this controlled by Memory Management Unit (MMU). + +The Memory Management Unit (MMU) establishes bridge between virtual and physical addresses using translation tables. Table Walk Unit and Translation Lookaside Buffers (TLBs) are 2 main pieces of MMU. Table Walk Unit implements an algorithm that interprets translation table, while the TLBs hold most recent translations for future uses derived from Table Walk Unit. The Virtual Address is composed of Kernel and application in blocks of data and code; the Physical Address controls peripherals, Flash, SRAM, and ROM. + +Simply put, Virtual Address is managed via software with memory instructions, and Physical address is the memory system that is controlled depending on the Translation Table input given by the Virtual Address. The following table summarizes Arduino® boards memory allocation: From 60b3d0fe76099b530481ab0b47d4dc43864f48b0 Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Wed, 30 Mar 2022 18:15:54 -0600 Subject: [PATCH 17/36] Based on Previous Commit: Typo-Fix --- content/learn/03.programming/06.memory-guide/memory-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 044316988f..fc528947fb 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -113,7 +113,7 @@ The `text` section contains instructions loaded into the flash memory; `data` se In hybid ARM architectures, memory is organized as shown in the image below: -Arduino Pro Family's Portenta H7 is built with ARM architecture microcontroller. This architecture is renowned for implementation of so called **Memor map**, with different address map configuration of 32-bit, 36-bit, and 40-bit that depends on the requirement of System On a Chip (SoC) address space with extra DRAM. The Memory Map grants interface with SoC design, while having most system control on a high level coding. Memory access instructions can be used on high level code to manage interrupt modules and built-in peripherals. All of this controlled by Memory Management Unit (MMU). +Arduino Pro Family's Portenta H7 is built with ARM architecture microcontroller. This architecture is renowned for implementation of so called **Memory map**, with different address map configuration of 32-bit, 36-bit, and 40-bit that depends on the requirement of System On a Chip (SoC) address space with extra DRAM. The Memory Map grants interface with SoC design, while having most system control on a high level coding. Memory access instructions can be used on high level code to manage interrupt modules and built-in peripherals. All of this controlled by Memory Management Unit (MMU). The Memory Management Unit (MMU) establishes bridge between virtual and physical addresses using translation tables. Table Walk Unit and Translation Lookaside Buffers (TLBs) are 2 main pieces of MMU. Table Walk Unit implements an algorithm that interprets translation table, while the TLBs hold most recent translations for future uses derived from Table Walk Unit. The Virtual Address is composed of Kernel and application in blocks of data and code; the Physical Address controls peripherals, Flash, SRAM, and ROM. From 8d4a5a7a24ccdf0ddc5f281124918317c760266c Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Thu, 31 Mar 2022 18:18:30 -0600 Subject: [PATCH 18/36] Overall content update & refinement --- .../06.memory-guide/memory-guide.md | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index fc528947fb..e19097a09d 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -150,23 +150,23 @@ The following table summarizes Arduino® boards memory allocation: ## Measuring Memory Usage in Arduino Boards -Memory usage stadistics will help you understand the resource management affected by the designed code. It is an important factor to consider, as the resources are finite. In fact, it should run without always reaching maximum load capacity. This is one stadistic that will tell you how efficient the code is designed. +Memory usage stadistics helps comprehend of the insight of resource management affected by the designed code structure. It is an important development consideration element, because the resources are finite. As a matter of fact, the software should perform always without reaching maximum load capacity. Memory load demand is one stadistic that will provide you an insight of how efficient the code is designed. Memory load could be observed either as available RAM at disposal for certain tasks, or Flash storage with remaing capacity for required headroom. ​ ### SRAM & DRAM: Quick Differentiation Specification -Embedded devices has **Static Random Access Memory (SRAM)** and **Dynamic Random Access Memory (DRAM)**. These are 2 different derivatives that forms Random Access Memory (RAM) inside the embedded devices. Both RAM types has trade-off in between them, and it is based on speed, physical size and cost. +Embedded devices compose of **Static Random Access Memory (SRAM)** and **Dynamic Random Access Memory (DRAM)**. These are 2 different derivatives that shapes the Random Access Memory (RAM). Both RAM types has trade-off in between them, and it is based on speed, physical size and manufacturing cost. -- SRAM is much faster than DRAM has to propose. In Read, Write and Access speed. -- SRAM is mucho more expensive in terms of manufacturing cost than DRAM. -- DRAM offers more friendly physical size than SRAM. +- SRAM performs much faster than DRAM has to propose. In Read, Write and Access speed. +- SRAM is much more expensive in terms of manufacturing cost than DRAM. +- DRAM offers more friendly physical size, in terms of storage capacity, than SRAM. -While these are 2 types of RAM that exists for embedded devices, optimization process that will be stated in the following are applicable as a whole. No matter which type of RAM is on-board, it can be managed efficiently with careful design factors in mind. +While these are 2 types of RAM that are found within embedded devices, optimization process that will be stated in the following are applicable as a whole. No matter which type of RAM is on-board, it can be controlled to achieve efficient memory management with careful design factors in mind. -Ultimately, it should not be abused whatsoever, because even if the code might run, the device may have a lot of holes to be filled and fixed to run in a stable manner. And the fix or patch that has to be applied later, might cost entire code architecture re-design. +Ultimately, it should not be abused whatsoever, because even if the code might produce results, the system may be filled with a lot of memory handling flaws causing unstable on-the-edge software. The fix or patch that are applied later, might cost entire code architecture re-design. ### Flash Memory Measurement -The Flash memory on Arduino boards can be measured with the help of the Arduino IDE. As the Flash memory is where the Application code will be stored, the Arduino IDE will report through output log to let the developer know how much resource is being used. +The Flash memory on Arduino boards can be measured with the help of the Arduino IDE. As the Flash memory is where the Application code is stored, the Arduino IDE will report through output log to let the developer know how much resource is being used. This is the output log format for Arduino Nano. @@ -180,15 +180,15 @@ This is the output log format for Arduino Portenta H7. ![Flash Memory Usage - Arduino Portenta H7 (ABX00042) [ARM]](assets/arm_portentah7.png) -Each image of Arduino IDE is based of three different Arduino boards, one based on AVR and the other two based of ARM architecture. The compiler will output a log where how much Flash resource is used when uploading the code. +Each image of Arduino IDE is based of selected three different Arduino boards, in which one is based on AVR and the other two is based of ARM architecture. The compiler will output a log where how much Flash resource is used when uploading the code. -The purpose of three images for different boards is to how that for each Arduino board family, the output log format is little different from one another; but it will show you the required information regarding the code that is to be uploaded to the board. +The purpose of these three images for different boards is to show that for each Arduino board family, the output log format is little different from one another; but it will show you the memory consumption information regarding the uploaded code. -***If it is required to handle the Flash memory within the code, please read more about in [this](https://docs.arduino.cc/tutorials/portenta-h7-lite/por-ard-flash) using Arduino Portenta H7*** +***If it is required to handle the Flash memory within high level code, please read more about in [this](https://docs.arduino.cc/tutorials/portenta-h7-lite/por-ard-flash) using Arduino Portenta H7*** ### SRAM Memory Measurement -The code may upload and run. However, there may be situations in which the program will suffer from sudden operation halt. Moments like this can be due to memory resource hogging. To solve this, it will require to understand in which sector of the code, the memory demand is going beyond the available resources. Following code fragment will help you measure the SRAM usage while the code is running. +The code may compile, upload and run. However, there may be situations in which the program will suffer from sudden operation halt. Thys type of issues are likely due to memory resource hogging or not enough memory to allocate. To solve this, it will require to understand in which sector of the code, the memory demand is going beyond the available resources. Following code fragment will help you measure the SRAM usage at a high level code. ```cpp void display_freeram(){ @@ -210,9 +210,9 @@ In the code, `__heap_start` and `__brkval` are as following: ### EEPROM Memory Measurement -To be able to use EEPROM features, it is already included with the Arduino IDE platform so it does not require additional step to install any library. +EEPROM features are already included with the Arduino IDE platform so it does not require additional step to install any library to use its features. -EEPROM memory measurement can be done through use of the following simple code fragment. The code is simplified to write a byte to know exactly which address it is reading from. It can be modified to read everything from every possible address. +EEPROM memory measurement can be done through use of the following simple code fragment. The code is simplified to write a byte to know exactly which address it is reading from. It can be modified to read everything from every available possible address. ```cpp #include @@ -221,7 +221,7 @@ EEPROM.write(address, value); EEPROM.read(address); ``` -On the other hand, it is possible to clear the entire EEPROM memory to set it to 0. +On the other hand, it is possible to clear the entire EEPROM memory to set it to 0. ```cpp #include @@ -240,13 +240,13 @@ The complete example codes can be found in our guide to EEPROM found below the f ***For more information on how to manage the EEPROM memory, please read [here](https://docs.arduino.cc/learn/programming/eeprom-guide)*** ## Optimizing Memory Usage in Arduino-based Systems -To know how the code utilizes the memory resources is one matter, but to optimize the memory is a whole different task. As the term development may infer, the requirements may change or be adjusted depending on external factors such as reduced device capacity due to inavailability of the components. Thus the code architecture may require optimization to be able to run on the reduced limited memory resources. +Knowing how the code utilizes the memory resources is one matter, but to optimize the memory is a whole different task. As the term development may infer, the requirements may change or be adjusted depending on external factors such as reduced device capacity due to inavailability of the components. Thus the code architecture may require optimization to be able to run on the reduced limited memory resources. -The optimization process also implies reduced computational complexities, trimming down extra time required to process the tasks. The memory optimization process may help the overall optimization process, as it will handle how the memory is managed in a more suitable manner. +The optimization process also implies reduced computational complexities, trimming down extra time required to process the tasks while using less memory resource to do the same task. The memory optimization process may help the overall code optimization process, as it will handle how the memory is managed in a more suitable manner by requiring smart algorithm development. ### Flash Memory Optimization -One of the memory sources to begin optimization with is the Flash memory. As the Flash memory is where the size itself of the code can be reduced greatly by considering some details. +Flash memory optimization is the most likely the straightforward optimization possible source to begin with. The Flash memory is where the capacity used by compiled code can be reduced greatly by considering some details. #### Detach Unused Sources Detaching unused sources include unused libraries, and code residues. Code residues can be composed of functions that are no longer used and floating variables that takes up the unnecessary space in memory. This will vastly improve the compiled code size and make more clear compilation process. @@ -254,7 +254,7 @@ Detaching unused sources include unused libraries, and code residues. Code resid #### Modular Tasks Modular tasks mean functions that wraps the code which will be used in a repetitive or continuous manner by receiving different parameters. It is a great way to maintain clean code structure and performance, while reducing the memory space required for additional tasks that might need to be implemented. -This leads to compact code structure, that is much easier to understand when debugging process is required, and demand developer to considerate compute complexity while designing the code structure. +This leads to compact code structure, that is much easier to understand when debugging process is required, and demand developer to considerate compute complexity when designing the code structure or such specific algorithm. ### SRAM Memory Optimization @@ -269,12 +269,12 @@ Serial.println(F("Something")); By wrapping the String with `F()`, will move the Strings to Flash memory only rather than to use SRAM space also. It can be observed as offloading such data to Flash memory instead of SRAM. -Flash memory is much more spacious than SRAM size, so it is possible to use the Flash space than using SRAM which will use Heap. This does not mean, the memory space will always be available as Flash memory does too have limited space. It is not recommendable to spam the code structure with Print Line, but to use them where they most matter for such applications with minimized implementation. +Flash memory is much more spacious than SRAM size, so it is better to use the Flash space than using SRAM which will use Heap. This does not mean the memory space will always be available, as Flash memory does have limited space too. It is not recommendable to cloag the code structure with Print Line, but to use them where they most matter for such applications with minimized implementation. #### PROGMEM It is not always with the literal String that occupies the SRAM space, but also using Global Variables which also takes up quite good amount of SRAM. As Global and Static variables are streamed to SRAM space, and pushes the Heap towards the Stack. The space occupied by this variables streamed to SRAM space will be saved at its location and will not be changing, meaning more of these variables are created, they will use more space and consequently, system failure due to low and poor memory management. -PROGMEM stands simply for Program Memory. We will use Program memory to store variable data offloading to Flash Memory space. As it goes same as to String Wrapper F(), PROGMEM uses Flash Memory space for its usage. The only disadvantage presented using PROGMEM is the Read Speed. Using RAM will provide much faster Read Speed, but PROGMEM, as it uses Flash Memory, it will be slower than RAM, given the same data size read. Thus, it is important to design the software knowing which variables are crucial and others has lower priority. It is one of the many factors that needs to be considered when developing the software, but this will lead to have nicely designed code architecture. +PROGMEM stands simply for **Program Memory**. We will use Program memory to store variable data offloading to Flash Memory space. As it goes same as to String Wrapper F(), PROGMEM uses Flash Memory space for its implementation. The only disadvantage presented using PROGMEM is the Read Speed. Using RAM will provide much faster Read Speed, but PROGMEM, as it uses Flash Memory, it will be slower than RAM, given the same data size. Thus, it is important to design the software knowing which variables are crucial and which has lower priority. It is one of the many factors that needs to be considered when developing the software, but this will lead to have nicely designed code architecture. To use the PROGMEM, it can begin with following code fragment. @@ -296,7 +296,7 @@ const char greetMessage[] PROGMEM = {"Hello There"}; #### Non Dynamic Memory Allocation Dynamic Memory Allocation usually is a good method if the given RAM size is big enough to get around with, from MegaBytes and so on. However, for embedded devices counting every Byte of the RAM, the process becomes hostile for RAM. -Dynamic Memory Allocations cause Heap fragmentation. With heap fragmentation, many areas of the RAM affected by it cannot reused again, leaving dead Byte that can be taken as an advantage for other tasks. On top of it, when dynamic allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the Heap Size. So to avoid Heap or RAM fragmentation as much as possible, you can follow following rules to apply into code architecture design. +Dynamic Memory Allocations cause **Heap fragmentation**. With heap fragmentation, many areas of the RAM affected by it cannot reused again, leaving dead Byte that can be taken as an advantage for other tasks. On top of it, when dynamic allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the Heap Size. So to avoid Heap or RAM fragmentation as much as possible, you can follow following rules to apply into code architecture design. - Prioritize using **Stack** than **Heap** if possible to do so. - Stack memory is fragmentation free and can be freed up completely when the function returns. Heap in contrast ma not free up the space even though it was instructed to do so. Using Local Variables will help to do this and try not to use dynamic memory allocation, composed of different calls: `malloc, calloc, realloc`. From efb213e30a0afdeea3b17a8fbd8156df76440d26 Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Thu, 31 Mar 2022 18:23:57 -0600 Subject: [PATCH 19/36] Based on Previous Commit: Typo-Fix --- content/learn/03.programming/06.memory-guide/memory-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index e19097a09d..72765ec298 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -150,7 +150,7 @@ The following table summarizes Arduino® boards memory allocation: ## Measuring Memory Usage in Arduino Boards -Memory usage stadistics helps comprehend of the insight of resource management affected by the designed code structure. It is an important development consideration element, because the resources are finite. As a matter of fact, the software should perform always without reaching maximum load capacity. Memory load demand is one stadistic that will provide you an insight of how efficient the code is designed. Memory load could be observed either as available RAM at disposal for certain tasks, or Flash storage with remaing capacity for required headroom. +Memory usage stadistics helps comprehend of the insight of resource management affected by the designed code structure. It is an important development consideration element, because the resources are finite. As a matter of fact, the software should perform always without reaching maximum load capacity. Memory load demand is one stadistic that will provide you an insight of how efficient the code is designed. Memory load could be observed either as available RAM at disposal for certain tasks, or Flash storage with remaining capacity for required headroom. ​ ### SRAM & DRAM: Quick Differentiation Specification From 0fb84dcc4d1381d259b70e6744a826d00336d109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Fri, 1 Apr 2022 09:34:35 -0400 Subject: [PATCH 20/36] Update tutorial content --- .../06.memory-guide/memory-guide.md | 782 +++++++++--------- 1 file changed, 391 insertions(+), 391 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 72765ec298..7d387cea0b 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -1,392 +1,392 @@ ---- -title: 'Arduino Memory Guide' -description: 'Learn about the built-in memory blocks of Arduino® boards in this article.' -tags: - - ROM - - RAM - - Flash - - SRAM - - EEPROM -author: 'José Bagur, Taddy Chung' ---- - -A microcontroller unit (also known as MCU) is an integrated circuit (IC) typically used to perform specific applications or tasks. Usually, this type of IC gathers information or data from its surroundings, process it, and generates specific outputs according to the gathered data. Microcontrollers today are everywhere; they are an essential part of modern embedded systems that can be found practically everywhere in our world, from smartwatches to electric vehicles; they are even on the Martian surface right now. - -One essential part of a microcontroller is its **memory**; memory stores information temporarily or permanently in microcontrollers and can be used for several purposes. This article talks about memory organization in microcontrollers, focusing on those present in Arduino® boards. Also, several ways to manage, measure, and optimize memory usage in Arduino-based systems are discussed in the article. - -## What is Memory? - -Memory blocks are essential parts of modern embedded systems, especially microcontroller-based ones. **Memory blocks are semiconductor devices that store and retrieve information or data**; a microcontroller central processing unit (CPU) uses and processes data stored in memory blocks to perform specific tasks. - -As shown in the image below, memory blocks in microcontrollers are usually described as **arrays**. Memory arrays are divided into **cells** that can store data and be accessed using a unique identifier representing its **address** or position relative to the memory array. Information in memory cells is stored using binary digits (bits), usually organized in bytes (8-bits); it can also be retrieved later by the MCU or other components of a microcontroller-based system. - -Memory in computing systems can be **volatile** or **non-volatile**. **Volatile memory is a temporary memory**, this means that data is stored while the system is running, but it is lost forever when the system is turned off. **Non-volatile memory is permanent memory**; data is not lost even if the system is turned off. - -## Memory Architectures 101 - -Computer architecture is a vast topic; we will focus on a general picture that will let us understand how memory is organized in the microcontrollers used in Arduino® boards. - -In the early days of computing, two computer architectures, i.e., the organization of the components inside a computing system, emerged: **von Neumann** and **Harvard**. - -### Von Neumann Architecture - -The von Neumann architecture, named after the mathematician, physicist, and computer scientist John von Neumann, was first introduced in the mid-'40s; it is also known as the Princeton architecture. T**his architecture stores program data and instructions in the same memory unit**; **both are accessed by the CPU using the same communications bus**, as shown below. Von Neumann's architecture is fundamental since nearly all digital computers design have been based on this architecture. - -### Harvard Architecture - -The Harvard architecture, named after the Harvard Mark I relay-based computer, was first introduced in the mid-'40s. **This architecture's main characteristic is that it uses two separate memory units**, **one for storing program instructions and one for storing program data**. Both memory units in the Harvard architecture are accessed by the CPU using different communication buses. - -### Modern Architectures: Hybrids - -Modern computing systems use **hybrid architectures** models that maximize performance using the best of both worlds, the von Neumann and the Harvard models. - -Microcontrollers are usually used in embedded applications. They must perform defined tasks reliably and efficiently, with low or constrained resources; this is why the **Harvard architecture model is mainly used in microcontrollers**: microcontrollers have a small program and data memory that needs to be accessed simultaneously. However, Harvard architecture is not always used in microcontrollers; some microcontroller families use hybrid or Von Neumann architecture models. - -### Arduino® Boards Architectures - -Arduino® boards are mainly based on two families of microcontrollers: **AVR®** and **ARM®**. While AVR® family microcontrollers are based on the Harvard architecture model, ARM® family microcontrollers can be based on either von Neuman or Harvard architectures models. The following table summarizes Arduino boards microcontrollers architectures: - -| **Board** | **Microcontroller** | **Family** | **Architecture** | -|:-------------------:|:-------------------:|:----------------:|:----------------:| -| UNO Mini | ATmega328P | AVR | Harvard | -| UNO Rev3 | ATmega328P | AVR | Harvard | -| UNO WiFi Rev2 | ATmega4809 | AVR | Harvard | -| UNO Rev3 SMD | ATmega328P | AVR | Harvard | -| Leonardo | ATmega32u4 | AVR | Harvard | -| Mega 2560 Rev3 | ATmega2560 | AVR | Harvard | -| Micro | ATmega32u4 | AVR | Harvard | -| Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | -| Portenta H7 | STM32H747 | ARM Cortex M4/M7 | Harvard | -| Nicla Sense ME | nRF52832 | ARM Cortex M4 | Harvard | -| Nano RP2040 Connect | RP2040 | ARM Cortex M0+ | Von Neumann | -| MKR FOX 1200 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | -| MKR NB 1500 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | -| MKR Vidor 4000 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | -| MKR WiFi 1010 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | -| MKR Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | -| MKR1000 WIFI | ATSAMW25H18 | ARM Cortex M0+ | Von Neumann | -| MKR WAN 1300 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | -| MKR WAN 1310 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | -| Nano | ATmega328P | AVR | Harvard | -| Nano Every | ATmega4809 | AVR | Harvard | -| Nano 33 IoT | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | -| Nano 33 BLE | nRF52840 | ARM Cortex M4 | Harvard | -| Nano 33 BLE Sense | nRF52840 | ARM Cortex M4 | Harvard | - -## Types of Memories - -Now, let us talk about the different memory units present on microcontrollers. All the different memory units inside a microcontroller can be divided into two main types: **RAM** and **ROM**. RAM (from Random-Access Memory) in microcontroller-based systems is a volatile memory used to store temporary data such as the system's firmware variables. ROM (from Read-Only Memory) in microcontroller-based systems is non-volatile memory used to store permanent data such as the system's firmware. - -RAM and ROM in microcontroller-based systems are organized into three main categories: - -* Flash -* RAM -* EEPROM - -Let us talk more about these types of memories. - -### Flash - -Flash memory in microcontroller-based systems is part of its ROM. The **Flash memory is where the system's firmware is stored to be executed**. For example, think of the famous `Blink.ino` example sketch, when we compile this sketch, we create a binary file that is later stored into the Flash memory of an Arduino board and executed when power on. - -### RAM - -**RAM** in microcontroller-based systems **is where the system's temporary data or run-time data is stored**. A microcontroller's RAM usually is SRAM; this is a type of RAM that uses a flip-flop to store one bit of data. For example, the variables created by functions. - -### EEPROM - -In microcontroller-based systems, Erasable Programmable Read-Only Memory, or EEPROM, is also part of its ROM; actually, Flash memory is a type of EEPROM. **The main difference between Flash memory and EEPROM is how they are managed**; EEPROM can be managed at the byte level (write or erased) while Flash can be managed at the block level. - -## Arduino® Boards Memory Allocation - -As stated before, Arduino® boards are mainly based on two families of microcontrollers, AVR® and ARM®; it is important to know that **memory allocation differs in both architectures**. In Harvard-based AVR architecture, memory is organized as shown in the image below: - -Something important to mention about AVR-based Arduino boards is how their SRAM is organized into different sections: - -- `Text` -- `Data` -- `BSS` -- `Stack` -- `Heap` - -The `text` section contains instructions loaded into the flash memory; `data` section contains variables initialized in the sketch, `BSS` section contains uninitialized data, `stack` section stores data of functions and interrupts, and `heap` section stores variables created during run time. - -In hybid ARM architectures, memory is organized as shown in the image below: - -Arduino Pro Family's Portenta H7 is built with ARM architecture microcontroller. This architecture is renowned for implementation of so called **Memory map**, with different address map configuration of 32-bit, 36-bit, and 40-bit that depends on the requirement of System On a Chip (SoC) address space with extra DRAM. The Memory Map grants interface with SoC design, while having most system control on a high level coding. Memory access instructions can be used on high level code to manage interrupt modules and built-in peripherals. All of this controlled by Memory Management Unit (MMU). - -The Memory Management Unit (MMU) establishes bridge between virtual and physical addresses using translation tables. Table Walk Unit and Translation Lookaside Buffers (TLBs) are 2 main pieces of MMU. Table Walk Unit implements an algorithm that interprets translation table, while the TLBs hold most recent translations for future uses derived from Table Walk Unit. The Virtual Address is composed of Kernel and application in blocks of data and code; the Physical Address controls peripherals, Flash, SRAM, and ROM. - -Simply put, Virtual Address is managed via software with memory instructions, and Physical address is the memory system that is controlled depending on the Translation Table input given by the Virtual Address. - -The following table summarizes Arduino® boards memory allocation: - -| **Board** | **Microcontroller** | **Family** | **Architecture** | **Flash** | **SRAM** | **EEPROM** | -|:-------------------:|:-------------------:|:----------------:|:----------------:|:---------:|:--------:|:----------:| -| UNO Mini | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | -| UNO Rev3 | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | -| UNO WiFi Rev2 | ATmega4809 | AVR | Harvard | 48kB | 6kB | 256B | -| UNO Rev3 SMD | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | -| Leonardo | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | -| Mega 2560 Rev3 | ATmega2560 | AVR | Harvard | 256kB | 8kB | 4kB | -| Micro | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | -| Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| Portenta H7 | STM32H747 | ARM Cortex M4/M7 | Harvard | | | | -| Nicla Sense ME | nRF52832 | ARM Cortex M4 | Harvard | | | | -| Nano RP2040 Connect | RP2040 | ARM Cortex M0+ | Von Neumann | - | 264kB | - | -| MKR FOX 1200 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| MKR NB 1500 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| MKR Vidor 4000 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| MKR WiFi 1010 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| MKR Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| MKR1000 WIFI | ATSAMW25H18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| MKR WAN 1300 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| MKR WAN 1310 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| Nano | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | -| Nano Every | ATmega4809 | AVR | Harvard | 48kB | 6kB | 256B | -| Nano 33 IoT | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| Nano 33 BLE | nRF52840 | ARM Cortex M4 | Harvard | | | | -| Nano 33 BLE Sense | nRF52840 | ARM Cortex M4 | Harvard | | | | - -## Measuring Memory Usage in Arduino Boards - -Memory usage stadistics helps comprehend of the insight of resource management affected by the designed code structure. It is an important development consideration element, because the resources are finite. As a matter of fact, the software should perform always without reaching maximum load capacity. Memory load demand is one stadistic that will provide you an insight of how efficient the code is designed. Memory load could be observed either as available RAM at disposal for certain tasks, or Flash storage with remaining capacity for required headroom. -​ -### SRAM & DRAM: Quick Differentiation Specification - -Embedded devices compose of **Static Random Access Memory (SRAM)** and **Dynamic Random Access Memory (DRAM)**. These are 2 different derivatives that shapes the Random Access Memory (RAM). Both RAM types has trade-off in between them, and it is based on speed, physical size and manufacturing cost. - -- SRAM performs much faster than DRAM has to propose. In Read, Write and Access speed. -- SRAM is much more expensive in terms of manufacturing cost than DRAM. -- DRAM offers more friendly physical size, in terms of storage capacity, than SRAM. - -While these are 2 types of RAM that are found within embedded devices, optimization process that will be stated in the following are applicable as a whole. No matter which type of RAM is on-board, it can be controlled to achieve efficient memory management with careful design factors in mind. - -Ultimately, it should not be abused whatsoever, because even if the code might produce results, the system may be filled with a lot of memory handling flaws causing unstable on-the-edge software. The fix or patch that are applied later, might cost entire code architecture re-design. - -### Flash Memory Measurement - -The Flash memory on Arduino boards can be measured with the help of the Arduino IDE. As the Flash memory is where the Application code is stored, the Arduino IDE will report through output log to let the developer know how much resource is being used. - -This is the output log format for Arduino Nano. - -![Flash Memory Usage - Arduino Nano [AVR]](assets/avr_nano.png) - -This is the output log format for Arduino MKR WAN 1310. - -![Flash Memory Usage - Arduino MKR WAN 1310 [ARM]](assets/arm_mkrwan1310.png) - -This is the output log format for Arduino Portenta H7. - -![Flash Memory Usage - Arduino Portenta H7 (ABX00042) [ARM]](assets/arm_portentah7.png) - -Each image of Arduino IDE is based of selected three different Arduino boards, in which one is based on AVR and the other two is based of ARM architecture. The compiler will output a log where how much Flash resource is used when uploading the code. - -The purpose of these three images for different boards is to show that for each Arduino board family, the output log format is little different from one another; but it will show you the memory consumption information regarding the uploaded code. - -***If it is required to handle the Flash memory within high level code, please read more about in [this](https://docs.arduino.cc/tutorials/portenta-h7-lite/por-ard-flash) using Arduino Portenta H7*** - -### SRAM Memory Measurement - -The code may compile, upload and run. However, there may be situations in which the program will suffer from sudden operation halt. Thys type of issues are likely due to memory resource hogging or not enough memory to allocate. To solve this, it will require to understand in which sector of the code, the memory demand is going beyond the available resources. Following code fragment will help you measure the SRAM usage at a high level code. - -```cpp -void display_freeram(){ - Serial.print(F("SRAM left")); - Serial.println(freeRam()); -} - -int freeRam() { - extern int __heap_start,*__brkval; - int v; - return (int)&v - (__brkval == 0 - ? (int)&__heap_start : (int) __brkval); -} -``` - -In the code, `__heap_start` and `__brkval` are as following: -- **`__heap_start`**: Refers to beginning of the Heap. -- **`__brkval`**: Last memory address pointer used by Heap. It is pointing towards the Stack. - -### EEPROM Memory Measurement - -EEPROM features are already included with the Arduino IDE platform so it does not require additional step to install any library to use its features. - -EEPROM memory measurement can be done through use of the following simple code fragment. The code is simplified to write a byte to know exactly which address it is reading from. It can be modified to read everything from every available possible address. - -```cpp -#include - -EEPROM.write(address, value); -EEPROM.read(address); -``` - -On the other hand, it is possible to clear the entire EEPROM memory to set it to 0. - -```cpp -#include - -... - -for (int i = 0 ; i < EEPROM.length() ; i++) { - EEPROM.write(i, 0); -} - -... -``` - -The complete example codes can be found in our guide to EEPROM found below the following code. - -***For more information on how to manage the EEPROM memory, please read [here](https://docs.arduino.cc/learn/programming/eeprom-guide)*** - -## Optimizing Memory Usage in Arduino-based Systems -Knowing how the code utilizes the memory resources is one matter, but to optimize the memory is a whole different task. As the term development may infer, the requirements may change or be adjusted depending on external factors such as reduced device capacity due to inavailability of the components. Thus the code architecture may require optimization to be able to run on the reduced limited memory resources. - -The optimization process also implies reduced computational complexities, trimming down extra time required to process the tasks while using less memory resource to do the same task. The memory optimization process may help the overall code optimization process, as it will handle how the memory is managed in a more suitable manner by requiring smart algorithm development. - -### Flash Memory Optimization - -Flash memory optimization is the most likely the straightforward optimization possible source to begin with. The Flash memory is where the capacity used by compiled code can be reduced greatly by considering some details. - -#### Detach Unused Sources -Detaching unused sources include unused libraries, and code residues. Code residues can be composed of functions that are no longer used and floating variables that takes up the unnecessary space in memory. This will vastly improve the compiled code size and make more clear compilation process. - -#### Modular Tasks -Modular tasks mean functions that wraps the code which will be used in a repetitive or continuous manner by receiving different parameters. It is a great way to maintain clean code structure and performance, while reducing the memory space required for additional tasks that might need to be implemented. - -This leads to compact code structure, that is much easier to understand when debugging process is required, and demand developer to considerate compute complexity when designing the code structure or such specific algorithm. - -### SRAM Memory Optimization - -#### String Wrapper - F() -It is convenient to use `Serial.println("Something");` to display the literals. This is used usually to understand where the code is going and to observe certain conditionals. However, doing this so will hog up the Static Random Access Memory (SRAM) space, which is something not desirable as the content is a simple literal string that is not used under the hood. - -The ideal way to use the Print Line command is to use the `F()` String Wrapper around the literals. This will lead us to following piece of code. - -```cpp -Serial.println(F("Something")); -``` - -By wrapping the String with `F()`, will move the Strings to Flash memory only rather than to use SRAM space also. It can be observed as offloading such data to Flash memory instead of SRAM. - -Flash memory is much more spacious than SRAM size, so it is better to use the Flash space than using SRAM which will use Heap. This does not mean the memory space will always be available, as Flash memory does have limited space too. It is not recommendable to cloag the code structure with Print Line, but to use them where they most matter for such applications with minimized implementation. - -#### PROGMEM -It is not always with the literal String that occupies the SRAM space, but also using Global Variables which also takes up quite good amount of SRAM. As Global and Static variables are streamed to SRAM space, and pushes the Heap towards the Stack. The space occupied by this variables streamed to SRAM space will be saved at its location and will not be changing, meaning more of these variables are created, they will use more space and consequently, system failure due to low and poor memory management. - -PROGMEM stands simply for **Program Memory**. We will use Program memory to store variable data offloading to Flash Memory space. As it goes same as to String Wrapper F(), PROGMEM uses Flash Memory space for its implementation. The only disadvantage presented using PROGMEM is the Read Speed. Using RAM will provide much faster Read Speed, but PROGMEM, as it uses Flash Memory, it will be slower than RAM, given the same data size. Thus, it is important to design the software knowing which variables are crucial and which has lower priority. It is one of the many factors that needs to be considered when developing the software, but this will lead to have nicely designed code architecture. - -To use the PROGMEM, it can begin with following code fragment. - -```cpp -#include - -// Basic PROGMEM Define Structure -const PROGMEM DataType Variable_Name[] = {var0, var1, var2 ...}; - -// Unsigned 16 Bit int -const PROGMEM uint16_t NumSet[] = {0, 1, 1, 2, 3, 5, 8 ...}; - -// Storing Char -const char greetMessage[] PROGMEM = {"Hello There"}; -``` - -***For In-Depth detail about PROGMEM, please read [here](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/)*** - -#### Non Dynamic Memory Allocation -Dynamic Memory Allocation usually is a good method if the given RAM size is big enough to get around with, from MegaBytes and so on. However, for embedded devices counting every Byte of the RAM, the process becomes hostile for RAM. - -Dynamic Memory Allocations cause **Heap fragmentation**. With heap fragmentation, many areas of the RAM affected by it cannot reused again, leaving dead Byte that can be taken as an advantage for other tasks. On top of it, when dynamic allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the Heap Size. So to avoid Heap or RAM fragmentation as much as possible, you can follow following rules to apply into code architecture design. - -- Prioritize using **Stack** than **Heap** if possible to do so. - - Stack memory is fragmentation free and can be freed up completely when the function returns. Heap in contrast ma not free up the space even though it was instructed to do so. Using Local Variables will help to do this and try not to use dynamic memory allocation, composed of different calls: `malloc, calloc, realloc`. - -- Reduced Global and Static Data if possible to do so. - - Meantime the code is running, memory area occupied by these data will not be freed up. Meaning the data won't be modified as it is constant data taking up the precious space. - -- Short Strings / Literals - - It is good practice to keep the literal Strings as short as possible. Single char takes **One** Byte of RAM, so shorter the better memory space usage. This does not mean, keeping it short and using it in several different areas of the code is possible. Use it when it is absolutely required and keep as short as possible to spare RAM space for other task functions. - - - Arrays are also recommended to be at a minimum size. If it requires to resize the array, you can always re-set the array size in the code. It may be a tedious, also non-efficient method to hard-code the array sizes. But if the code utilizes small array sizes and less than 3 arrays, it may be suffice via manual resizing, knowing the requirements. A smart way to do this is resizeable array with limited size. In which the tasks will use the array without going over the size boundary, thus it is suitable for extensive code size. Although, the limit of the array size must be analyzed and kept as small as possible. - -#### RESERVE() -If the tasks work with the Strings, that changes in its size depending on the operation outcome, `RESERVE()` is way to go. This function will help to reserve buffer space and pre-allocate for String variable, which changes in its size, and avoid fragmentation. String variable that changes in its size could be a result of `int` type variable wrapped to be used as a `String` for example. - -To use the `RESERVE()` function, it is possible to begin usage with following code piece. - -```cpp -// String_Variable is variable of String type -// Alloc_Size is memory to be pre-allocated in number of Bytes with unsigned int type -String_Variable.reserve(Alloc_Size); -``` - -***For more information about the `RESERVE()` function, please check out [here](https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/reserve/)*** - -#### Buffer Size Control -Backend processes also requires memory pool for its processing purpose. It is something in which the machine will work on according to the size of the memory pool defined. This Buffer size can be user defined, meaning it can be can reduced to allocate lower memory size. It is similar to defining Array size, in which it is important not to allocate excessive size when it will use only third portion of the defined size. - -In between backend services, Serial communication defines the needed memory pool as Serial Buffer Size. Bigger serial buffer assists in establishing high speed communication, relative to the device that is interchanging data stream. If high speed communication is not part of the requiremente, the buffer size can be redefined to save some memory consumption. This is possible to do so by modifying the `HardwareSerial.h` that comes with Arduino IDE compiler, searching the following line. - -```cpp -#define SERIAL_TX_BUFFER_SIZE 64 - -#define SERIAL_RX_BUFFER_SIZE 64 -``` - -Libraries, or external modules that involve in code architecture development, also uses Buffer pool for better computing performance. Although, depending on the requirement, smooth performance might be cherry on top for the code architecture that is being developed. It is feasible to modify the buffer size that is designated in the library code. - -#### Corrective Data Type Usage -Implementation of adequate data type leads to a good overall code architecture. It may be desirable for the developer to use easiest or the most accessible data type to handle the data stream. However, it is important to consider the amount of memory space that it takes up when using certain data types. - -The Data Types exist to ease data stream format and to be handled without making illegal access. The illegal access in terms of data types are meant when the data is handled in the code with incompatible format. So it is a good practice to not to abuse the the data type and use only convenient types for every data bits. Rather, design and allocate memory carefully according to the requirements, which will help to reserve some memory space if further designed tasks needs extra space. - -Following table shows some of the existing data types to opt out for more options. - -| Data Type | Byte Size | Range | Format Specifier | -| :--------------------: | :---------: | :-----------------------------------: | :-----------------: | -| **char, signed char** | 1 | -128 ~ 127 | %c | -| **unsigned char** | 1 | 0 ~ 255 | %c | -| **int, signed int** | 2 , 4 | -32,768 ~ 32,767 | %d, %i | -| **unsigned int** | 2 , 4 | 0 ~ 65,535 | %u | -| **signed short int** | 2 | -32,768 ~ 32,767 | %hd | -| **unsigned short int** | 2 | 0 ~ 65,535 | %hu | -| **long int** | 4 | -2,147,483,648 ~ 2,147,483,647 | %ld, %li | -| **long long int** | 8 | -(2^63-1) ~ 2^63-1 (C99 Standard) | %lld, %lli | -| **unsigned long int** | 4 | 0 to 4,294,967,295 | %lu | -| **unsigned long long int** | 8 | 2^64-1 (C99 standard) | %llu | -| **float** | 4 | 1E-37 ~ 1E+37 + 6 Digit Precision | %f | -| **double** | 8 | 1E-37 ~ 1E+37 + 10 Digit Precision | %lf | -| **long double** | 10 | 1E-37 ~ 1E+37 + 10 Digit Precision | %Lf | -​ -### EEPROM Memory Optimization - -EEPROM memory optimization usually is not required, as it will be used mainly to store external module tuning constant. The data which are to be used by EEPROM space are the ones does not really need Flash memory as storage source. On top of it, it is not a good practice to offload SRAM data on EEPROM space. SRAM data are placed within volatility in mind, so offloading to EERPOM space, which is non-volatile memory, will mean the offloaded data will be engraved into EEPROM space. As result, the it is impractical use of storage and the variable will change in its value, making the old data unusable. - -One thing to consider with EEPROM is the read and write operation cycles. With EEPROM, it is crucial to know that write operation is limited. The read operation is unlimited for EEPROM. However, the write operation is finite and capped to 100,000 cycles of operation usually. Thus, it is important to save only parameters that are absolutely important for sensors or modules to work with mostly unchanging data. Additionally avoid implementing in a loop code, to avoid constant write operation, as it will wipe out, most likely in instant. - -### EEPROM Emulation with Flash Memory. - -As EEPROM is limited with write operatin cycle, it also applies same to Flash memory. Both of them are subjected to loss of data retention after the manufacturer's defined life cycle. EEPROM is based of NOR type memory, while the Flash memory is NAND type, making the EEPROM more costly than Flash memory. EEPROM works by accessing the data byte-wise, whereas Flash memory accesses block by block. - -Sometimes the developer would have to use the EEPROM as an alternative storage for task operations, but we clearly know that it will be impractical coding due to its size and behaviour properties. To solve this, it is possible to use Flash memory to emulate the EEPROM. Thanks to `FlashStorage` library created by Chrisitan Maglie, it is possible to emulate the EEPROM by using Flash memory. - -***`FlashStorage` library by Christian Maglie can be accessed by [here](https://github.com/cmaglie/FlashStorage)*** - -Above library will help you to use the Flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As it is for EEPROM, the Flash memory is also limited in write operation cycle. With two new additional functions stated in the library, one of them being `EEPROM.commit()` should not be called inside a loop function. Otherwise, it will wipe out the Flash memory's write operation cycles, thus loss of data retention ability. - -## Tips & Troubleshooting - -Notice that with boards that do not have a lot of SRAM available, like the UNO. It's easy to use it all up by having lots of strings in your program. For example, a declaration like: -```arduino -char message[] = "I support the Cape Wind project."; -``` - -puts 33 bytes into SRAM (each character ta|kes a byte, plus the '\0' terminator). This might not seem like a lot, but it doesn't take long to get to 2048, especially if you have a large amount of text to send to a display, or a large lookup table, for example. - -If you run out of SRAM, your program may fail in unexpected ways; it will appear to upload successfully, but not run, or run strangely. To check if this is happening, you can try commenting out or shortening the strings or other data structures in your sketch (without changing the code). If it then runs successfully, you're probably running out of SRAM. There are a few things you can do to address this problem: - -- If your sketch talks to a program running on a (desktop/laptop) computer, you can try shifting data or calculations to the computer, reducing the load on the Arduino. - -- If you have lookup tables or other large arrays, use the smallest data type necessary to store the values you need; for example, an [int](/en/Reference/Int) takes up two bytes, while a [byte](arduino.cc/en/Reference/Byte) uses only one (but can store a smaller range of values). - +--- +title: 'Arduino Memory Guide' +description: 'Learn about the built-in memory blocks of Arduino® boards in this article.' +tags: + - ROM + - RAM + - Flash + - SRAM + - EEPROM +author: 'José Bagur, Taddy Chung' +--- + +A microcontroller unit (also known as MCU) is an integrated circuit (IC) typically used to perform specific applications or tasks. Usually, this type of IC gathers information or data from its surroundings, process it, and generates specific outputs according to the gathered data. Microcontrollers today are everywhere; they are an essential part of modern embedded systems that can be found practically everywhere in our world, from smartwatches to electric vehicles; they are even on the Martian surface right now. + +One essential part of a microcontroller is its **memory**; memory stores information temporarily or permanently in microcontrollers and can be used for several purposes. This article talks about memory organization in microcontrollers, focusing on those present in Arduino® boards. Also, several ways to manage, measure, and optimize memory usage in Arduino-based systems are discussed in the article. + +## What is Memory? + +Memory blocks are essential parts of modern embedded systems, especially microcontroller-based ones. **Memory blocks are semiconductor devices that store and retrieve information or data**; a microcontroller central processing unit (CPU) uses and processes data stored in memory blocks to perform specific tasks. + +As shown in the image below, memory blocks in microcontrollers are usually described as **arrays**. Memory arrays are divided into **cells** that can store data and be accessed using a unique identifier representing its **address** or position relative to the memory array. Information in memory cells is stored using binary digits (bits), usually organized in bytes (8-bits); it can also be retrieved later by the MCU or other components of a microcontroller-based system. + +Memory in computing systems can be **volatile** or **non-volatile**. **Volatile memory is a temporary memory**, this means that data is stored while the system is running, but it is lost forever when the system is turned off. **Non-volatile memory is permanent memory**; data is not lost even if the system is turned off. + +## Memory Architectures 101 + +Computer architecture is a vast topic; we will focus on a general picture that will let us understand how memory is organized in the microcontrollers used in Arduino® boards. + +In the early days of computing, two computer architectures, i.e., the organization of the components inside a computing system, emerged: **von Neumann** and **Harvard**. + +### Von Neumann Architecture + +The von Neumann architecture, named after the mathematician, physicist, and computer scientist John von Neumann, was first introduced in the mid-'40s; it is also known as the Princeton architecture. T**his architecture stores program data and instructions in the same memory unit**; **both are accessed by the CPU using the same communications bus**, as shown below. Von Neumann's architecture is fundamental since nearly all digital computers design have been based on this architecture. + +### Harvard Architecture + +The Harvard architecture, named after the Harvard Mark I relay-based computer, was first introduced in the mid-'40s. **This architecture's main characteristic is that it uses two separate memory units**, **one for storing program instructions and one for storing program data**. Both memory units in the Harvard architecture are accessed by the CPU using different communication buses. + +### Modern Architectures: Hybrids + +Modern computing systems use **hybrid architectures** models that maximize performance using the best of both worlds, the von Neumann and the Harvard models. + +Microcontrollers are usually used in embedded applications. They must perform defined tasks reliably and efficiently, with low or constrained resources; this is why the **Harvard architecture model is mainly used in microcontrollers**: microcontrollers have a small program and data memory that needs to be accessed simultaneously. However, Harvard architecture is not always used in microcontrollers; some microcontroller families use hybrid or Von Neumann architecture models. + +### Arduino® Boards Architectures + +Arduino® boards are mainly based on two families of microcontrollers: **AVR®** and **ARM®**. While AVR® family microcontrollers are based on the Harvard architecture model, ARM® family microcontrollers can be based on either von Neuman or Harvard architectures models. The following table summarizes Arduino boards microcontrollers architectures: + +| **Board** | **Microcontroller** | **Family** | **Architecture** | +|:-------------------:|:-------------------:|:----------------:|:----------------:| +| UNO Mini | ATmega328P | AVR | Harvard | +| UNO Rev3 | ATmega328P | AVR | Harvard | +| UNO WiFi Rev2 | ATmega4809 | AVR | Harvard | +| UNO Rev3 SMD | ATmega328P | AVR | Harvard | +| Leonardo | ATmega32u4 | AVR | Harvard | +| Mega 2560 Rev3 | ATmega2560 | AVR | Harvard | +| Micro | ATmega32u4 | AVR | Harvard | +| Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| Portenta H7 | STM32H747 | ARM Cortex M4/M7 | Harvard | +| Nicla Sense ME | nRF52832 | ARM Cortex M4 | Harvard | +| Nano RP2040 Connect | RP2040 | ARM Cortex M0+ | Von Neumann | +| MKR FOX 1200 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| MKR NB 1500 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| MKR Vidor 4000 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| MKR WiFi 1010 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| MKR Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| MKR1000 WIFI | ATSAMW25H18 | ARM Cortex M0+ | Von Neumann | +| MKR WAN 1300 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| MKR WAN 1310 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| Nano | ATmega328P | AVR | Harvard | +| Nano Every | ATmega4809 | AVR | Harvard | +| Nano 33 IoT | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | +| Nano 33 BLE | nRF52840 | ARM Cortex M4 | Harvard | +| Nano 33 BLE Sense | nRF52840 | ARM Cortex M4 | Harvard | + +## Types of Memories + +Now, let us talk about the different memory units present on microcontrollers. All the different memory units inside a microcontroller can be divided into two main types: **RAM** and **ROM**. RAM (from Random-Access Memory) in microcontroller-based systems is a volatile memory used to store temporary data such as the system's firmware variables. ROM (from Read-Only Memory) in microcontroller-based systems is non-volatile memory used to store permanent data such as the system's firmware. + +RAM and ROM in microcontroller-based systems are organized into three main categories: + +* Flash +* RAM +* EEPROM + +Let us talk more about these types of memories. + +### Flash + +Flash memory in microcontroller-based systems is part of its ROM. The **Flash memory is where the system's firmware is stored to be executed**. For example, think of the famous `Blink.ino` example sketch, when we compile this sketch, we create a binary file that is later stored into the Flash memory of an Arduino board and executed when power on. + +### RAM + +**RAM** in microcontroller-based systems **is where the system's temporary data or run-time data is stored**. A microcontroller's RAM usually is SRAM; this is a type of RAM that uses a flip-flop to store one bit of data. For example, the variables created by functions. + +### EEPROM + +In microcontroller-based systems, Erasable Programmable Read-Only Memory, or EEPROM, is also part of its ROM; actually, Flash memory is a type of EEPROM. **The main difference between Flash memory and EEPROM is how they are managed**; EEPROM can be managed at the byte level (write or erased) while Flash can be managed at the block level. + +## Arduino® Boards Memory Allocation + +As stated before, Arduino® boards are mainly based on two families of microcontrollers, AVR® and ARM®; it is important to know that **memory allocation differs in both architectures**. In Harvard-based AVR architecture, memory is organized as shown in the image below: + +Something important to mention about AVR-based Arduino boards is how their SRAM is organized into different sections: + +- `Text` +- `Data` +- `BSS` +- `Stack` +- `Heap` + +The `text` section contains instructions loaded into the flash memory; `data` section contains variables initialized in the sketch, `BSS` section contains uninitialized data, `stack` section stores data of functions and interrupts, and `heap` section stores variables created during run time. + +In hybrid ARM architectures, memory is organized as shown in the image below: + +Arduino Pro Family's Portenta H7 is built with an ARM architecture microcontroller. This architecture is renowned for implementing a so-called memory map, with different address map configurations of 32-bit, 36-bit, and 40-bit that depend on the System On a Chip (SoC) address space with extra DRAM. The Memory Map grants interface with SoC design while having most system control on a high-level coding. Memory access instructions can be used on high-level code to manage interrupt modules and built-in peripherals—all of this controlled by Memory Management Unit (MMU). + +The Memory Management Unit (MMU) uses translation tables to establish a bridge between virtual and physical addresses. The Virtual Address is composed of Kernel and application in data and code blocks; the Physical Address controls peripherals, Flash, SRAM, and ROM. Table Walk Unit and Translation Lookaside Buffers (TLBs) are two main pieces of MMU. Table Walk Unit implements an algorithm that interprets the translation table, while the TLBs hold the most recent translations for future uses derived from the Table Walk Unit. + +Simply put, the Virtual Address is managed via software with memory instructions, and the Physical address is the memory system that is controlled depending on the Translation Table input given by the Virtual Address. + +The following table summarizes the Arduino® board's memory allocation: + +| **Board** | **Microcontroller** | **Family** | **Architecture** | **Flash** | **SRAM** | **EEPROM** | +|:-------------------:|:-------------------:|:----------------:|:----------------:|:---------:|:--------:|:----------:| +| UNO Mini | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | +| UNO Rev3 | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | +| UNO WiFi Rev2 | ATmega4809 | AVR | Harvard | 48kB | 6kB | 256B | +| UNO Rev3 SMD | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | +| Leonardo | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | +| Mega 2560 Rev3 | ATmega2560 | AVR | Harvard | 256kB | 8kB | 4kB | +| Micro | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | +| Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| Portenta H7 | STM32H747 | ARM Cortex M4/M7 | Harvard | 16MB | 8MB | - | +| Nicla Sense ME | nRF52832 | ARM Cortex M4 | Harvard | 512kB | 64kB | - | +| Nano RP2040 Connect | RP2040 | ARM Cortex M0+ | Von Neumann | - | 264kB | - | +| MKR FOX 1200 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR NB 1500 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR Vidor 4000 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR WiFi 1010 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR1000 WIFI | ATSAMW25H18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR WAN 1300 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR WAN 1310 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| Nano | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | +| Nano Every | ATmega4809 | AVR | Harvard | 48kB | 6kB | 256B | +| Nano 33 IoT | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| Nano 33 BLE | nRF52840 | ARM Cortex M4 | Harvard | 1MB | 256kB | - | +| Nano 33 BLE Sense | nRF52840 | ARM Cortex M4 | Harvard | 1MB | 256kB | - | + +## Measuring Memory Usage in Arduino Boards + +Memory usage statistics help comprehend the insight of resource management affected by the designed code structure. Memory load demand is one statistic that will give you an insight into how efficient the code is design|ed. It is a crucial development consideration element because the resources are finite inside a microcontroller-based system; **software should always perform without reaching maximum load capacity to avoid problems or issues**. Memory load could be observed either as **available RAM** at disposal for specific tasks or **Flash storage remaining capacity** for required headroom. +​ +### SRAM & DRAM: Quick Differentiation Specification + +Embedded devices compose of **Static Random Access Memory (SRAM)** and **Dynamic Random Access Memory (DRAM)**. These are 2 different derivatives that shapes the Random Access Memory (RAM). Both RAM types has trade-off in between them, and it is based on speed, physical size and manufacturing cost. + +- SRAM performs much faster than DRAM has to propose. In Read, Write and Access speed. +- SRAM is much more expensive in terms of manufacturing cost than DRAM. +- DRAM offers more friendly physical size, in terms of storage capacity, than SRAM. + +While these are 2 types of RAM that are found within embedded devices, optimization process that will be stated in the following are applicable as a whole. No matter which type of RAM is on-board, it can be controlled to achieve efficient memory management with careful design factors in mind. + +Ultimately, it should not be abused whatsoever, because even if the code might produce results, the system may be filled with a lot of memory handling flaws causing unstable on-the-edge software. The fix or patch that are applied later, might cost entire code architecture re-design. + +### Flash Memory Measurement + +The Flash memory on Arduino boards can be measured with the help of the Arduino IDE. As the Flash memory is where the Application code is stored, the Arduino IDE will report through output log to let the developer know how much resource is being used. + +This is the output log format for Arduino Nano. + +![Flash Memory Usage - Arduino Nano [AVR]](assets/avr_nano.png) + +This is the output log format for Arduino MKR WAN 1310. + +![Flash Memory Usage - Arduino MKR WAN 1310 [ARM]](assets/arm_mkrwan1310.png) + +This is the output log format for Arduino Portenta H7. + +![Flash Memory Usage - Arduino Portenta H7 (ABX00042) [ARM]](assets/arm_portentah7.png) + +Each image of Arduino IDE is based of selected three different Arduino boards, in which one is based on AVR and the other two is based of ARM architecture. The compiler will output a log where how much Flash resource is used when uploading the code. + +The purpose of these three images for different boards is to show that for each Arduino board family, the output log format is little different from one another; but it will show you the memory consumption information regarding the uploaded code. + +***If it is required to handle the Flash memory within high level code, please read more about in [this](https://docs.arduino.cc/tutorials/portenta-h7-lite/por-ard-flash) using Arduino Portenta H7*** + +### SRAM Memory Measurement + +The code may compile, upload and run. However, there may be situations in which the program will suffer from sudden operation halt. Thys type of issues are likely due to memory resource hogging or not enough memory to allocate. To solve this, it will require to understand in which sector of the code, the memory demand is going beyond the available resources. Following code fragment will help you measure the SRAM usage at a high level code. + +```cpp +void display_freeram(){ + Serial.print(F("SRAM left")); + Serial.println(freeRam()); +} + +int freeRam() { + extern int __heap_start,*__brkval; + int v; + return (int)&v - (__brkval == 0 + ? (int)&__heap_start : (int) __brkval); +} +``` + +In the code, `__heap_start` and `__brkval` are as following: +- **`__heap_start`**: Refers to beginning of the Heap. +- **`__brkval`**: Last memory address pointer used by Heap. It is pointing towards the Stack. + +### EEPROM Memory Measurement + +EEPROM features are already included with the Arduino IDE platform so it does not require additional step to install any library to use its features. + +EEPROM memory measurement can be done through use of the following simple code fragment. The code is simplified to write a byte to know exactly which address it is reading from. It can be modified to read everything from every available possible address. + +```cpp +#include + +EEPROM.write(address, value); +EEPROM.read(address); +``` + +On the other hand, it is possible to clear the entire EEPROM memory to set it to 0. + +```cpp +#include + +... + +for (int i = 0 ; i < EEPROM.length() ; i++) { + EEPROM.write(i, 0); +} + +... +``` + +The complete example codes can be found in our guide to EEPROM found below the following code. + +***For more information on how to manage the EEPROM memory, please read [here](https://docs.arduino.cc/learn/programming/eeprom-guide)*** + +## Optimizing Memory Usage in Arduino-based Systems +Knowing how the code utilizes the memory resources is one matter, but to optimize the memory is a whole different task. As the term development may infer, the requirements may change or be adjusted depending on external factors such as reduced device capacity due to inavailability of the components. Thus the code architecture may require optimization to be able to run on the reduced limited memory resources. + +The optimization process also implies reduced computational complexities, trimming down extra time required to process the tasks while using less memory resource to do the same task. The memory optimization process may help the overall code optimization process, as it will handle how the memory is managed in a more suitable manner by requiring smart algorithm development. + +### Flash Memory Optimization + +Flash memory optimization is the most likely the straightforward optimization possible source to begin with. The Flash memory is where the capacity used by compiled code can be reduced greatly by considering some details. + +#### Detach Unused Sources +Detaching unused sources include unused libraries, and code residues. Code residues can be composed of functions that are no longer used and floating variables that takes up the unnecessary space in memory. This will vastly improve the compiled code size and make more clear compilation process. + +#### Modular Tasks +Modular tasks mean functions that wraps the code which will be used in a repetitive or continuous manner by receiving different parameters. It is a great way to maintain clean code structure and performance, while reducing the memory space required for additional tasks that might need to be implemented. + +This leads to compact code structure, that is much easier to understand when debugging process is required, and demand developer to considerate compute complexity when designing the code structure or such specific algorithm. + +### SRAM Memory Optimization + +#### String Wrapper - F() +It is convenient to use `Serial.println("Something");` to display the literals. This is used usually to understand where the code is going and to observe certain conditionals. However, doing this so will hog up the Static Random Access Memory (SRAM) space, which is something not desirable as the content is a simple literal string that is not used under the hood. + +The ideal way to use the Print Line command is to use the `F()` String Wrapper around the literals. This will lead us to following piece of code. + +```cpp +Serial.println(F("Something")); +``` + +By wrapping the String with `F()`, will move the Strings to Flash memory only rather than to use SRAM space also. It can be observed as offloading such data to Flash memory instead of SRAM. + +Flash memory is much more spacious than SRAM size, so it is better to use the Flash space than using SRAM which will use Heap. This does not mean the memory space will always be available, as Flash memory does have limited space too. It is not recommendable to cloag the code structure with Print Line, but to use them where they most matter for such applications with minimized implementation. + +#### PROGMEM +It is not always with the literal String that occupies the SRAM space, but also using Global Variables which also takes up quite good amount of SRAM. As Global and Static variables are streamed to SRAM space, and pushes the Heap towards the Stack. The space occupied by this variables streamed to SRAM space will be saved at its location and will not be changing, meaning more of these variables are created, they will use more space and consequently, system failure due to low and poor memory management. + +PROGMEM stands simply for **Program Memory**. We will use Program memory to store variable data offloading to Flash Memory space. As it goes same as to String Wrapper F(), PROGMEM uses Flash Memory space for its implementation. The only disadvantage presented using PROGMEM is the Read Speed. Using RAM will provide much faster Read Speed, but PROGMEM, as it uses Flash Memory, it will be slower than RAM, given the same data size. Thus, it is important to design the software knowing which variables are crucial and which has lower priority. It is one of the many factors that needs to be considered when developing the software, but this will lead to have nicely designed code architecture. + +To use the PROGMEM, it can begin with following code fragment. + +```cpp +#include + +// Basic PROGMEM Define Structure +const PROGMEM DataType Variable_Name[] = {var0, var1, var2 ...}; + +// Unsigned 16 Bit int +const PROGMEM uint16_t NumSet[] = {0, 1, 1, 2, 3, 5, 8 ...}; + +// Storing Char +const char greetMessage[] PROGMEM = {"Hello There"}; +``` + +***For In-Depth detail about PROGMEM, please read [here](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/)*** + +#### Non Dynamic Memory Allocation +Dynamic Memory Allocation usually is a good method if the given RAM size is big enough to get around with, from MegaBytes and so on. However, for embedded devices counting every Byte of the RAM, the process becomes hostile for RAM. + +Dynamic Memory Allocations cause **Heap fragmentation**. With heap fragmentation, many areas of the RAM affected by it cannot reused again, leaving dead Byte that can be taken as an advantage for other tasks. On top of it, when dynamic allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the Heap Size. So to avoid Heap or RAM fragmentation as much as possible, you can follow following rules to apply into code architecture design. + +- Prioritize using **Stack** than **Heap** if possible to do so. + - Stack memory is fragmentation free and can be freed up completely when the function returns. Heap in contrast ma not free up the space even though it was instructed to do so. Using Local Variables will help to do this and try not to use dynamic memory allocation, composed of different calls: `malloc, calloc, realloc`. + +- Reduced Global and Static Data if possible to do so. + - Meantime the code is running, memory area occupied by these data will not be freed up. Meaning the data won't be modified as it is constant data taking up the precious space. + +- Short Strings / Literals + - It is good practice to keep the literal Strings as short as possible. Single char takes **One** Byte of RAM, so shorter the better memory space usage. This does not mean, keeping it short and using it in several different areas of the code is possible. Use it when it is absolutely required and keep as short as possible to spare RAM space for other task functions. + + - Arrays are also recommended to be at a minimum size. If it requires to resize the array, you can always re-set the array size in the code. It may be a tedious, also non-efficient method to hard-code the array sizes. But if the code utilizes small array sizes and less than 3 arrays, it may be suffice via manual resizing, knowing the requirements. A smart way to do this is resizeable array with limited size. In which the tasks will use the array without going over the size boundary, thus it is suitable for extensive code size. Although, the limit of the array size must be analyzed and kept as small as possible. + +#### RESERVE() +If the tasks work with the Strings, that changes in its size depending on the operation outcome, `RESERVE()` is way to go. This function will help to reserve buffer space and pre-allocate for String variable, which changes in its size, and avoid fragmentation. String variable that changes in its size could be a result of `int` type variable wrapped to be used as a `String` for example. + +To use the `RESERVE()` function, it is possible to begin usage with following code piece. + +```cpp +// String_Variable is variable of String type +// Alloc_Size is memory to be pre-allocated in number of Bytes with unsigned int type +String_Variable.reserve(Alloc_Size); +``` + +***For more information about the `RESERVE()` function, please check out [here](https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/reserve/)*** + +#### Buffer Size Control +Backend processes also requires memory pool for its processing purpose. It is something in which the machine will work on according to the size of the memory pool defined. This Buffer size can be user defined, meaning it can be can reduced to allocate lower memory size. It is similar to defining Array size, in which it is important not to allocate excessive size when it will use only third portion of the defined size. + +In between backend services, Serial communication defines the needed memory pool as Serial Buffer Size. Bigger serial buffer assists in establishing high speed communication, relative to the device that is interchanging data stream. If high speed communication is not part of the requiremente, the buffer size can be redefined to save some memory consumption. This is possible to do so by modifying the `HardwareSerial.h` that comes with Arduino IDE compiler, searching the following line. + +```cpp +#define SERIAL_TX_BUFFER_SIZE 64 + +#define SERIAL_RX_BUFFER_SIZE 64 +``` + +Libraries, or external modules that involve in code architecture development, also uses Buffer pool for better computing performance. Although, depending on the requirement, smooth performance might be cherry on top for the code architecture that is being developed. It is feasible to modify the buffer size that is designated in the library code. + +#### Corrective Data Type Usage +Implementation of adequate data type leads to a good overall code architecture. It may be desirable for the developer to use easiest or the most accessible data type to handle the data stream. However, it is important to consider the amount of memory space that it takes up when using certain data types. + +The Data Types exist to ease data stream format and to be handled without making illegal access. The illegal access in terms of data types are meant when the data is handled in the code with incompatible format. So it is a good practice to not to abuse the the data type and use only convenient types for every data bits. Rather, design and allocate memory carefully according to the requirements, which will help to reserve some memory space if further designed tasks needs extra space. + +Following table shows some of the existing data types to opt out for more options. + +| Data Type | Byte Size | Range | Format Specifier | +| :--------------------: | :---------: | :-----------------------------------: | :-----------------: | +| **char, signed char** | 1 | -128 ~ 127 | %c | +| **unsigned char** | 1 | 0 ~ 255 | %c | +| **int, signed int** | 2 , 4 | -32,768 ~ 32,767 | %d, %i | +| **unsigned int** | 2 , 4 | 0 ~ 65,535 | %u | +| **signed short int** | 2 | -32,768 ~ 32,767 | %hd | +| **unsigned short int** | 2 | 0 ~ 65,535 | %hu | +| **long int** | 4 | -2,147,483,648 ~ 2,147,483,647 | %ld, %li | +| **long long int** | 8 | -(2^63-1) ~ 2^63-1 (C99 Standard) | %lld, %lli | +| **unsigned long int** | 4 | 0 to 4,294,967,295 | %lu | +| **unsigned long long int** | 8 | 2^64-1 (C99 standard) | %llu | +| **float** | 4 | 1E-37 ~ 1E+37 + 6 Digit Precision | %f | +| **double** | 8 | 1E-37 ~ 1E+37 + 10 Digit Precision | %lf | +| **long double** | 10 | 1E-37 ~ 1E+37 + 10 Digit Precision | %Lf | +​ +### EEPROM Memory Optimization + +EEPROM memory optimization usually is not required, as it will be used mainly to store external module tuning constant. The data which are to be used by EEPROM space are the ones does not really need Flash memory as storage source. On top of it, it is not a good practice to offload SRAM data on EEPROM space. SRAM data are placed within volatility in mind, so offloading to EERPOM space, which is non-volatile memory, will mean the offloaded data will be engraved into EEPROM space. As result, the it is impractical use of storage and the variable will change in its value, making the old data unusable. + +One thing to consider with EEPROM is the read and write operation cycles. With EEPROM, it is crucial to know that write operation is limited. The read operation is unlimited for EEPROM. However, the write operation is finite and capped to 100,000 cycles of operation usually. Thus, it is important to save only parameters that are absolutely important for sensors or modules to work with mostly unchanging data. Additionally avoid implementing in a loop code, to avoid constant write operation, as it will wipe out, most likely in instant. + +### EEPROM Emulation with Flash Memory. + +As EEPROM is limited with write operatin cycle, it also applies same to Flash memory. Both of them are subjected to loss of data retention after the manufacturer's defined life cycle. EEPROM is based of NOR type memory, while the Flash memory is NAND type, making the EEPROM more costly than Flash memory. EEPROM works by accessing the data byte-wise, whereas Flash memory accesses block by block. + +Sometimes the developer would have to use the EEPROM as an alternative storage for task operations, but we clearly know that it will be impractical coding due to its size and behaviour properties. To solve this, it is possible to use Flash memory to emulate the EEPROM. Thanks to `FlashStorage` library created by Chrisitan Maglie, it is possible to emulate the EEPROM by using Flash memory. + +***`FlashStorage` library by Christian Maglie can be accessed by [here](https://github.com/cmaglie/FlashStorage)*** + +Above library will help you to use the Flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As it is for EEPROM, the Flash memory is also limited in write operation cycle. With two new additional functions stated in the library, one of them being `EEPROM.commit()` should not be called inside a loop function. Otherwise, it will wipe out the Flash memory's write operation cycles, thus loss of data retention ability. + +## Tips & Troubleshooting + +Notice that with boards that do not have a lot of SRAM available, like the UNO. It's easy to use it all up by having lots of strings in your program. For example, a declaration like: +```arduino +char message[] = "I support the Cape Wind project."; +``` + +puts 33 bytes into SRAM (each character ta|kes a byte, plus the '\0' terminator). This might not seem like a lot, but it doesn't take long to get to 2048, especially if you have a large amount of text to send to a display, or a large lookup table, for example. + +If you run out of SRAM, your program may fail in unexpected ways; it will appear to upload successfully, but not run, or run strangely. To check if this is happening, you can try commenting out or shortening the strings or other data structures in your sketch (without changing the code). If it then runs successfully, you're probably running out of SRAM. There are a few things you can do to address this problem: + +- If your sketch talks to a program running on a (desktop/laptop) computer, you can try shifting data or calculations to the computer, reducing the load on the Arduino. + +- If you have lookup tables or other large arrays, use the smallest data type necessary to store the values you need; for example, an [int](/en/Reference/Int) takes up two bytes, while a [byte](arduino.cc/en/Reference/Byte) uses only one (but can store a smaller range of values). + - If you don't need to modify the strings or data while your sketch is running, you can store them in flash (program) memory instead of SRAM; to do this, use the [PROGMEM](arduino.cc/en/Reference/PROGMEM) keyword. \ No newline at end of file From 8f30fc6aed8fca14a367e8ab10f256ac383795ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Fri, 1 Apr 2022 10:37:08 -0400 Subject: [PATCH 21/36] Update tutorial content --- .../06.memory-guide/memory-guide.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 7d387cea0b..3d5bbcf5cc 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -111,13 +111,14 @@ Something important to mention about AVR-based Arduino boards is how their SRAM The `text` section contains instructions loaded into the flash memory; `data` section contains variables initialized in the sketch, `BSS` section contains uninitialized data, `stack` section stores data of functions and interrupts, and `heap` section stores variables created during run time. -In hybrid ARM architectures, memory is organized as shown in the image below: +In hybrid ARM architectures, memory is handled by the **Memory Management Unit** (MMU). The main role of the MMU is to enable the processor to run multiple tasks independently in its own virtual memory space; the MMU then uses translation tables to establish a bridge between the virtual and the physical memory addresses. An example of how memory is organized in ARM-based microcontrollers, virtually and physically, is shown in the image below: -Arduino Pro Family's Portenta H7 is built with an ARM architecture microcontroller. This architecture is renowned for implementing a so-called memory map, with different address map configurations of 32-bit, 36-bit, and 40-bit that depend on the System On a Chip (SoC) address space with extra DRAM. The Memory Map grants interface with SoC design while having most system control on a high-level coding. Memory access instructions can be used on high-level code to manage interrupt modules and built-in peripherals—all of this controlled by Memory Management Unit (MMU). +Usually, memory in ARM-based microcontroller is organized into the following sections: -The Memory Management Unit (MMU) uses translation tables to establish a bridge between virtual and physical addresses. The Virtual Address is composed of Kernel and application in data and code blocks; the Physical Address controls peripherals, Flash, SRAM, and ROM. Table Walk Unit and Translation Lookaside Buffers (TLBs) are two main pieces of MMU. Table Walk Unit implements an algorithm that interprets the translation table, while the TLBs hold the most recent translations for future uses derived from the Table Walk Unit. - -Simply put, the Virtual Address is managed via software with memory instructions, and the Physical address is the memory system that is controlled depending on the Translation Table input given by the Virtual Address. +- `System` +- `Peripherals` +- `ROM` +- `RAM` The following table summarizes the Arduino® board's memory allocation: @@ -131,7 +132,7 @@ The following table summarizes the Arduino® board's memory allocation: | Mega 2560 Rev3 | ATmega2560 | AVR | Harvard | 256kB | 8kB | 4kB | | Micro | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | | Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| Portenta H7 | STM32H747 | ARM Cortex M4/M7 | Harvard | 16MB | 8MB | - | +| Porten ta H7* | STM32H747 | ARM Cortex M4/M7 | Harvard | 16MB | 8MB | - | | Nicla Sense ME | nRF52832 | ARM Cortex M4 | Harvard | 512kB | 64kB | - | | Nano RP2040 Connect | RP2040 | ARM Cortex M0+ | Von Neumann | - | 264kB | - | | MKR FOX 1200 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | @@ -151,6 +152,8 @@ The following table summarizes the Arduino® board's memory allocation: ## Measuring Memory Usage in Arduino Boards Memory usage statistics help comprehend the insight of resource management affected by the designed code structure. Memory load demand is one statistic that will give you an insight into how efficient the code is design|ed. It is a crucial development consideration element because the resources are finite inside a microcontroller-based system; **software should always perform without reaching maximum load capacity to avoid problems or issues**. Memory load could be observed either as **available RAM** at disposal for specific tasks or **Flash storage remaining capacity** for required headroom. + +Let us talk more about memory usage measurement in Arduino boards. ​ ### SRAM & DRAM: Quick Differentiation Specification From 98037b7d402ac1ebb773a4c4e366eeb38c3f67b8 Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Fri, 1 Apr 2022 16:19:43 -0600 Subject: [PATCH 22/36] Content Update --- .../06.memory-guide/memory-guide.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 3d5bbcf5cc..dee52206df 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -111,14 +111,22 @@ Something important to mention about AVR-based Arduino boards is how their SRAM The `text` section contains instructions loaded into the flash memory; `data` section contains variables initialized in the sketch, `BSS` section contains uninitialized data, `stack` section stores data of functions and interrupts, and `heap` section stores variables created during run time. -In hybrid ARM architectures, memory is handled by the **Memory Management Unit** (MMU). The main role of the MMU is to enable the processor to run multiple tasks independently in its own virtual memory space; the MMU then uses translation tables to establish a bridge between the virtual and the physical memory addresses. An example of how memory is organized in ARM-based microcontrollers, virtually and physically, is shown in the image below: +In hybrid ARM architectures, so called **Memory map** is implemented, with different address map configuration of 32-bit, 36-bit, and 40-bit that depends on the requirement of System On a Chip (SoC) address space with extra DRAM. The Memory Map grants interface with SoC design, while having most system control on a high level coding. Memory access instructions can be used on high level code to manage interrupt modules and built-in peripherals. All of this controlled by Memory Management Unit (MMU). -Usually, memory in ARM-based microcontroller is organized into the following sections: +The memory resource is handled by the **Memory Management Unit** (MMU). The main role of the MMU is to enable the processor to run multiple tasks independently in its own virtual memory space; the MMU then uses translation tables to establish a bridge between the virtual and the physical memory addresses. Virtual Address is managed via software with memory instructions, and Physical address is the memory system that is controlled depending on the Translation Table input given by the Virtual Address. +An example of how memory is organized in ARM-based microcontrollers, virtually and physically, is shown in the image below: -- `System` -- `Peripherals` +The ARM-based microcontroller's memory department is organized into the following sections respectively within the address type mentioned previously: + +- **Virtual Address** +- `Kernel Code & Data` +- `Application Code & Data` + +- **Physical Address** - `ROM` - `RAM` +- `Flash` +- `Peripherals` The following table summarizes the Arduino® board's memory allocation: From a22b51b1e043a4c5995ef1ef08416b776ef79e3d Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Fri, 1 Apr 2022 16:52:49 -0600 Subject: [PATCH 23/36] Minor Struct Update --- .../03.programming/06.memory-guide/memory-guide.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index dee52206df..4907bf76f6 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -119,14 +119,14 @@ An example of how memory is organized in ARM-based microcontrollers, virtually a The ARM-based microcontroller's memory department is organized into the following sections respectively within the address type mentioned previously: - **Virtual Address** -- `Kernel Code & Data` -- `Application Code & Data` + - `Kernel Code & Data` + - `Application Code & Data` - **Physical Address** -- `ROM` -- `RAM` -- `Flash` -- `Peripherals` + - `ROM` + - `RAM` + - `Flash` + - `Peripherals` The following table summarizes the Arduino® board's memory allocation: From 4b0bcb09ff22526f1be05800b50f23c0893c077c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20S=C3=B6derby?= <35461661+karlsoderby@users.noreply.github.com> Date: Tue, 5 Apr 2022 16:27:32 +0200 Subject: [PATCH 24/36] review part 1, until "memory types" --- .../06.memory-guide/memory-guide.md | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 4907bf76f6..a7d0362ca9 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -7,12 +7,12 @@ tags: - Flash - SRAM - EEPROM -author: 'José Bagur, Taddy Chung' +author: 'Arduino, José Bagur, Taddy Chung' --- -A microcontroller unit (also known as MCU) is an integrated circuit (IC) typically used to perform specific applications or tasks. Usually, this type of IC gathers information or data from its surroundings, process it, and generates specific outputs according to the gathered data. Microcontrollers today are everywhere; they are an essential part of modern embedded systems that can be found practically everywhere in our world, from smartwatches to electric vehicles; they are even on the Martian surface right now. +A microcontroller unit (also known as a MCU) is an integrated circuit (IC), typically used to perform specific applications or tasks. Usually, this type of IC gathers information or data from its surroundings, process it, and generates specific outputs according to the gathered data. Microcontrollers today are everywhere; they are an essential part of modern embedded systems that can be found practically everywhere in our world, from smartwatches to electric vehicles; they are even on the Martian surface right now. -One essential part of a microcontroller is its **memory**; memory stores information temporarily or permanently in microcontrollers and can be used for several purposes. This article talks about memory organization in microcontrollers, focusing on those present in Arduino® boards. Also, several ways to manage, measure, and optimize memory usage in Arduino-based systems are discussed in the article. +One essential part of a microcontroller is its **memory**; memory stores information temporarily or permanently in microcontrollers, and can be used for several purposes. In this article, we will explore memory organization in microcontrollers, focusing on those present in Arduino® boards. We will also explore several ways to manage, measure, and optimize memory usage in Arduino-based systems are discussed in the article. ## What is Memory? @@ -20,7 +20,7 @@ Memory blocks are essential parts of modern embedded systems, especially microco As shown in the image below, memory blocks in microcontrollers are usually described as **arrays**. Memory arrays are divided into **cells** that can store data and be accessed using a unique identifier representing its **address** or position relative to the memory array. Information in memory cells is stored using binary digits (bits), usually organized in bytes (8-bits); it can also be retrieved later by the MCU or other components of a microcontroller-based system. -Memory in computing systems can be **volatile** or **non-volatile**. **Volatile memory is a temporary memory**, this means that data is stored while the system is running, but it is lost forever when the system is turned off. **Non-volatile memory is permanent memory**; data is not lost even if the system is turned off. +Memory in computing systems can be **volatile** or **non-volatile**. Volatile memory is a **temporary memory**, this means that data is stored while the system is running, but it is lost forever when the system is turned off. Non-volatile memory is **permanent memory**; data is not lost even if the system is turned off. ## Memory Architectures 101 @@ -30,11 +30,13 @@ In the early days of computing, two computer architectures, i.e., the organizati ### Von Neumann Architecture -The von Neumann architecture, named after the mathematician, physicist, and computer scientist John von Neumann, was first introduced in the mid-'40s; it is also known as the Princeton architecture. T**his architecture stores program data and instructions in the same memory unit**; **both are accessed by the CPU using the same communications bus**, as shown below. Von Neumann's architecture is fundamental since nearly all digital computers design have been based on this architecture. +The von Neumann architecture, named after the mathematician, physicist, and computer scientist John von Neumann, was first introduced in the mid-'40s; it is also known as the Princeton architecture. This architecture stores program data and instructions in the same memory unit. + +Both are accessed by the CPU using the same communications bus, as shown below. Von Neumann's architecture is fundamental since nearly all digital computers design have been based on this architecture. ### Harvard Architecture -The Harvard architecture, named after the Harvard Mark I relay-based computer, was first introduced in the mid-'40s. **This architecture's main characteristic is that it uses two separate memory units**, **one for storing program instructions and one for storing program data**. Both memory units in the Harvard architecture are accessed by the CPU using different communication buses. +The Harvard architecture, named after the Harvard Mark I relay-based computer, was first introduced in the mid-'40s. This architecture's main characteristic is that it uses **two separate memory units**, one for storing program instructions and one for storing program data. Both memory units in the Harvard architecture are accessed by the CPU using different communication buses. ### Modern Architectures: Hybrids @@ -73,15 +75,15 @@ Arduino® boards are mainly based on two families of microcontrollers: **AVR®** | Nano 33 BLE | nRF52840 | ARM Cortex M4 | Harvard | | Nano 33 BLE Sense | nRF52840 | ARM Cortex M4 | Harvard | -## Types of Memories +## Memory Types Now, let us talk about the different memory units present on microcontrollers. All the different memory units inside a microcontroller can be divided into two main types: **RAM** and **ROM**. RAM (from Random-Access Memory) in microcontroller-based systems is a volatile memory used to store temporary data such as the system's firmware variables. ROM (from Read-Only Memory) in microcontroller-based systems is non-volatile memory used to store permanent data such as the system's firmware. RAM and ROM in microcontroller-based systems are organized into three main categories: -* Flash -* RAM -* EEPROM +- Flash +- RAM +- EEPROM Let us talk more about these types of memories. From bbd6e41d092eea9faff6cdcabd1bab027ba666b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Tue, 5 Apr 2022 10:31:26 -0600 Subject: [PATCH 25/36] Update tutorial content --- .../06.memory-guide/memory-guide.md | 203 ++++++++++-------- 1 file changed, 111 insertions(+), 92 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 4907bf76f6..24b913be3e 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -32,9 +32,13 @@ In the early days of computing, two computer architectures, i.e., the organizati The von Neumann architecture, named after the mathematician, physicist, and computer scientist John von Neumann, was first introduced in the mid-'40s; it is also known as the Princeton architecture. T**his architecture stores program data and instructions in the same memory unit**; **both are accessed by the CPU using the same communications bus**, as shown below. Von Neumann's architecture is fundamental since nearly all digital computers design have been based on this architecture. +**ADD IMAGE HERE** + ### Harvard Architecture -The Harvard architecture, named after the Harvard Mark I relay-based computer, was first introduced in the mid-'40s. **This architecture's main characteristic is that it uses two separate memory units**, **one for storing program instructions and one for storing program data**. Both memory units in the Harvard architecture are accessed by the CPU using different communication buses. +The Harvard architecture, named after the Harvard Mark I relay-based computer, was first introduced in the mid-'40s. **This architecture's main characteristic is that it uses two separate memory units**, **one for storing program instructions and one for storing program data**. Both memory units in the Harvard architecture are accessed by the CPU using different communication buses. + +**ADD IMAGE HERE** ### Modern Architectures: Hybrids @@ -91,7 +95,7 @@ Flash memory in microcontroller-based systems is part of its ROM. The **Flash me ### RAM -**RAM** in microcontroller-based systems **is where the system's temporary data or run-time data is stored**. A microcontroller's RAM usually is SRAM; this is a type of RAM that uses a flip-flop to store one bit of data. For example, the variables created by functions. +**RAM** in microcontroller-based systems **is where the system's temporary data or run-time data is stored**; for example, the variables created by functions of a program. RAM in microcontrollers usually is **SRAM**; this is a type of RAM that uses a flip-flop to store one bit of data. There is also another type of RAM that can be found in microcontrollers: DRAM. ### EEPROM @@ -101,7 +105,9 @@ In microcontroller-based systems, Erasable Programmable Read-Only Memory, or EEP As stated before, Arduino® boards are mainly based on two families of microcontrollers, AVR® and ARM®; it is important to know that **memory allocation differs in both architectures**. In Harvard-based AVR architecture, memory is organized as shown in the image below: -Something important to mention about AVR-based Arduino boards is how their SRAM is organized into different sections: +**ADD IMAGE HERE** + +Something important to mention about AVR-based Arduino boards is how their SRAM is organized into the following sections: - `Text` - `Data` @@ -111,18 +117,19 @@ Something important to mention about AVR-based Arduino boards is how their SRAM The `text` section contains instructions loaded into the flash memory; `data` section contains variables initialized in the sketch, `BSS` section contains uninitialized data, `stack` section stores data of functions and interrupts, and `heap` section stores variables created during run time. -In hybrid ARM architectures, so called **Memory map** is implemented, with different address map configuration of 32-bit, 36-bit, and 40-bit that depends on the requirement of System On a Chip (SoC) address space with extra DRAM. The Memory Map grants interface with SoC design, while having most system control on a high level coding. Memory access instructions can be used on high level code to manage interrupt modules and built-in peripherals. All of this controlled by Memory Management Unit (MMU). +In hybrid ARM architectures, a **memory map** is implemented with different address map configurations of 32-bit, 36-bit, and 40-bit. ARM's memory map grants an interface with the barebones of the microcontroller while having the most control over memory with high-level coding. Memory access instructions can be used on high-level code to manage interrupt modules and built-in peripherals—all of this controlled by the **Memory Management Unit** (MMU). The main role of the MMU is to enable the processor to run multiple tasks independently in its own virtual memory space; the MMU then uses translation tables to establish a bridge between the virtual and the physical memory addresses. Virtual memory is managed via software with memory instructions, and the physical address is the memory system that is controlled depending on the Translation Table input given by the Virtual Address. -The memory resource is handled by the **Memory Management Unit** (MMU). The main role of the MMU is to enable the processor to run multiple tasks independently in its own virtual memory space; the MMU then uses translation tables to establish a bridge between the virtual and the physical memory addresses. Virtual Address is managed via software with memory instructions, and Physical address is the memory system that is controlled depending on the Translation Table input given by the Virtual Address. An example of how memory is organized in ARM-based microcontrollers, virtually and physically, is shown in the image below: -The ARM-based microcontroller's memory department is organized into the following sections respectively within the address type mentioned previously: +**ADD IMAGE HERE** -- **Virtual Address** - - `Kernel Code & Data` - - `Application Code & Data` +The ARM-based microcontroller's memory is organized into the following sections within the address type mentioned previously: -- **Physical Address** +- **Virtual address:** + - `Kernel code and data` + - `Application code and data` + +- **Physical address:** - `ROM` - `RAM` - `Flash` @@ -140,7 +147,7 @@ The following table summarizes the Arduino® board's memory allocation: | Mega 2560 Rev3 | ATmega2560 | AVR | Harvard | 256kB | 8kB | 4kB | | Micro | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | | Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| Porten ta H7* | STM32H747 | ARM Cortex M4/M7 | Harvard | 16MB | 8MB | - | +| Portenta H7* | STM32H747 | ARM Cortex M4/M7 | Harvard | 16MB | 8MB | - | | Nicla Sense ME | nRF52832 | ARM Cortex M4 | Harvard | 512kB | 64kB | - | | Nano RP2040 Connect | RP2040 | ARM Cortex M0+ | Von Neumann | - | 264kB | - | | MKR FOX 1200 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | @@ -157,53 +164,41 @@ The following table summarizes the Arduino® board's memory allocation: | Nano 33 BLE | nRF52840 | ARM Cortex M4 | Harvard | 1MB | 256kB | - | | Nano 33 BLE Sense | nRF52840 | ARM Cortex M4 | Harvard | 1MB | 256kB | - | -## Measuring Memory Usage in Arduino Boards - -Memory usage statistics help comprehend the insight of resource management affected by the designed code structure. Memory load demand is one statistic that will give you an insight into how efficient the code is design|ed. It is a crucial development consideration element because the resources are finite inside a microcontroller-based system; **software should always perform without reaching maximum load capacity to avoid problems or issues**. Memory load could be observed either as **available RAM** at disposal for specific tasks or **Flash storage remaining capacity** for required headroom. - -Let us talk more about memory usage measurement in Arduino boards. -​ -### SRAM & DRAM: Quick Differentiation Specification +**ADD PRO NOTE HERE** -Embedded devices compose of **Static Random Access Memory (SRAM)** and **Dynamic Random Access Memory (DRAM)**. These are 2 different derivatives that shapes the Random Access Memory (RAM). Both RAM types has trade-off in between them, and it is based on speed, physical size and manufacturing cost. +## Measuring Memory Usage in Arduino® Boards -- SRAM performs much faster than DRAM has to propose. In Read, Write and Access speed. -- SRAM is much more expensive in terms of manufacturing cost than DRAM. -- DRAM offers more friendly physical size, in terms of storage capacity, than SRAM. +Memory usage statistics help comprehend the insight of resource management affected by the designed code structure. Memory load demand is one statistic that will give you an insight into how efficient the code is designed. It is a crucial development consideration element because the resources in microcontroller-based systems are constrained and finite. Memory load could be observed either as **available RAM** at disposal for specific tasks or **Flash storage remaining capacity** for required headroom. -While these are 2 types of RAM that are found within embedded devices, optimization process that will be stated in the following are applicable as a whole. No matter which type of RAM is on-board, it can be controlled to achieve efficient memory management with careful design factors in mind. +***To avoid run-time problems, microcontroller-based systems should always run without reaching their maximum memory capacity.*** -Ultimately, it should not be abused whatsoever, because even if the code might produce results, the system may be filled with a lot of memory handling flaws causing unstable on-the-edge software. The fix or patch that are applied later, might cost entire code architecture re-design. +Let us talk more about **memory usage measurement** in Arduino® boards. ### Flash Memory Measurement -The Flash memory on Arduino boards can be measured with the help of the Arduino IDE. As the Flash memory is where the Application code is stored, the Arduino IDE will report through output log to let the developer know how much resource is being used. - -This is the output log format for Arduino Nano. - -![Flash Memory Usage - Arduino Nano [AVR]](assets/avr_nano.png) +Flash memory on Arduino® boards can be measured with the help of the Arduino IDE. As stated before, Flash memory is where the application code is stored; **the Arduino IDE reports Flash memory usage through its compiler output console** to let developers know how much Flash memory resources are being used. -This is the output log format for Arduino MKR WAN 1310. +For example, the IDE's compiler output console an AVR-based Arduino® board, the UNO, with the `Blink.ino` example sketch uploaded, is shown in the image below: -![Flash Memory Usage - Arduino MKR WAN 1310 [ARM]](assets/arm_mkrwan1310.png) +![Flash memory memory measurement in an AVR-based Arduino® board](assets/avr_nano.png) -This is the output log format for Arduino Portenta H7. +The IDE's compiler output console log for an ARM-based Arduino® board, the MKR WAN 1310, is shown in the image below: -![Flash Memory Usage - Arduino Portenta H7 (ABX00042) [ARM]](assets/arm_portentah7.png) +![Flash memory memory measurement in an ARM-based Arduino® board](assets/arm_mkrwan1310.png) -Each image of Arduino IDE is based of selected three different Arduino boards, in which one is based on AVR and the other two is based of ARM architecture. The compiler will output a log where how much Flash resource is used when uploading the code. +The IDE's compiler output console log for another ARM-based Arduino®, the Portenta H7, is shown in the image below: -The purpose of these three images for different boards is to show that for each Arduino board family, the output log format is little different from one another; but it will show you the memory consumption information regarding the uploaded code. +![Flash memory memory measurement in an ARM-based Arduino® board](assets/arm_portentah7.png) -***If it is required to handle the Flash memory within high level code, please read more about in [this](https://docs.arduino.cc/tutorials/portenta-h7-lite/por-ard-flash) using Arduino Portenta H7*** +Notice that the compiler's output changes depending on if the board is AVR-based or ARM-based. ### SRAM Memory Measurement -The code may compile, upload and run. However, there may be situations in which the program will suffer from sudden operation halt. Thys type of issues are likely due to memory resource hogging or not enough memory to allocate. To solve this, it will require to understand in which sector of the code, the memory demand is going beyond the available resources. Following code fragment will help you measure the SRAM usage at a high level code. +Sometimes, there are situations where even when code is compiled and uploaded successfully by the IDE into a board, it suffers from sudden halts. These issues are likely due to memory resource-hogging or insufficient memory to allocate. To solve this, it is necessary to understand which code sector the memory demand is going beyond the available resources. The following example code can be used to **measure SRAM usage**: -```cpp -void display_freeram(){ - Serial.print(F("SRAM left")); +```arduino +void display_freeram() { + Serial.print(F("- SRAM left: ")); Serial.println(freeRam()); } @@ -215,115 +210,137 @@ int freeRam() { } ``` -In the code, `__heap_start` and `__brkval` are as following: -- **`__heap_start`**: Refers to beginning of the Heap. -- **`__brkval`**: Last memory address pointer used by Heap. It is pointing towards the Stack. +Remember that the `heap` section is where variables created during the run time are stored. In the code, `__heap_start` and `__brkval` are as following: -### EEPROM Memory Measurement +- **`__heap_start`**: the beginning of the `heap` section. +- **`__brkval`**: the last memory address pointer used by the `heap`. -EEPROM features are already included with the Arduino IDE platform so it does not require additional step to install any library to use its features. +**ADD REFERENCE HERE, DOES THIS WORKS FOR ARM ALSO?** -EEPROM memory measurement can be done through use of the following simple code fragment. The code is simplified to write a byte to know exactly which address it is reading from. It can be modified to read everything from every available possible address. +### EEPROM Memory Measurement -```cpp +EEPROM memory management can be done easily using native libraries already installed into the Arduino IDE. The `EEPROM` library can be used to read, write and erase the EEPROM memory. The following code shows how a byte of information can be stored in the EEPROM memory and then read using the `write` and `read` functions: + +```arduino #include -EEPROM.write(address, value); -EEPROM.read(address); +void setup() { +} + +void loop { + // Write data into an specific address of the EEPROM memory + EEPROM.write(address, value); + + // Read data of an specific address of the EEPROM memory + EEPROM.read(address); +} ``` -On the other hand, it is possible to clear the entire EEPROM memory to set it to 0. +Also, it is possible to clear the entire EEPROM memory by setting it to 0, as shown in the code below: -```cpp +```arduino #include -... +void setup() { +} -for (int i = 0 ; i < EEPROM.length() ; i++) { +void loop { + for (int i = 0 ; i < EEPROM.length() ; i++) { + // Clear EEPROM memory EEPROM.write(i, 0); -} -... +} ``` -The complete example codes can be found in our guide to EEPROM found below the following code. - -***For more information on how to manage the EEPROM memory, please read [here](https://docs.arduino.cc/learn/programming/eeprom-guide)*** +***Check [this](https://docs.arduino.cc/learn/programming/eeprom-guide) guide for more information on managing the EEPROM memory of Arduino boards.*** ## Optimizing Memory Usage in Arduino-based Systems -Knowing how the code utilizes the memory resources is one matter, but to optimize the memory is a whole different task. As the term development may infer, the requirements may change or be adjusted depending on external factors such as reduced device capacity due to inavailability of the components. Thus the code architecture may require optimization to be able to run on the reduced limited memory resources. -The optimization process also implies reduced computational complexities, trimming down extra time required to process the tasks while using less memory resource to do the same task. The memory optimization process may help the overall code optimization process, as it will handle how the memory is managed in a more suitable manner by requiring smart algorithm development. +Knowing how code uses memory resources of a system is just the first recommended task in the development process; a whole different task is **optimizing memory usage**. As the term development may infer, the requirements may change or be adjusted depending on external factors such as reduced device capacity due to the unavailability of the components. Thus the code architecture may require optimization to run on the reduced limited memory resources. + +The memory usage optimization process also implies reduced computational complexities, trimming down extra time required to process tasks while using fewer memory resources to do the same tasks. The memory usage optimization process may help the overall code optimization process, as it will handle how the memory is managed more suitably by requiring intelligent algorithms development. + +Let us talk about some memory usage optimization techniques. ### Flash Memory Optimization -Flash memory optimization is the most likely the straightforward optimization possible source to begin with. The Flash memory is where the capacity used by compiled code can be reduced greatly by considering some details. +Flash memory optimization is the most likely straightforward optimization possible source. Flash memory is where the capacity used by compiled code can be significantly reduced by considering some details. #### Detach Unused Sources -Detaching unused sources include unused libraries, and code residues. Code residues can be composed of functions that are no longer used and floating variables that takes up the unnecessary space in memory. This will vastly improve the compiled code size and make more clear compilation process. + +Detaching new sources includes **unused libraries** and **code residues**. Code residues can be composed of no-longer-used functions and floating variables that take up the unnecessary space in memory. This will vastly improve the compiled code size and make a more clear compilation process. + #### Modular Tasks -Modular tasks mean functions that wraps the code which will be used in a repetitive or continuous manner by receiving different parameters. It is a great way to maintain clean code structure and performance, while reducing the memory space required for additional tasks that might need to be implemented. -This leads to compact code structure, that is much easier to understand when debugging process is required, and demand developer to considerate compute complexity when designing the code structure or such specific algorithm. +**Modular tasks** mean **functions that wrap code that will be used repetitively or continuously** by receiving different parameters. It is a great way to maintain clean code structure and performance while reducing the memory space required for additional tasks that might need to be implemented. + +This leads to a compact code structure, which is much easier to understand when debugging is required and demands the developer consider computing complexity when designing the code structure or such a specific algorithm. ### SRAM Memory Optimization -#### String Wrapper - F() -It is convenient to use `Serial.println("Something");` to display the literals. This is used usually to understand where the code is going and to observe certain conditionals. However, doing this so will hog up the Static Random Access Memory (SRAM) space, which is something not desirable as the content is a simple literal string that is not used under the hood. +SRAM memory is probably the most important memory unit inside a microcontroller-based system; optimizing the SRAM usage is essential for designing reliable microcontroller-based systems. SRAM shortages are usually the most common memory problems found; SRAM optimization can help in reducing this type of issue. -The ideal way to use the Print Line command is to use the `F()` String Wrapper around the literals. This will lead us to following piece of code. +#### String Wrapper -```cpp +`Serial.print()` or `Serial.println()` instructions uses SRAM space, which can be convenient but not desirable. The ideal way to use a `Serial.print()` or `Serial.println()` instruction is with the use of the **`F()` String wrapper** around the literals. For example: + +```arduino Serial.println(F("Something")); ``` -By wrapping the String with `F()`, will move the Strings to Flash memory only rather than to use SRAM space also. It can be observed as offloading such data to Flash memory instead of SRAM. - -Flash memory is much more spacious than SRAM size, so it is better to use the Flash space than using SRAM which will use Heap. This does not mean the memory space will always be available, as Flash memory does have limited space too. It is not recommendable to cloag the code structure with Print Line, but to use them where they most matter for such applications with minimized implementation. +Wrapping the String `Something` with the `F()` wrapper will **move the Strings to Flash memory only rather than to use SRAM space** also. Using the `F()` wrapper can be observed as offloading such data to Flash memory instead of SRAM. Flash memory is much more spacious than SRAM, so it is better to use Flash memory space than SRAM, which will use `heap` section. This does not mean that memory space will always be available, as Flash memory does have limited space. It is not recommended to clog code with `Serial.print()` or `Serial.println()` instructions, but use them where they most matter inside the code. #### PROGMEM -It is not always with the literal String that occupies the SRAM space, but also using Global Variables which also takes up quite good amount of SRAM. As Global and Static variables are streamed to SRAM space, and pushes the Heap towards the Stack. The space occupied by this variables streamed to SRAM space will be saved at its location and will not be changing, meaning more of these variables are created, they will use more space and consequently, system failure due to low and poor memory management. -PROGMEM stands simply for **Program Memory**. We will use Program memory to store variable data offloading to Flash Memory space. As it goes same as to String Wrapper F(), PROGMEM uses Flash Memory space for its implementation. The only disadvantage presented using PROGMEM is the Read Speed. Using RAM will provide much faster Read Speed, but PROGMEM, as it uses Flash Memory, it will be slower than RAM, given the same data size. Thus, it is important to design the software knowing which variables are crucial and which has lower priority. It is one of the many factors that needs to be considered when developing the software, but this will lead to have nicely designed code architecture. +Not only Strings occupy SRAM space, but **global variables** also take up quite a good amount of SRAM space. As global and static variables are streamed into SRAM space and push the `heap` memory section towards the `stack`. The space occupied by these variables streamed into SRAM space will be saved at its location and will not be changing, meaning more of these variables are created, they will use more space, and consequently, the system presenting problems and issues due to poor memory management. -To use the PROGMEM, it can begin with following code fragment. +`PROGMEM`, which stands for **Program Memory**, can be used to store variable data into Flash memory space, just as the `F()` wrapper described before, but the use of `PROGMEM` presents one disadvantage: data read speed. Using RAM will provide a much faster data read speed, but `PROGMEM`, as it uses Flash memory, will be slower than RAM, given the same data size. Thus, it is essential to design code knowing which variables are crucial and which do not or have a lower priority. -```cpp +The use of `PROGMEM` in an AVR-based Arduino board is shown in the example code below: + +```arduino #include -// Basic PROGMEM Define Structure +// Basic PROGMEM structure const PROGMEM DataType Variable_Name[] = {var0, var1, var2 ...}; -// Unsigned 16 Bit int +// Storing an unsigned, 16-bit, integer const PROGMEM uint16_t NumSet[] = {0, 1, 1, 2, 3, 5, 8 ...}; -// Storing Char -const char greetMessage[] PROGMEM = {"Hello There"}; +// Storing a char in PROGMEM +const char greetMessage[] PROGMEM = {"Something"}; ``` -***For In-Depth detail about PROGMEM, please read [here](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/)*** +***For more information about PROGMEM, check [this](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/) article.*** -#### Non Dynamic Memory Allocation -Dynamic Memory Allocation usually is a good method if the given RAM size is big enough to get around with, from MegaBytes and so on. However, for embedded devices counting every Byte of the RAM, the process becomes hostile for RAM. +**ADD REFERENCE HERE, DOES THIS WORKS FOR ARM ALSO?** -Dynamic Memory Allocations cause **Heap fragmentation**. With heap fragmentation, many areas of the RAM affected by it cannot reused again, leaving dead Byte that can be taken as an advantage for other tasks. On top of it, when dynamic allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the Heap Size. So to avoid Heap or RAM fragmentation as much as possible, you can follow following rules to apply into code architecture design. +#### Non-Dynamic Memory Allocation -- Prioritize using **Stack** than **Heap** if possible to do so. - - Stack memory is fragmentation free and can be freed up completely when the function returns. Heap in contrast ma not free up the space even though it was instructed to do so. Using Local Variables will help to do this and try not to use dynamic memory allocation, composed of different calls: `malloc, calloc, realloc`. +Dynamic memory allocation is usually a suitable method if the RAM size of the system is big enough to get around with; however, for microcontroller-based systems, such as embedded systems, counting every Byte of RAM is not recommended. -- Reduced Global and Static Data if possible to do so. - - Meantime the code is running, memory area occupied by these data will not be freed up. Meaning the data won't be modified as it is constant data taking up the precious space. +Dynamic memory allocations cause **`heap` fragmentation**. With `heap` fragmentation, many areas of RAM affected by it cannot be reused again, leaving dead Bytes that can be taken as an advantage for other tasks. On top of it, when dynamic memory allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the `heap` size. So to avoid `heap` or RAM fragmentation as much as possible, the following rules can be followed: -- Short Strings / Literals - - It is good practice to keep the literal Strings as short as possible. Single char takes **One** Byte of RAM, so shorter the better memory space usage. This does not mean, keeping it short and using it in several different areas of the code is possible. Use it when it is absolutely required and keep as short as possible to spare RAM space for other task functions. +- Prioritize using the **`stack`** rather than the **`heap`**: + + - `Stack` memory is fragmentation-free and can be freed up thoroughly when the function returns. `Heap`, in contrast, may not free up the space even though it was instructed to do so. Using local variables will help to do this and try not to use dynamic memory allocation, composed of different calls: `malloc, calloc, realloc`. - - Arrays are also recommended to be at a minimum size. If it requires to resize the array, you can always re-set the array size in the code. It may be a tedious, also non-efficient method to hard-code the array sizes. But if the code utilizes small array sizes and less than 3 arrays, it may be suffice via manual resizing, knowing the requirements. A smart way to do this is resizeable array with limited size. In which the tasks will use the array without going over the size boundary, thus it is suitable for extensive code size. Although, the limit of the array size must be analyzed and kept as small as possible. +- Reduced global and static data (if possible): + + - Meantime the code is running, memory area occupied by these data will not be freed up. The data will not be modified as constant data takes up precious space. + +- Short Strings/Literals: + + - It is good to keep Strings/literals as short as possible. A single char takes **one** Byte of RAM, so the shorter, the better memory space usage. This does not mean keeping it short and using it in several different code areas is possible. Use it when required and keep it as short as possible to spare RAM space for other tasks. + + - Arrays are also recommended to be at a minimum size. If it requires resizing the array, you can always re-set the array size in code. It may be a tedious, also non-efficient method to hard-code the array sizes. However, if the code utilizes small array sizes and less than three arrays, it may suffice via manual resizing, knowing the requirements. An intelligent way to do this is a resizeable array with limited size. The tasks will use the array without going over the size boundary. Thus it is suitable for extensive code. Although, the limit of the array size must be analyzed and kept as small as possible. #### RESERVE() -If the tasks work with the Strings, that changes in its size depending on the operation outcome, `RESERVE()` is way to go. This function will help to reserve buffer space and pre-allocate for String variable, which changes in its size, and avoid fragmentation. String variable that changes in its size could be a result of `int` type variable wrapped to be used as a `String` for example. -To use the `RESERVE()` function, it is possible to begin usage with following code piece. +If tasks in code work with Strings, that changes in its size depending on the operation outcome, `RESERVE()` is way to go. This function will help to reserve buffer space and pre-allocate for a String variable, which changes in its size, and avoid memory fragmentation. String variable that changes in its size could be a result of an `int` type variable wrapped to be used as a `String`, for example. + +To use the `RESERVE()` instruction, it is possible to begin usage with following code piece. ```cpp // String_Variable is variable of String type @@ -334,6 +351,7 @@ String_Variable.reserve(Alloc_Size); ***For more information about the `RESERVE()` function, please check out [here](https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/reserve/)*** #### Buffer Size Control + Backend processes also requires memory pool for its processing purpose. It is something in which the machine will work on according to the size of the memory pool defined. This Buffer size can be user defined, meaning it can be can reduced to allocate lower memory size. It is similar to defining Array size, in which it is important not to allocate excessive size when it will use only third portion of the defined size. In between backend services, Serial communication defines the needed memory pool as Serial Buffer Size. Bigger serial buffer assists in establishing high speed communication, relative to the device that is interchanging data stream. If high speed communication is not part of the requiremente, the buffer size can be redefined to save some memory consumption. This is possible to do so by modifying the `HardwareSerial.h` that comes with Arduino IDE compiler, searching the following line. @@ -347,6 +365,7 @@ In between backend services, Serial communication defines the needed memory pool Libraries, or external modules that involve in code architecture development, also uses Buffer pool for better computing performance. Although, depending on the requirement, smooth performance might be cherry on top for the code architecture that is being developed. It is feasible to modify the buffer size that is designated in the library code. #### Corrective Data Type Usage + Implementation of adequate data type leads to a good overall code architecture. It may be desirable for the developer to use easiest or the most accessible data type to handle the data stream. However, it is important to consider the amount of memory space that it takes up when using certain data types. The Data Types exist to ease data stream format and to be handled without making illegal access. The illegal access in terms of data types are meant when the data is handled in the code with incompatible format. So it is a good practice to not to abuse the the data type and use only convenient types for every data bits. Rather, design and allocate memory carefully according to the requirements, which will help to reserve some memory space if further designed tasks needs extra space. From 29ce6a62080f9bf8a4570cd289fe009ed5b8cc62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Tue, 5 Apr 2022 15:19:18 -0600 Subject: [PATCH 26/36] Update tutorial content --- .../06.memory-guide/memory-guide.md | 57 +++++++------------ 1 file changed, 20 insertions(+), 37 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 24b913be3e..22f7dd225b 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -194,7 +194,7 @@ Notice that the compiler's output changes depending on if the board is AVR-based ### SRAM Memory Measurement -Sometimes, there are situations where even when code is compiled and uploaded successfully by the IDE into a board, it suffers from sudden halts. These issues are likely due to memory resource-hogging or insufficient memory to allocate. To solve this, it is necessary to understand which code sector the memory demand is going beyond the available resources. The following example code can be used to **measure SRAM usage**: +Sometimes, there are situations where even when code is compiled and uploaded successfully by the IDE into a board, it suffers from sudden halts. These issues are likely due to memory resource-hogging or insufficient memory to allocate. It is necessary to understand which code sector the memory demand is going beyond the available resources to solve this. The following example code can be used to **measure SRAM usage**: ```arduino void display_freeram() { @@ -322,55 +322,55 @@ Dynamic memory allocation is usually a suitable method if the RAM size of the sy Dynamic memory allocations cause **`heap` fragmentation**. With `heap` fragmentation, many areas of RAM affected by it cannot be reused again, leaving dead Bytes that can be taken as an advantage for other tasks. On top of it, when dynamic memory allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the `heap` size. So to avoid `heap` or RAM fragmentation as much as possible, the following rules can be followed: -- Prioritize using the **`stack`** rather than the **`heap`**: +- **Prioritize using the `stack` rather than the `heap`**: - `Stack` memory is fragmentation-free and can be freed up thoroughly when the function returns. `Heap`, in contrast, may not free up the space even though it was instructed to do so. Using local variables will help to do this and try not to use dynamic memory allocation, composed of different calls: `malloc, calloc, realloc`. -- Reduced global and static data (if possible): +- **Reduced global and static data (if possible)**: - Meantime the code is running, memory area occupied by these data will not be freed up. The data will not be modified as constant data takes up precious space. -- Short Strings/Literals: +- **Use short Strings/literals**: - It is good to keep Strings/literals as short as possible. A single char takes **one** Byte of RAM, so the shorter, the better memory space usage. This does not mean keeping it short and using it in several different code areas is possible. Use it when required and keep it as short as possible to spare RAM space for other tasks. - - Arrays are also recommended to be at a minimum size. If it requires resizing the array, you can always re-set the array size in code. It may be a tedious, also non-efficient method to hard-code the array sizes. However, if the code utilizes small array sizes and less than three arrays, it may suffice via manual resizing, knowing the requirements. An intelligent way to do this is a resizeable array with limited size. The tasks will use the array without going over the size boundary. Thus it is suitable for extensive code. Although, the limit of the array size must be analyzed and kept as small as possible. + - **Arrays** are also recommended to be at a minimum size. If it requires resizing the array, you can always re-set the array size in code. It may be a tedious, also non-efficient method to hard-code the array sizes. However, if the code utilizes small array sizes and less than three arrays, it may suffice via manual resizing, knowing the requirements. An intelligent way to do this is a resizeable array with limited size. The tasks will use the array without going over the size boundary. Thus it is suitable for extensive code. Although, the limit of the array size must be analyzed and kept as small as possible. -#### RESERVE() +#### Reserve Function -If tasks in code work with Strings, that changes in its size depending on the operation outcome, `RESERVE()` is way to go. This function will help to reserve buffer space and pre-allocate for a String variable, which changes in its size, and avoid memory fragmentation. String variable that changes in its size could be a result of an `int` type variable wrapped to be used as a `String`, for example. +In tasks in code work with Strings that change in size depending on the operation outcome, `reserve()` is the way to go. This function will help **reserve buffer space and pre-allocate for a String variable**, changing its size and avoiding memory fragmentation. A String variable that changes in its size could result from an int type variable wrapped to be used as a String, for example. -To use the `RESERVE()` instruction, it is possible to begin usage with following code piece. +The following code shows how to use the `reserve()` instruction: -```cpp -// String_Variable is variable of String type -// Alloc_Size is memory to be pre-allocated in number of Bytes with unsigned int type +```arduino +// String_Variable is an String type variable +// Alloc_Size is the memory to be pre-allocated in number of Bytes with unsigned int type String_Variable.reserve(Alloc_Size); ``` -***For more information about the `RESERVE()` function, please check out [here](https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/reserve/)*** +***Please check out [here](https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/reserve/) for more information about the `reserve()` function.*** #### Buffer Size Control -Backend processes also requires memory pool for its processing purpose. It is something in which the machine will work on according to the size of the memory pool defined. This Buffer size can be user defined, meaning it can be can reduced to allocate lower memory size. It is similar to defining Array size, in which it is important not to allocate excessive size when it will use only third portion of the defined size. +Backend processes also require a memory pool for their processing purpose. It is something on which the system will work according to the size of the memory pool defined. This **buffer size can be user-defined**, which can be reduced to allocate a lower memory size. Think about defining an array variable size, in which it is important not to allocate excessive size when it uses only a third portion of the defined size. -In between backend services, Serial communication defines the needed memory pool as Serial Buffer Size. Bigger serial buffer assists in establishing high speed communication, relative to the device that is interchanging data stream. If high speed communication is not part of the requiremente, the buffer size can be redefined to save some memory consumption. This is possible to do so by modifying the `HardwareSerial.h` that comes with Arduino IDE compiler, searching the following line. +Let us discuss an example: serial communications in Arduino. Serial communications is a regularly used service in Arduino-based systems; Serial communications in Arduino work using the preinstalled Serial library (external libraries can also emulate serial communications using software). In between backend services, serial communications define the needed memory pool as a buffer with a defined size. If high-speed serial communication is not part of the requirements, the serial buffer size can be redefined to save some memory consumption. This can be made easily by modifying the following code line in the `HardwareSerial.h` file that can be found in the installation folder of the Arduino IDE: -```cpp +```arduino #define SERIAL_TX_BUFFER_SIZE 64 #define SERIAL_RX_BUFFER_SIZE 64 ``` -Libraries, or external modules that involve in code architecture development, also uses Buffer pool for better computing performance. Although, depending on the requirement, smooth performance might be cherry on top for the code architecture that is being developed. It is feasible to modify the buffer size that is designated in the library code. +External libraries can usually be modified to optimize buffer sizes used for performing specific tasks of the libraries. #### Corrective Data Type Usage -Implementation of adequate data type leads to a good overall code architecture. It may be desirable for the developer to use easiest or the most accessible data type to handle the data stream. However, it is important to consider the amount of memory space that it takes up when using certain data types. +Implementation of adequate **data type** leads to a good overall code architecture. It may be desirable for developers to use easiest or the most accessible data type to handle the data in code. However, it is important to consider the amount of memory space that it takes up when using certain data types. -The Data Types exist to ease data stream format and to be handled without making illegal access. The illegal access in terms of data types are meant when the data is handled in the code with incompatible format. So it is a good practice to not to abuse the the data type and use only convenient types for every data bits. Rather, design and allocate memory carefully according to the requirements, which will help to reserve some memory space if further designed tasks needs extra space. +Data types exist to ease data stream format and to be handled without making illegal access. The illegal access in terms of data types are meant when the data is handled in the code with incompatible format. So it is a good practice to not to abuse the the data type and use only convenient types for every data bits. Rather, design and allocate memory carefully according to the requirements, which will help to reserve some memory space if further designed tasks needs extra space. -Following table shows some of the existing data types to opt out for more options. +The following table shows basic value data types in Arduino: | Data Type | Byte Size | Range | Format Specifier | | :--------------------: | :---------: | :-----------------------------------: | :-----------------: | @@ -402,21 +402,4 @@ Sometimes the developer would have to use the EEPROM as an alternative storage f ***`FlashStorage` library by Christian Maglie can be accessed by [here](https://github.com/cmaglie/FlashStorage)*** -Above library will help you to use the Flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As it is for EEPROM, the Flash memory is also limited in write operation cycle. With two new additional functions stated in the library, one of them being `EEPROM.commit()` should not be called inside a loop function. Otherwise, it will wipe out the Flash memory's write operation cycles, thus loss of data retention ability. - -## Tips & Troubleshooting - -Notice that with boards that do not have a lot of SRAM available, like the UNO. It's easy to use it all up by having lots of strings in your program. For example, a declaration like: -```arduino -char message[] = "I support the Cape Wind project."; -``` - -puts 33 bytes into SRAM (each character ta|kes a byte, plus the '\0' terminator). This might not seem like a lot, but it doesn't take long to get to 2048, especially if you have a large amount of text to send to a display, or a large lookup table, for example. - -If you run out of SRAM, your program may fail in unexpected ways; it will appear to upload successfully, but not run, or run strangely. To check if this is happening, you can try commenting out or shortening the strings or other data structures in your sketch (without changing the code). If it then runs successfully, you're probably running out of SRAM. There are a few things you can do to address this problem: - -- If your sketch talks to a program running on a (desktop/laptop) computer, you can try shifting data or calculations to the computer, reducing the load on the Arduino. - -- If you have lookup tables or other large arrays, use the smallest data type necessary to store the values you need; for example, an [int](/en/Reference/Int) takes up two bytes, while a [byte](arduino.cc/en/Reference/Byte) uses only one (but can store a smaller range of values). - -- If you don't need to modify the strings or data while your sketch is running, you can store them in flash (program) memory instead of SRAM; to do this, use the [PROGMEM](arduino.cc/en/Reference/PROGMEM) keyword. \ No newline at end of file +Above library will help you to use the Flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As it is for EEPROM, the Flash memory is also limited in write operation cycle. With two new additional functions stated in the library, one of them being `EEPROM.commit()` should not be called inside a loop function. Otherwise, it will wipe out the Flash memory's write operation cycles, thus loss of data retention ability. \ No newline at end of file From 3d4596b8e6df50e00293bf743732d7d10134e635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20S=C3=B6derby?= <35461661+karlsoderby@users.noreply.github.com> Date: Wed, 6 Apr 2022 14:26:25 +0200 Subject: [PATCH 27/36] Update memory-guide.md --- .../06.memory-guide/memory-guide.md | 108 ++++++++++-------- 1 file changed, 59 insertions(+), 49 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index a7d0362ca9..0e2cb2d2e1 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -77,7 +77,7 @@ Arduino® boards are mainly based on two families of microcontrollers: **AVR®** ## Memory Types -Now, let us talk about the different memory units present on microcontrollers. All the different memory units inside a microcontroller can be divided into two main types: **RAM** and **ROM**. RAM (from Random-Access Memory) in microcontroller-based systems is a volatile memory used to store temporary data such as the system's firmware variables. ROM (from Read-Only Memory) in microcontroller-based systems is non-volatile memory used to store permanent data such as the system's firmware. +All the different memory units inside a microcontroller can be divided into two main types: **RAM** and **ROM**. RAM (from Random-Access Memory) in microcontroller-based systems is a volatile memory used to store temporary data such as the system's firmware variables. ROM (from Read-Only Memory) in microcontroller-based systems is non-volatile memory used to store permanent data such as the system's firmware. RAM and ROM in microcontroller-based systems are organized into three main categories: @@ -85,25 +85,23 @@ RAM and ROM in microcontroller-based systems are organized into three main categ - RAM - EEPROM -Let us talk more about these types of memories. - ### Flash -Flash memory in microcontroller-based systems is part of its ROM. The **Flash memory is where the system's firmware is stored to be executed**. For example, think of the famous `Blink.ino` example sketch, when we compile this sketch, we create a binary file that is later stored into the Flash memory of an Arduino board and executed when power on. +**Flash** memory in microcontroller-based systems is part of its ROM. The flash memory is where the system's firmware is stored to be executed. For example, think of the famous `Blink.ino` sketch, when we compile this sketch, we create a binary file that is later stored in the flash memory of an Arduino board. The sketch is then executed when the board is powered on. ### RAM -**RAM** in microcontroller-based systems **is where the system's temporary data or run-time data is stored**. A microcontroller's RAM usually is SRAM; this is a type of RAM that uses a flip-flop to store one bit of data. For example, the variables created by functions. +**RAM** in microcontroller-based systems is where the system's temporary data or run-time data is stored. A microcontroller's RAM usually is SRAM; this is a type of RAM that uses a flip-flop to store one bit of data. For example, the variables created by functions. ### EEPROM -In microcontroller-based systems, Erasable Programmable Read-Only Memory, or EEPROM, is also part of its ROM; actually, Flash memory is a type of EEPROM. **The main difference between Flash memory and EEPROM is how they are managed**; EEPROM can be managed at the byte level (write or erased) while Flash can be managed at the block level. +In microcontroller-based systems, Erasable Programmable Read-Only Memory, or EEPROM, is also part of its ROM; actually, Flash memory is a type of EEPROM. The main difference between Flash memory and EEPROM is how they are managed; EEPROM can be managed at the byte level (write or erased) while Flash can be managed at the block level. ## Arduino® Boards Memory Allocation As stated before, Arduino® boards are mainly based on two families of microcontrollers, AVR® and ARM®; it is important to know that **memory allocation differs in both architectures**. In Harvard-based AVR architecture, memory is organized as shown in the image below: -Something important to mention about AVR-based Arduino boards is how their SRAM is organized into different sections: +Important to mention about AVR-based Arduino boards is how their SRAM is organized into different sections: - `Text` - `Data` @@ -113,24 +111,27 @@ Something important to mention about AVR-based Arduino boards is how their SRAM The `text` section contains instructions loaded into the flash memory; `data` section contains variables initialized in the sketch, `BSS` section contains uninitialized data, `stack` section stores data of functions and interrupts, and `heap` section stores variables created during run time. -In hybrid ARM architectures, so called **Memory map** is implemented, with different address map configuration of 32-bit, 36-bit, and 40-bit that depends on the requirement of System On a Chip (SoC) address space with extra DRAM. The Memory Map grants interface with SoC design, while having most system control on a high level coding. Memory access instructions can be used on high level code to manage interrupt modules and built-in peripherals. All of this controlled by Memory Management Unit (MMU). +In hybrid ARM architectures, a so called **memory map** is implemented, with a different address map configuration of 32-bit, 36-bit, and 40-bit that depends on the requirement of System On a Chip (SoC) address space with extra DRAM. The Memory Map grants interface with SoC design, while having most system control on a high level coding. Memory access instructions can be used on high level code to manage interrupt modules and built-in peripherals. All of this controlled by **Memory Management Unit (MMU)**. + +The memory resource is handled by the MMU. The main role of the MMU is to enable the processor to run multiple tasks independently in its own virtual memory space; the MMU then uses translation tables to establish a bridge between the virtual and the physical memory addresses. Virtual Address is managed via software with memory instructions, and Physical address is the memory system that is controlled depending on the Translation Table input given by the Virtual Address. -The memory resource is handled by the **Memory Management Unit** (MMU). The main role of the MMU is to enable the processor to run multiple tasks independently in its own virtual memory space; the MMU then uses translation tables to establish a bridge between the virtual and the physical memory addresses. Virtual Address is managed via software with memory instructions, and Physical address is the memory system that is controlled depending on the Translation Table input given by the Virtual Address. An example of how memory is organized in ARM-based microcontrollers, virtually and physically, is shown in the image below: The ARM-based microcontroller's memory department is organized into the following sections respectively within the address type mentioned previously: -- **Virtual Address** +**Virtual Address** + - `Kernel Code & Data` - `Application Code & Data` -- **Physical Address** +**Physical Address** + - `ROM` - `RAM` - `Flash` - `Peripherals` -The following table summarizes the Arduino® board's memory allocation: +The following table summarizes a specific Arduino® board's memory allocation: | **Board** | **Microcontroller** | **Family** | **Architecture** | **Flash** | **SRAM** | **EEPROM** | |:-------------------:|:-------------------:|:----------------:|:----------------:|:---------:|:--------:|:----------:| @@ -142,7 +143,7 @@ The following table summarizes the Arduino® board's memory allocation: | Mega 2560 Rev3 | ATmega2560 | AVR | Harvard | 256kB | 8kB | 4kB | | Micro | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | | Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| Porten ta H7* | STM32H747 | ARM Cortex M4/M7 | Harvard | 16MB | 8MB | - | +| Portenta H7* | STM32H747 | ARM Cortex M4/M7 | Harvard | 16MB | 8MB | - | | Nicla Sense ME | nRF52832 | ARM Cortex M4 | Harvard | 512kB | 64kB | - | | Nano RP2040 Connect | RP2040 | ARM Cortex M0+ | Von Neumann | - | 264kB | - | | MKR FOX 1200 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | @@ -161,7 +162,7 @@ The following table summarizes the Arduino® board's memory allocation: ## Measuring Memory Usage in Arduino Boards -Memory usage statistics help comprehend the insight of resource management affected by the designed code structure. Memory load demand is one statistic that will give you an insight into how efficient the code is design|ed. It is a crucial development consideration element because the resources are finite inside a microcontroller-based system; **software should always perform without reaching maximum load capacity to avoid problems or issues**. Memory load could be observed either as **available RAM** at disposal for specific tasks or **Flash storage remaining capacity** for required headroom. +Memory usage statistics help comprehend the insight of resource management affected by the designed code structure. Memory load demand is one statistic that will give you an insight into how efficient the code is design|ed. It is a crucial development consideration element because the resources are finite inside a microcontroller-based system; **software should always perform without reaching maximum load capacity to avoid problems or issues**. Memory load could be observed either as **available RAM** at disposal for specific tasks or **flash storage remaining capacity** for required headroom. Let us talk more about memory usage measurement in Arduino boards. ​ @@ -203,7 +204,7 @@ The purpose of these three images for different boards is to show that for each The code may compile, upload and run. However, there may be situations in which the program will suffer from sudden operation halt. Thys type of issues are likely due to memory resource hogging or not enough memory to allocate. To solve this, it will require to understand in which sector of the code, the memory demand is going beyond the available resources. Following code fragment will help you measure the SRAM usage at a high level code. -```cpp +```arduino void display_freeram(){ Serial.print(F("SRAM left")); Serial.println(freeRam()); @@ -227,7 +228,7 @@ EEPROM features are already included with the Arduino IDE platform so it does no EEPROM memory measurement can be done through use of the following simple code fragment. The code is simplified to write a byte to know exactly which address it is reading from. It can be modified to read everything from every available possible address. -```cpp +```arduino #include EEPROM.write(address, value); @@ -236,7 +237,7 @@ EEPROM.read(address); On the other hand, it is possible to clear the entire EEPROM memory to set it to 0. -```cpp +```arduino #include ... @@ -250,10 +251,11 @@ for (int i = 0 ; i < EEPROM.length() ; i++) { The complete example codes can be found in our guide to EEPROM found below the following code. -***For more information on how to manage the EEPROM memory, please read [here](https://docs.arduino.cc/learn/programming/eeprom-guide)*** +***For more information on how to manage the EEPROM memory, you can refer to [this guide](https://docs.arduino.cc/learn/programming/eeprom-guide).*** ## Optimizing Memory Usage in Arduino-based Systems -Knowing how the code utilizes the memory resources is one matter, but to optimize the memory is a whole different task. As the term development may infer, the requirements may change or be adjusted depending on external factors such as reduced device capacity due to inavailability of the components. Thus the code architecture may require optimization to be able to run on the reduced limited memory resources. + +Knowing how the code utilizes the memory resources is one matter, but to optimize the memory is a different task. As the term development may infer, the requirements may change or be adjusted depending on external factors such as reduced device capacity due to inavailability of the components. Thus the code architecture may require optimization to be able to run on the reduced limited memory resources. The optimization process also implies reduced computational complexities, trimming down extra time required to process the tasks while using less memory resource to do the same task. The memory optimization process may help the overall code optimization process, as it will handle how the memory is managed in a more suitable manner by requiring smart algorithm development. @@ -262,9 +264,11 @@ The optimization process also implies reduced computational complexities, trimmi Flash memory optimization is the most likely the straightforward optimization possible source to begin with. The Flash memory is where the capacity used by compiled code can be reduced greatly by considering some details. #### Detach Unused Sources + Detaching unused sources include unused libraries, and code residues. Code residues can be composed of functions that are no longer used and floating variables that takes up the unnecessary space in memory. This will vastly improve the compiled code size and make more clear compilation process. #### Modular Tasks + Modular tasks mean functions that wraps the code which will be used in a repetitive or continuous manner by receiving different parameters. It is a great way to maintain clean code structure and performance, while reducing the memory space required for additional tasks that might need to be implemented. This leads to compact code structure, that is much easier to understand when debugging process is required, and demand developer to considerate compute complexity when designing the code structure or such specific algorithm. @@ -274,20 +278,21 @@ This leads to compact code structure, that is much easier to understand when deb #### String Wrapper - F() It is convenient to use `Serial.println("Something");` to display the literals. This is used usually to understand where the code is going and to observe certain conditionals. However, doing this so will hog up the Static Random Access Memory (SRAM) space, which is something not desirable as the content is a simple literal string that is not used under the hood. -The ideal way to use the Print Line command is to use the `F()` String Wrapper around the literals. This will lead us to following piece of code. +The ideal way to use the Print Line command is to use the `F()` String Wrapper around the literals. See the example below: -```cpp +```arduino Serial.println(F("Something")); ``` -By wrapping the String with `F()`, will move the Strings to Flash memory only rather than to use SRAM space also. It can be observed as offloading such data to Flash memory instead of SRAM. +By wrapping the String with `F()`, it will move the Strings to the flash memory only, rather than to use SRAM space. It can be observed as offloading such data to flash memory instead of SRAM. -Flash memory is much more spacious than SRAM size, so it is better to use the Flash space than using SRAM which will use Heap. This does not mean the memory space will always be available, as Flash memory does have limited space too. It is not recommendable to cloag the code structure with Print Line, but to use them where they most matter for such applications with minimized implementation. +Flash memory is much more spacious than SRAM size, so it is better to use the flash space than using SRAM which will use Heap. This does not mean the memory space will always be available, as Flash memory does have limited space too. It is not recommendable to clog the code structure with "Print Line", but to use them where they most matter for such applications with minimized implementation. #### PROGMEM -It is not always with the literal String that occupies the SRAM space, but also using Global Variables which also takes up quite good amount of SRAM. As Global and Static variables are streamed to SRAM space, and pushes the Heap towards the Stack. The space occupied by this variables streamed to SRAM space will be saved at its location and will not be changing, meaning more of these variables are created, they will use more space and consequently, system failure due to low and poor memory management. -PROGMEM stands simply for **Program Memory**. We will use Program memory to store variable data offloading to Flash Memory space. As it goes same as to String Wrapper F(), PROGMEM uses Flash Memory space for its implementation. The only disadvantage presented using PROGMEM is the Read Speed. Using RAM will provide much faster Read Speed, but PROGMEM, as it uses Flash Memory, it will be slower than RAM, given the same data size. Thus, it is important to design the software knowing which variables are crucial and which has lower priority. It is one of the many factors that needs to be considered when developing the software, but this will lead to have nicely designed code architecture. +It is not always the literal String that occupies the SRAM space, but using **global variables** also takes up quite good amount of SRAM. As **global** and **static** variables are streamed to SRAM space, and pushes the **heap** towards the **stack**. The space occupied by this variables streamed to SRAM space will be saved at its location and will not be changing, meaning more of these variables are created, they will use more space and consequently, system failure due to low and poor memory management. + +**PROGMEM** stands simply for **program memory**. We will use program memory to store variable data offloading to flash memory space. Same as the String wrapper `F()`, PROGMEM uses flash memory space for its implementation. The only disadvantage presented using PROGMEM is the **read speed**. Using RAM will provide much faster read speed, but PROGMEM, as it uses flash memory, it will be slower than RAM, given the same data size. Thus, it is important to design the software knowing which variables are crucial and which has lower priority. It is one of the many factors that needs to be considered when developing the software, but this will lead to have nicely designed code architecture. To use the PROGMEM, it can begin with following code fragment. @@ -304,28 +309,30 @@ const PROGMEM uint16_t NumSet[] = {0, 1, 1, 2, 3, 5, 8 ...}; const char greetMessage[] PROGMEM = {"Hello There"}; ``` -***For In-Depth detail about PROGMEM, please read [here](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/)*** +***You can read more about PROGMEM in the [language reference](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/).*** -#### Non Dynamic Memory Allocation -Dynamic Memory Allocation usually is a good method if the given RAM size is big enough to get around with, from MegaBytes and so on. However, for embedded devices counting every Byte of the RAM, the process becomes hostile for RAM. +#### Non Dynamic Memory Allocation -Dynamic Memory Allocations cause **Heap fragmentation**. With heap fragmentation, many areas of the RAM affected by it cannot reused again, leaving dead Byte that can be taken as an advantage for other tasks. On top of it, when dynamic allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the Heap Size. So to avoid Heap or RAM fragmentation as much as possible, you can follow following rules to apply into code architecture design. +Dynamic memory allocation is a good method if the given RAM size is big enough to get around with, from MegaBytes and so on. However, for embedded devices counting every Byte of the RAM, the process becomes hostile for RAM. -- Prioritize using **Stack** than **Heap** if possible to do so. - - Stack memory is fragmentation free and can be freed up completely when the function returns. Heap in contrast ma not free up the space even though it was instructed to do so. Using Local Variables will help to do this and try not to use dynamic memory allocation, composed of different calls: `malloc, calloc, realloc`. +Dynamic Memory Allocations cause **heap fragmentation**. With heap fragmentation, many areas of the RAM affected by it cannot reused again, leaving dead Byte that can be taken as an advantage for other tasks. On top of it, when dynamic allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the Heap Size. So to avoid heap or RAM fragmentation as much as possible, you can follow following rules to apply into code architecture design. -- Reduced Global and Static Data if possible to do so. +- Prioritize using **stack** than **heap** if possible to do so. + - Stack memory is fragmentation free and can be freed up completely when the function returns. Heap in contrast ma not free up the space even though it was instructed to do so. Using local variables will help to do this and try not to use dynamic memory allocation, composed of different calls: `malloc, calloc, realloc`. + +- Reduced global and static data if possible to do so. - Meantime the code is running, memory area occupied by these data will not be freed up. Meaning the data won't be modified as it is constant data taking up the precious space. -- Short Strings / Literals - - It is good practice to keep the literal Strings as short as possible. Single char takes **One** Byte of RAM, so shorter the better memory space usage. This does not mean, keeping it short and using it in several different areas of the code is possible. Use it when it is absolutely required and keep as short as possible to spare RAM space for other task functions. +- Short strings / literals + - It is good practice to keep the literal Strings as short as possible. Single char takes **one** byte of RAM, so shorter the better memory space usage. This does not mean, keeping it short and using it in several different areas of the code is possible. Use it when it is absolutely required and keep as short as possible to spare RAM space for other task functions. - Arrays are also recommended to be at a minimum size. If it requires to resize the array, you can always re-set the array size in the code. It may be a tedious, also non-efficient method to hard-code the array sizes. But if the code utilizes small array sizes and less than 3 arrays, it may be suffice via manual resizing, knowing the requirements. A smart way to do this is resizeable array with limited size. In which the tasks will use the array without going over the size boundary, thus it is suitable for extensive code size. Although, the limit of the array size must be analyzed and kept as small as possible. -#### RESERVE() -If the tasks work with the Strings, that changes in its size depending on the operation outcome, `RESERVE()` is way to go. This function will help to reserve buffer space and pre-allocate for String variable, which changes in its size, and avoid fragmentation. String variable that changes in its size could be a result of `int` type variable wrapped to be used as a `String` for example. +#### Reserve Function + +If the tasks work with the Strings, that changes in its size depending on the operation outcome, `reserve()` is way to go. This function will help to reserve buffer space and pre-allocate for String variable, which changes in its size, and avoid fragmentation. String variable that changes in its size could be a result of `int` type variable wrapped to be used as a `String` for example. -To use the `RESERVE()` function, it is possible to begin usage with following code piece. +To use the `reserve()` function, it is possible to begin usage with following code piece. ```cpp // String_Variable is variable of String type @@ -333,12 +340,13 @@ To use the `RESERVE()` function, it is possible to begin usage with following co String_Variable.reserve(Alloc_Size); ``` -***For more information about the `RESERVE()` function, please check out [here](https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/reserve/)*** +***For more information about the `reserve()` function, visit [this article](https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/reserve/).*** #### Buffer Size Control -Backend processes also requires memory pool for its processing purpose. It is something in which the machine will work on according to the size of the memory pool defined. This Buffer size can be user defined, meaning it can be can reduced to allocate lower memory size. It is similar to defining Array size, in which it is important not to allocate excessive size when it will use only third portion of the defined size. -In between backend services, Serial communication defines the needed memory pool as Serial Buffer Size. Bigger serial buffer assists in establishing high speed communication, relative to the device that is interchanging data stream. If high speed communication is not part of the requiremente, the buffer size can be redefined to save some memory consumption. This is possible to do so by modifying the `HardwareSerial.h` that comes with Arduino IDE compiler, searching the following line. +Backend processes also requires memory pool for its processing purpose. It is something in which the machine will work on according to the size of the memory pool defined. This buffer size can be user defined, meaning it can be can reduced to allocate lower memory size. It is similar to defining Array size, in which it is important not to allocate excessive size when it will use only third portion of the defined size. + +In between backend services, serial communication defines the needed memory pool as **serial buffer size**. Bigger serial buffer assists in establishing high speed communication, relative to the device that is interchanging data stream. If high speed communication is not part of the requiremente, the buffer size can be redefined to save some memory consumption. This is possible to do so by modifying the `HardwareSerial.h` that comes with Arduino IDE compiler, searching the following line. ```cpp #define SERIAL_TX_BUFFER_SIZE 64 @@ -346,12 +354,13 @@ In between backend services, Serial communication defines the needed memory pool #define SERIAL_RX_BUFFER_SIZE 64 ``` -Libraries, or external modules that involve in code architecture development, also uses Buffer pool for better computing performance. Although, depending on the requirement, smooth performance might be cherry on top for the code architecture that is being developed. It is feasible to modify the buffer size that is designated in the library code. +Libraries, or external modules that involve in code architecture development, also uses buffer pool for better computing performance. Although, depending on the requirement, smooth performance might be cherry on top for the code architecture that is being developed. It is feasible to modify the buffer size that is designated in the library code. #### Corrective Data Type Usage + Implementation of adequate data type leads to a good overall code architecture. It may be desirable for the developer to use easiest or the most accessible data type to handle the data stream. However, it is important to consider the amount of memory space that it takes up when using certain data types. -The Data Types exist to ease data stream format and to be handled without making illegal access. The illegal access in terms of data types are meant when the data is handled in the code with incompatible format. So it is a good practice to not to abuse the the data type and use only convenient types for every data bits. Rather, design and allocate memory carefully according to the requirements, which will help to reserve some memory space if further designed tasks needs extra space. +The data types exist to ease data stream format and to be handled without making illegal access. The illegal access in terms of data types is when the data is handled in the code with incompatible format. So it is a good practice to not to abuse the the data type and use only convenient types for every data bits. Rather, design and allocate memory carefully according to the requirements, which will help to reserve some memory space if further designed tasks needs extra space. Following table shows some of the existing data types to opt out for more options. @@ -373,33 +382,34 @@ Following table shows some of the existing data types to opt out for more option ​ ### EEPROM Memory Optimization -EEPROM memory optimization usually is not required, as it will be used mainly to store external module tuning constant. The data which are to be used by EEPROM space are the ones does not really need Flash memory as storage source. On top of it, it is not a good practice to offload SRAM data on EEPROM space. SRAM data are placed within volatility in mind, so offloading to EERPOM space, which is non-volatile memory, will mean the offloaded data will be engraved into EEPROM space. As result, the it is impractical use of storage and the variable will change in its value, making the old data unusable. +EEPROM memory optimization usually is not required, as it will be used mainly to store external module tuning constant. The data which are to be used by EEPROM space are the ones does not really need flash memory as storage source. On top of it, it is not a good practice to offload SRAM data on EEPROM space. SRAM data are placed within volatility in mind, so offloading to EERPOM space, which is non-volatile memory, will mean the offloaded data will be engraved into EEPROM space. As result, the it is impractical use of storage and the variable will change in its value, making the old data unusable. One thing to consider with EEPROM is the read and write operation cycles. With EEPROM, it is crucial to know that write operation is limited. The read operation is unlimited for EEPROM. However, the write operation is finite and capped to 100,000 cycles of operation usually. Thus, it is important to save only parameters that are absolutely important for sensors or modules to work with mostly unchanging data. Additionally avoid implementing in a loop code, to avoid constant write operation, as it will wipe out, most likely in instant. -### EEPROM Emulation with Flash Memory. +### EEPROM Emulation with Flash Memory As EEPROM is limited with write operatin cycle, it also applies same to Flash memory. Both of them are subjected to loss of data retention after the manufacturer's defined life cycle. EEPROM is based of NOR type memory, while the Flash memory is NAND type, making the EEPROM more costly than Flash memory. EEPROM works by accessing the data byte-wise, whereas Flash memory accesses block by block. -Sometimes the developer would have to use the EEPROM as an alternative storage for task operations, but we clearly know that it will be impractical coding due to its size and behaviour properties. To solve this, it is possible to use Flash memory to emulate the EEPROM. Thanks to `FlashStorage` library created by Chrisitan Maglie, it is possible to emulate the EEPROM by using Flash memory. +Sometimes the developer would have to use the EEPROM as an alternative storage for task operations, but we clearly know that it will be impractical coding due to its size and behaviour properties. To solve this, it is possible to use Flash memory to emulate the EEPROM. Thanks to [FlashStorage](https://github.com/cmaglie/FlashStorage) library created by Chrisitan Maglie, it is possible to emulate the EEPROM by using Flash memory. -***`FlashStorage` library by Christian Maglie can be accessed by [here](https://github.com/cmaglie/FlashStorage)*** +***Find out more in the [FlashStorage](https://github.com/cmaglie/FlashStorage) library by Christian Maglie.*** -Above library will help you to use the Flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As it is for EEPROM, the Flash memory is also limited in write operation cycle. With two new additional functions stated in the library, one of them being `EEPROM.commit()` should not be called inside a loop function. Otherwise, it will wipe out the Flash memory's write operation cycles, thus loss of data retention ability. +The above library will help you to use the flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As it is for EEPROM, the Flash memory is also limited in write operation cycle. With two new additional functions stated in the library, one of them being `EEPROM.commit()` should not be called inside a loop function. Otherwise, it will wipe out the Flash memory's write operation cycles, thus loss of data retention ability. ## Tips & Troubleshooting Notice that with boards that do not have a lot of SRAM available, like the UNO. It's easy to use it all up by having lots of strings in your program. For example, a declaration like: + ```arduino char message[] = "I support the Cape Wind project."; ``` -puts 33 bytes into SRAM (each character ta|kes a byte, plus the '\0' terminator). This might not seem like a lot, but it doesn't take long to get to 2048, especially if you have a large amount of text to send to a display, or a large lookup table, for example. +puts 33 bytes into SRAM (each character takes a byte, plus the `\0` terminator). This might not seem like a lot, but it doesn't take long to get to 2048, especially if you have a large amount of text to send to a display, or a large lookup table, for example. If you run out of SRAM, your program may fail in unexpected ways; it will appear to upload successfully, but not run, or run strangely. To check if this is happening, you can try commenting out or shortening the strings or other data structures in your sketch (without changing the code). If it then runs successfully, you're probably running out of SRAM. There are a few things you can do to address this problem: - If your sketch talks to a program running on a (desktop/laptop) computer, you can try shifting data or calculations to the computer, reducing the load on the Arduino. -- If you have lookup tables or other large arrays, use the smallest data type necessary to store the values you need; for example, an [int](/en/Reference/Int) takes up two bytes, while a [byte](arduino.cc/en/Reference/Byte) uses only one (but can store a smaller range of values). +- If you have lookup tables or other large arrays, use the smallest data type necessary to store the values you need; for example, an [int](https://www.arduino.cc/reference/en/language/variables/data-types/int/) takes up two bytes, while a [byte](https://www.arduino.cc/reference/en/language/variables/data-types/byte/) uses only one (but can store a smaller range of values). - If you don't need to modify the strings or data while your sketch is running, you can store them in flash (program) memory instead of SRAM; to do this, use the [PROGMEM](arduino.cc/en/Reference/PROGMEM) keyword. \ No newline at end of file From c344c82eacb5da39d2ad40cc604dbf09786cf9fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20S=C3=B6derby?= <35461661+karlsoderby@users.noreply.github.com> Date: Wed, 6 Apr 2022 15:47:30 +0200 Subject: [PATCH 28/36] Added images --- .../06.memory-guide/assets/memory-guide-001.png | Bin 0 -> 52654 bytes .../06.memory-guide/assets/memory-guide-002.png | Bin 0 -> 77696 bytes .../06.memory-guide/assets/memory-guide-003.png | Bin 0 -> 46590 bytes .../06.memory-guide/assets/memory-guide-004.png | Bin 0 -> 30923 bytes .../06.memory-guide/memory-guide.md | 4 ++++ 5 files changed, 4 insertions(+) create mode 100644 content/learn/03.programming/06.memory-guide/assets/memory-guide-001.png create mode 100644 content/learn/03.programming/06.memory-guide/assets/memory-guide-002.png create mode 100644 content/learn/03.programming/06.memory-guide/assets/memory-guide-003.png create mode 100644 content/learn/03.programming/06.memory-guide/assets/memory-guide-004.png diff --git a/content/learn/03.programming/06.memory-guide/assets/memory-guide-001.png b/content/learn/03.programming/06.memory-guide/assets/memory-guide-001.png new file mode 100644 index 0000000000000000000000000000000000000000..a4e1067d84a34e06022bf6d6e7525ef6b6d2f2dd GIT binary patch literal 52654 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

    IZSYCI1XC`QNE<920brG-t3X)uye9WTtfl-7iQv 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

    KE#e5;Fqe#}A z5422T8@60^ye#_<5en6YRQX&euhh4F?~-pdnfS?3O|80Buz01c&)ZI1`uFy-PV`p` z5`s%D-bKv`A+-xNVc+*y*y$*{CXOcXzFTgKi?C=9At7}`fPqe=@Egp`L3SDcj>%D- zcVJ8Bo&hlIB1H6ql|DEzYjWRLqAFi3P(Ez@=k5(f#hwS+R<*7$bl*n_6gQrkCHh+k zUb|L=i9ts3lZ>u@s(tZF?cOpt>^Z2*37{X4f)s+-uel^n2Ne2r+9$k`(~13lquNf=+>1;9YJp9VOO2SNj?{InNC26}KVjea z*8pw&t80Z9O&5IO+w?rte*#OOEcO!cyVFcDerRX2d*;@TT=&VSjSSA$C#ijHh5y?y zWs}zV|66SFk4?^hrH1JL;YZd&NG#^aK!yK>^5rjr<;m{RY&Z57!!>ZjHQ4Jn)jDTO z4p#vgOOBVJ8h7b)x)Xv0q$g(-HCD4)vJ&I)YHVd+4f-xf6Le}5e>unB42jAe2>kfq z5ht7Q=d%fkMVcH=AJ{0kSj{~`tq%CvKb_fl*PO+)sYA6Rm2;Lal{3nuPlb9nG9dv! zJEwl;WlGz#dVO`yH_OYIl|1Fvi1q0aI|Jan0DaBMCg)aVf&=)vrMK1Ijh{a%ja8oc z*aXR+PJat_;^w-Yvd?wB&3ZA7=y0hMg!)g45bMh%jT;BWyrm z+0ZixnCA#q{X~;XFC9|rs6=T9#ZvBI)_&Cz+Tp?Lv|UDIYXaU8x0-V*aDCz_II?LN z+%zC{KJT%RMW}~EEZ@xD*^kM5Q3dCgX>#7C3p106GZhcb_|V2o;1F;+7=8MKp)Qh4 zn#Q{kdVjIJ3@S$E@{X?#L4vC!@-I(1BTpXUd;gGzR=$RKk?lzW-;Ck-V5dl?IEaE( z_?U#fu^%jAzgL9&IBnR94ffti=Z3V&xVTDM%KDi+98gcUj%{qSA=hoR`qI#%q3*TW z_3YrCUaU)fcyN+8iDLZrqV@0~o1SsCah^k~U=Pot9B63ir`f7ztM5BxJ&Co?rxp!z z5qeIoK7NrX9GVsVEWD30BUAsL@~E>_FHhhkWiC(1NYl+)2H4~b@PXHv>M7Hmq$?g zRP7Dx^Iy0*+5-{}bce$5_QC4B?O!TBv>!wT&&!GH^ZB^qX>z-epB(J69zPyY3Q}L3 zJNG7X-HC?2DF#w*KnAKj%pZfChRbjiD28&OW|a^)U;6_(4~!8DhQu=^R)La#5=8z? z8}&W@B9Vv4e<0l=_ocJ)(YY$m9`s_5bX0D+1&O9Sdb^JZQU^vmOI{-7?=-g=j{0n$ zP@)5py!VoQlIqXu8tlaC!!L{*Q=Tko%<{+5W7T^aLzDxuX#@e?0Oe|0_bB@#30MkP z_11$j=x-)hGOnL5uUKaedO~_IU@;U!LFH~&Oa05W*ZsJfnU%+J;nohg*xN8N)mVav zyOPKgUr1=PPWUPmwVJjwt|1{7i(*UtH*>%?5vHy*5$O~~`H-zYd%VVPw5LMzgT)>{#Ft{0c zfnizPx6MldpV4ww10N>pz)~Ju&ldoh0mx{9UKwow6nZmbDlecTJA4TK7+BOv1*0+2-`d*tAagtjJ3}F7_Qfm3{a{_^0m8I@D~aH9A9$6 z0!|gXd}R4&;pkwMN121ofB|6TPsWoaLa3`Y#**vJeeY_!El56jtKTygau+Sn1(AH^ z@3r)cck}AZjCQ3vWv|7>QnTXMUT1&Q>t4UL0E|V>)^CRQ)>n(H!F_wXvf9M^9+=Li z30J_&D|-pij>Xjaeypy*>NsOYJZgea8+G5;d$_t*ZK372C;wiO9$RqC5RRb?o06)vWn-N1!$`K{*xJY8_Pbxix@`<< zqIF@Kq907pCbdi~O40ZFibBZ4V)G~K8DD6#61m=UzETR+(%T`qFSn$wNIM7nsAGaT zNPKym_MRaf?SMBj*&R|>kl{>QUi0)+^_T1>O#EWnm4ql|=VqBt#zZv&yBv$5*vEi<1qAC8Ha zhWocP>?=toC_$IlWjRxv#w7Vn*r8u`3f5+MGn|z6PlykJQ{@ZpVxsuP_eEnFPjl3k zB{>z=mo~8Lk%J1k6qI3^QsjnV0cKC~$+1b*mXnNm(y&){E*Pn2&9+19=Zmzdj2i1{ zhKMKzPUCtno%3<6SpWIm!$v%WwA3To+ZbQjGx0aW&2wynLqhbUrFU**9xN7 zLl?S-b0~ffnVDx3?=G97m1}PedOee=GSjgS!G7?1e3CNXI`nWEUKZSOD21HzA*w*I zVQx`W^h?_cJs5TX1;&J1!e%9sKk(4+S@%RP^~@AKF*m%?))6IjUuJJ}{Osim?z*rC z?kI4(?+#B4=Wp-+m7nu#h}4Hua)zs+y%H^RQjW{hD@DT6-NQ`SVRwVYY#Axk?ukI8 z=*xn&j%}(tsgVZEj?YjXVg`=FK*O1wyzMxwHdBe(a6de92#&?v`AdClwCu@DvW#Dz zuUMe&>PKWVVz^LRu5qMsk*sUrRP}ORafdUzsw_$SuRAB(6A~9i45P45h>gZ;24mBd z%euFlxE{L}@FFRsxn=c|GB2@T?b1{Utjys>(n^?Bot@Fd>G+Zm!9a=El6_F$wI0|S zj;3nN`St>olUNJ|6eDwC!G3OL3eWzdC1apcKqvp|cz^_t%xvm2-;J4#P+geO?@!gg zxL!=;lQL{W5PFk?G~K`YJb3tHf-dR5uu`(urhn>_)Qrd765V{P;nGAdC7ptOMNz<) znCx>I*O*xAE9ccAk8}2i3U9W33lUr;2qWKsnm~Z4m#jJFA`y{g)%m(AdT^;fbV>+y zXjeBOVey$Q0H!g{{9?ppB^# z%(X651P*baHPuAi6`lm-pWjR$SO;& zUfV`0YH_VynELRcP6hkk_?bsyU*PvNiz9w^pd=E0af})G{ln%Gcu+(*15?1?4}Z4w zIS5zB3g0W*0BTY`aZfU@%SH^G%d?L}P9#2d@sc$jcNo@EUUXwT9Z{nAWQ$R4JEDjd zCUxx{QToe=?p3059<=!ZNepO-81Az(&^pBu4JlvIIzMyWTDHW9$EiykJi4z#0CL>` zubAUJ&YN%k{qFy|)*!<{_rX-|=5@WPCe%9Mak!_-9c^t^Y&N?$>Hd8Iko-OltpKn+ z-#&l*IE6psUX&HY<3n*Y8p*B+wkpZiQcY?EA44M+)^JuzKeDRYZ#{Bm!3l@6v`J56 zJp@+`9xhZu>)M#g9GjPGX~9M>j_BN;pA&b&CDqS1GF#@tIe{ZsM$8~Zr5I^si=!V$Y5vzc)Hu-TE!T%tJ-Em1Gz!*C*18Z6Xpn~MdE_a{?l$w&G8jJSeAZ`b<- ztkINKb_M!saT5pPSED%rvIva&Au>6=~IeUD0@f8 zpuK({M(-pD*??LLx^MMOXQd8DW9%?>vUONXNV9!>s6J$7DFD6i@X=6i{F!?;1{;x) z(SGUKH_>vD6Y~?atK(YIq0h7OZpxP5KK`v%RV#Y$ zF>WVyZahF#S0?lFETZp132tAEj7YP2`c3zCOSacVs_msAcRcKHNsX`Z^5+W)eR~>a zdgrvGt6Tf)oftqfrs9Q*+3H1oqHN>^(Hl08N4S?%pVdSq@`KE}bMQZnu)mu;5msOJ zVENho`%`zNVp|>!2Izy-d5l=+W)F+e*B;ouqvGPp*U<@*DfI=iICr1v0b)rw!oQ4N zjkt-<)oqcL@AMv~Pg3f8Bq+>%hLHhIetj17J8S zq$}a=)(&s1-}UflI}>>)GgQXwFU{}`e54Opiq);pZjOEjTxb$M%{(m~tH}^{;O$DE zI!iU#1wPt(;Nr6k-XuQi!zFvO|E1@!*RJ&%n|}-9C;}Etv&2@T?%%fbee8DS9hcle zl9x>-a*;JRb7yc7-(BE4tkid|83C#ryEXKj`_s~!4c(tqb|hx-tS>wg1uOO0_nQlA z%(lnn(L#rHdTLnOva!mJWQR5H85%TU=Nb~beqh17j4&bc{NymILs5E)1>f|4rY8jx^oAZ9r$Lh@AEa_d0k|9ggd zpt5d}dEk!&uDZ8%L7>V6&K;+NAT~Mvo7Z*CgV`3Ds0!N+#D!pSNy|l5^y^2NUFAO# zT5rxqo_l$@PBY=$li;GS$bU>ZEFTD*ap%=USv9-F4!g#l8CGch*c|No__1E{t`*P4 ztDPoEuQ=ad=tl1^dFG*Y{?%1Kcg+`1c|4xDzGxXRIi9KWCHoEuUS@)#sxc`vY%OD* zGQ03&scAf)pf)Z@&nJJX1jO9V*M5Wo`Fv3g1G*k_VDa;{CgJuoCmc3 z@9C9ipuP11$J;Xpn*W>tvN{9W6A*B?aj?n%J-d31Bb@E;=_$Scd&~bVWqEaKqc0zl zQdn3BK*F)|y6ELw{nulQf_((4HROljmqDqg4`m0Rg|Du(5xpTzVIedtBwVL#qTb(x zw`${u5qf;cK?jZ?O<+gfxn@6XAYj%Agr+e1coH#eWv+K|BAvuPFd{4x%|mMMs$GtEiSE9L&+6Wk z>fjgL<&jd_J%;aIP55;CXZf30T+kjKK+NTg6J|oge#cIok8a0s*Ca6%-fq5x2#D*E z(Mv@Lipu@CHCpvC@vuDAh7Sq3ZcS}h!~=i2L`{|DIF>CVY;HJoe6pX230&Am_9jxu z!^g;N0}tUV5!cJ7I+Dw09JVv(FBfTbqim;)VuBNpvb!0S4bEtL7JDCV$(v9qAva9z zqHFNuAILeVhNT=TyGF9Hx6=ajckvqRohXTnT`sfmCTg$m+(B%M6Q#4Wyg`=rAHxXe< zSxw>@Yhzp5;DL%lMa8ELF;u-NALS-F3SKYlf*|#2AHU+8>4u14984qSkQl0Q6`plz zU}^mZryJ<}t+36a?eGCYPw*x`?QlvzB`IXhreP4HCQv=U7QehPb5{*Dy&8>x} zct`Ktup0POkaIGU^Ncn}+oA407jsoEqgo5R>0PCBBGmlhg+agI{`C`9;>+j{7E;lr zUHij6zlwgc^!1>3iU^7rxKuXXQCP$#Gd^m8_%KCZIhQg>0D+`GBr2lsri_xMpj<(m zp1A_$MGvPKkpV9sjQNnl6*r$V)3n?piSW!b*0UHfx~qdeNA{_F-Oj8|I^%6BT=2K@DMnAxW&5x5YQtM5{gqjg!Wtq2Zsj3QQDl*#9rYYm2 z+-;HdMe-}(4~ifxkEK9LUF_kdtH_nl3SSDUn3V4W#ptARoc&g6k(WMa#_S~v^9fu| zb%0>Yi?o`?2bIT+LLmq8#|O4y8k1v#2-X7^T1!Y}W(EzY5}YLM_<+){Pr`=#o<-RZ5ox!aI#JPR*9 zdF8hZl+BVqEf9^GHYzh^FxWwFPyQe@l@f-x$Rw$iEp@#<6faMSLs6Tdb=y1!j=AcbZ)wMc{YMt3f{!5+PtypbKYY`(6%laBh z^?8v%ED~ov1{==RUa}w_9o@P(v415!kjM&4PLjI5G}^&Xj6X*!+{oNwpo=DC*e%3G z9ObvdaEY9~XVvY{7$Ng}8>A>q(CP~5>-n%+{1h)}zr1g>a?iskzR&k+o%7s(IfWHC ze4AQ#Jg&(v5mS7mGuP|hR?Fr!QG-!~OPT8}zRw)EY4YkYKJz%9c<#ZKcMUt+1}n%8 zj@W;wmSLv%jvaK!vDWwqIaALgkw2}*Ejw8 z53ke?cWi4tSUG4Fsy!{zdg>-PuL$B$W!@M$jk5+zL{bL#m1QuCBlrLg_+bIR$^!UB~%DnHJDJd=}nXDDo!m#xobYsEa`S>z){8X4${7{y_3?Xs zA0K88CZv^rAClO;i#^9(* z*VC2Y2y-0@N!#kg`Z52dkC-pGvX`-l@>4&v1ZttX`#|!yrq;p+CKpXl_Kz7knh6ft zj<{N(hdV0!2jqCmj=~*^nhamqR1_UMS*zsB`S9q_663>^wii*z8BTS=T;391syX&Z z1g8F|fs~G3M*P0p_4buH*K%3WD|m=q=l~VwS4t1Vqo_Z0&p~%D8v~sD{Jmaw^?|}b zZ?I~0&r;4Ig^QHn!ML-syO1D9F3xth7fDSx48Qa|<0e>kgb99ZtM(`DH;B}3R(CalZs;epET2Q|Mns7Ee65O}16 zMqL|s-FE6UUIdR%(l`_%wOZuaR|b!cm7QwTDjRRu7JX)~^p@EoQCH(pbIX-qxgKhiR47@g*)jb!u|CY0S^azd%2oIWD7iy0N zfG6vG54&0*%c15!-ydiW%!|4PJ~L8!vU_eq&JPG9-UU(rb5&N{3cc3EGhRLtX0HYVXTJo&xS4wF_POO364NLU+Jd{JD7TvqZ?^yLq)oVV3-ScM?IIiWDSSs59+b0P%xrbrsReC`5H_9_3NTMWQitMt8W|H6!(JaYuS%& zY7Y?FZf)3S7O&f0rVJlAogS-z(-KX6P8_29Nb4s~X#A+u`9e@CPoG9G>$jXL=T zBozJv9P4bX6QB=DLS8LBRbOxAW@?)Jr*g|g#zO%ErF?iJc1}R_PW4h&9Dw_y_e!te@CONauA7mT5p5Ssx z@O2;_xt%Wf*iA=bhR~lGi6n6cI>fG@02#umQ%Z3zQHU72tDP0e$O=+bP<(3hrOh|F zH$do{QSfkqU5cjYA}_W(v#&NFjxc4K|DGgjj=0nFkmhq{-`fJ8qIfOu1{H4dRH}2c z$1{8jYs}vA+EEQqnYzx3$n5lsoIc&pc+igTsYX%qmBD8+s6)Nmtn;Xx{5D>X){o`P zw&%emF0?gv z0330Dw5;f&*V~rlnc?WiM+&d}Bh%e3SrabnS*lu7G$e`jdP%zvCOgd@k9fPHe|4o+ z6g9M>uj{o*Y>Og6LN~t@1_DNc4P^BXZ)&US#MCFX^1i8iDklQ_7e>!k%zqq;zfp;O z8lp8+DDZ+u+I_b`@HrOxkjtQSG~bC5c(Sx;uxWaj9m9d{D2kUrXvI7x=GoR7J|Yovy4yCdwQhm=J+JK|@(7%6hPkKOjM{hzS(Mq2uUwvk%iEEZ2X9Fgd+d&t7p*B2=?66;39}BV zT$dR?KV#t@sQkUS$z1>R51;&W4%vo*i}(lHn67>CpaPP>chj8fGU7^z+G8#XJlhLr z5b+L8&iG6sKoGdPJ{5Jlo5q-D<=Ho-oD>{ax0MNCkb9P>jsxK+&UwcO)v{ICrH7L` zi_|XmEiv-?OVUu`7GVFXk@>P9?!W@dJIg^J+?)cJVtL>Btmtms)t{^jYzDaxpKY`$ z5~wjcquprP^))`(8Q|r-r}VG!5vB)a8_Kc*ec`8G(>~FRb*2zO(mDjrGx6^7}L{(Nm4?Ra@jvfRH%0wvy*IGu6Lc z#e0Q#u^hSWvU8JnvO>yyi4T`1wxlbMZ}fcLfkzg=otdP7tDa|&;!Cb%NXOuSHgixv z%N#J#RJnx(8tjsH4E5o$cA7hk-g7r> zvGv7>(YBLHbhNOc{5RWzlQpC=YY8O-_BM)nVBtOfg#=8IX)k_p-Pdc^HcIc)^6(ED z!Kp{Dpsa@iyB}f)8oQ%#3jb&Y#tcKog1su}T`sLYX9s-Z-7-VN2|A7xu1;Rti zb`RT%{Dka>SRo><44u*o9c_vwG{U9Gbyh6hX@HSW(mggyohf4fMIdX`V?Hk}1U=W^ z^X4(!7W0QXH+clbWs67G`m1GZBv-=l=L`;g{3XmM^UR*OXpCjjGKuO4A=IY?C9wKU z2!C8m)$BcmyJwDm70hL>=`B=c-`!4c6V!hif2*9)P%12Wm+aORwSy#ttiVJW-~kg^ zgGRZ44k-}G%8jzxtb#erpF&K;8?NQ;83Vr z`*^YM;siJlInDThciV03sWA_`z)PZV6*K({(jSUUH9ST((Tj@L$cl6K`k4)DKT5y2kgxG}^j*O}ie6WhUs0y2N{%xBkIY!YhS z8v@ZWWC*-}U~B)-lFKl*xU2=dE!wJDjgl=%Pdf||_)G(qEV!@$m}+`7qA2~Ud~7^& zCCe5psQa|`q&{G*zZDU$8g4f9FXa?pS6Fe>H?1+(?M;q8*;^?WsB0aSOJ7KT^42>U zIv_a}Ec3mzbwM_#_+eikb+p__#-6brmY)~ZRtij8Did*8t!AqVCEFjDi_?;u!Z4Yw za7@`jYre;8V3l-Ln%CGwF$mObOP}z+Q=_&!CLX9?D_`f$KK=bnKYXn)M$ZoZ3ln;A zP8zT-;vCF!P-VXm zq=aEPU_pY^c2Ib-TL$Eq41`kk552zZY^L=Q-q&9bEd*S5SwwZdwCx1R8w80JNE+u= z#3>v4+Q;-X4v0z0EjA^iB+J|(U`xsCPPY8v8|swH-R(>K2d^$Vls`r;`pf-v@${kW z>u!!)^M8A-V=BUZSEPIh%dc-D1zkP1&59X9n`Ka)GKW-AV3fw02?>Rs)2!}3y63ar zz|t;>D$zlb?Sb|~ulK2ksmuB0h&yuz0GfPw-HS1w##0O?k^}FCoTk1=OU8gdljYU9 zt84l`$VQVBM*U`uhsq1?*aU{y3*%XB(^IgA7xIg|9kDg)_9;0}hoLqwyfTcg+OYZv zNwQCVAMG-V4Odj2ZXBC%dih%qa9y(vF;g4j*Bf2wfo^MBv2?fIeb@yN125zi)Gi+R zre!XdKX4p&1WX;$jr#%f>v;i`6rin#KAWH|S|qCnPbRn zEcihyY&$esD@RJ+e5YKq1rAG&XXWP z(Xxf^pZ_kL!}1Vw`LviN*O7wDCDdzE8-<(!F%L3BvwVe@@R3Zdk%F)bhqBz*j)D{| z0w0k(8}B6)AuzjU z%J&+)$0K;CXvuHCi0U%k8+v>}3PK+il;T15m)t<0RO7Y7OGSKvy%h^3nB)QGqQ716 z=8RCy+Fiqs?vf%@ck3LkGy!(>j8saGYZuFD4NB4|)YhF|w z_jH!QfuU--h1v)A?9PPj17Au-Q8K1UMs%~8$8hB|l zjvm}N6sdHt$(vNfZeC@h%UwBp1q7-H&Sgom=LQw){e6R6eqj8?Kl%+<)Hg@rIhQ20R}Cvezr83S#D$9MU3IZtMPej82q z^gXO#GYl61frM%b)V?d-h)S=Q)wGp%4>1@iV2w8y0MhwegS+w!hzR~3|F>HAzg(uA zNPLy0>3cRKJ>8wz=r>U02}b@~>l9KsAqt|xH-9c(qK_qJr5#3bY6LBJde<-296bEQ zK{NCUvB?W^haM-tZ6#(RxZFkGm}sCb&sSR72ZCvi$gqgu?%-v6%{rJ*&;#VLBjUDA zniTLN^?TZy^367Nj`Ew;zB(3v6dC^EN~O$OAKb>^B29B9?l)|9VW5=9by^?b->}IS z7i>QF&iCd2Th|TuRd}TsE-^V?3-h6nftuI_B7(Vr#>Mo|7qT=UUhjN5eRMW~QkdS! z0QQIKkV^5jw9?e>&c!xJyEMgKUlIiX^OJ6?^fF}iEsAFa<1!na zSvcZjwg32H565E(kz;scr@#LlZmQzT_Pf>}ciR>ewwh#Vvs<<(&ro^edMHQsV6!hnMiCwQN4hgFPIx6~ z{BAu_YNQH?=;YsV&CY3cpgJCOFdTd=yk(hEPN?aw3TFkd{5y}!F4L3JPU3ivmoFT@ z{O=Cr>Vsc)$4mblO8i~RQ~LIf=V*UAn}|#f6+_M*86*hHVI&)72O$k!O-fJe%yH>tP}s{euPY0&c9 zR3=1l*%QDI5z%sVq)GF)%pj9#D_)x8GWh$`vCq9Y6O^_f+hG`bcS~Qj$_M(@XUxYavRQ%u=gfDuC#|Z_FCEH6oH{e|HX-h%XHVO)?Yh}D)xki@ zU>C(oBO*5Fp-?q3Kbf2kjNW?dZ`NFiaW5u6upl|I!t*ld~doa+w5is&nCswFV&)C#S)_{R0dPy(jrh-`u3?0?vJm&^&b!u0TAQU zD|mkgr5_BNOLMi^{d(#x*o2&bg+WF8t>`K?IwU23E$BgdpYwk(EOcHL6n_$nA1!mp zux?P{|GE4)?IadVK^fFFAkN>I*b{Vo8lyF|xpHZfIWTzi-(4s$0zB+zGSSsQd_3vPj7v3VkB*c^dKY({(Hogtf>rT7yP{JvPIyfC6`9uRV4*^s?>;= zzMEDK_oX}RQcztJVQXEB;;7ZcMe*GgaWuXL+4B5v6Uv(=J!s|iPg~N zy?p|g=Z@%`RE8dEV?q)L*CsgPimzXqv%01VWoz@C;&|QnR>)E0`Xpl%$n~PO1X1<> zyz@!>w{Hcb@yDa055rblUkomiDwMecBdVL<$4t_Pb3{Fu8d7CUltaeRsizJYo&AoZ z5QpJJHc)fHUG)CU4^Y?C^Fi#7Mn==q8bOKYM>WN_Nb%Zl@C48EdMrD$-d;!c(JGk%;rS;tBq;#T~&s|?(VL~r313pdl(cP%VVTypcwK~ z?hjz(NB0JCgj2JuPhc#CRlJUa6kng+(F&V;L{!I#vwlaSH-rZ>mVj(FaJXCtaqW+; z&gIr-cseBXdS{xxd5+s%%weJzb4l25u?~N(61uj}QRwc0W`#V#uhv!Y_!`3OZ&=5m zOev7G1CH<&e{c5YR`sC8;l*^^mw(5g_BnefB|E@oj8k{FQA`K4 z4r+40__sgz5B~*(=fwtsH0cj2EQp#L9j zOpO=zgTl{P`%grBb{$G4*z0Ue7cTabnzHupX=K!OEb$u9-qhSPwz3j~wiC3Mhcml% zLe4ZyL*(|>-~8hqx@BhX!7*nI(wepzIfYC_tg6<=bS*lC6s*{=`wewvA3t!Vz>9Rz zx7Hhg-`rC%%(lLS=qP;g|D0i8m6}BZ42MuPIO|aPgT0AO znWFc{$^rda75A43G3~1uT?%Sm@DsU=lvEl_f)l+d=Eh$Uat`#2(jfEVwGIzO%5l6) zsCA;7zkTah{}MHy5Xv@@y7P|)>ubiyia4u)GJOcKyn$O^LzjLsVFtU?nkum#+Mk-L ztA#aatu2h&KCZPSAUEXwdG!eSn}zf2-3Cx-M=-3Yg8q!HHde`WGn$oQIaC`7<&O_oMaeeI~YV7j`YY;9}dbXBF_inuH~-@Fd(tV4gvXp>%Y^o z+AjnWGBWKMdnITSsBapj^dh@qd12&LLxfN%V=S;iUEsA7;`SM0hrfgW&x1*XtmrAZ zBaI9>Mlg{U{i^=Z9TvHULH%9}ITwG?t1Zygek^Gm(Dg6PI|E4ZhAp!shA6>Q_L&*1 z>Ii9Ik9H*9?wT;^Iwq|QXiffdu2ubH3X!u8fRTSU)A`ww(oIwTJkN3_><}a`vQGdE zS4LDVHPOlXVC&d$gd=ojrH{m5Ely990{&SE%hBMcNaE)v%oWn7E@l1DO$}m~7tivWR?h;KS8ZRW1mF~SUV1NH>eN3A`UX(^03)r)cVTB_` zjQ7w(2AM#N(fs;iIRd>kWKnyheD%hF~C?D;Y&Jz$#( z>9_|eX~;JLv2F9~7s)1B*EQa+N)GYp+t(MoAf?3QPSyCa2^=JDJ8W-#4}AOuLDYFA zikdd`B7niI9}f=5XE!`*AEFISTrl8EiD}=gZ~S-{e5r7?CUl(2+*%vEqPShJF*I>DFboXTJx)2Y$@2R{zHEmC&8zI%6iWsSG(kHM@Yy^VanEGY*;MXzO79M zob^`fw2wIn=sLQpSTI7qhu)v}Ym5uz_~N?Jdyn1m&uSi|u|2aE!Iu{_z(VGLj}6mfX#aENqO;C?>6|;m1Hag{cx6z z)IZ_W*PL`L3@}UmfR713Cm8Xgi?lPnDBMt%id~8cc}!oYH<4;&O`?>|8g31dx_0Sv zFo$k-Fkg~KQ+00jSCje&W>Gb_^%c|>$;(6g4V(IEEbc5458}p}y6=F0!WY`iyoL^q zP=}m_aiO$O4DIe2FFOE7&B119x&eTr<7yb!f{ljxtqIbolzA=`31uZ)fh zs5xpL`%gSss=qXWFTxQ+3T$(zCEdx{x#KmIH!LR(FL}5g=TTIDP2RT&1iM;+-nY304G%vy%j(?8%rPMZu6_2I z#gocLrWD15$rVG)_@$H~MX6=+wmmej75){<7cNJT1M6ja(&zFBa9$qkHQgn(`Bv?aVtzm+Bc{rQG^DY@%xZkoLxUW{??k5f)1; zbGHOXk?<72=Ur7S9MRYl`(D>{Y^IQmt;GP)2G@9Wx39_Kv!&%^>y42*hZ3-P&2EDn z;o(iN05Jwp_wl2A^wP%m821c*r2>1`R5h7sJn(|qbf4<7p9<6b7#t>bWNgz;Q(2}8 zFoy*#KEF zh)75H6^tR5Mw^ypbLcQVVFdE#73*M2!@QqYe`5A zjlczS3aKkY#g+414Qgj|rG_Z5x@7>)q}1_Qlvuqgb--x@Y&-l-I>NVb&jnmx+V0etTzAbk`-)bic^i=a1q zobg?h@-2eSZdi>gA=|U%`O(r`KXdcAQ}$7>TKBGt2Chrg2U>C+=W;7zb61~m$_l-x z4saIDaC=aN+GP!HED>vKM>W|7ma&ZG#r65Vkt9pIBrhO!0jw zKcx^MbWgu9v&J6mc)%M%sTz^Hr&BbrJtQ&ZleuV=5S7JD;)V zgm3UAI_yjdx|X*QR7hd|LAy*kVL|}^poD0q;-_LDs>59G8}TT|D#LNk2mJDb?#u#K z<%l3Xj_82gnjNf}qS-YBfwj-S*Y{rRSeb6~sAYWNl&e}k!BCxZn^_HVCJH))`4aF! zm8g}?DO>!xn%;*FQ$X_QuI9&K``EI0FMQKjK;Lcu?vRyCyqXLRu1$XHEgrLWPXywN zoCxIwWowb=l(*+=GO4_9Wnz`&L>o@ywA|RdZ3f zXO0jI#SvA08u%Ntew8*+&eN}rWYe&$F@Hk!kxx}G;{bkf8DShuABPdk40X+#?kqz1 z6n!C@P0}_G#(mpFlNgqP()hJ};zgu*TTh{UOm*7SR&=gBIJ3COt2N}}k@;aNW4WOm z-0T2fs`etrIDg_{oFtqizg<>yfuuMfLp8Sbq}K{4(Ga8&GI}0N|xM;=XT=-D?8ePe;Jv0ESy@=TQ()`Cptw6QCNaFID!DKAq*708+y> zPUD!xz9EMkZ1B1pz^-G@D=}={Y3_iefq)#4bdmO^oI_LNQYfF{EJOe2ar_Tpk6d=e z=12}>_=SCQs$O!fc?FtReTinqBpZOe;?(1Q%d{#-Pse$gS0_Z13_bGA`2to%9{9!s zcu+`5P^jURc&71!w+~Fe$qBSQT|~wsWDV{bvJH1M!A?X34=~;a$4?DUIY_)nNtOrR z{z=#E(oXp+u$(={fA=~Nc9@&Zo|TS{4B%U-bZLWfMoPYM&Prbm%H3S7`ekC;sjqN6 zAz>p*FV-r%e3m=IuC#1_a3=9)HsB;GVMGwdkv z^F2u}YRn3bckaqj$0MdQ4SEIeEMW61l9BjrJ=1R=h%ry9cGNAF;3^M!#ehbp>`OJm z9=8?L&vMC*Y8f^c-v(+mv4@o4T1s#xlCOVJ9=R6UO#mM0&@&3gEl2X9x;bCW2C zr}mlR@Hc)qzkgUcZgTLRoX0BH*}?A@b$s|V4{?im3jZ84I>Ud^(e#D@L%7Xe>|j=W zYy4V9e9dh`0ZXq7v~uDcQMJsu>QPp36J|O(F!?+F{vss|Ps^!~AS}d*U*9obug+xDpfF|Q zNoa2e$9Qm-^9(HZ-g1rokGIZz0aa7ChGL?>C?N$Mcv|&M)sXB*pO!cLeD3MRiuea; zoSqI~oh;cj7RYItLXVPHc~rkRo{vdqN-M#Ylr&;-z#D1dY}X(29klelXzgyeV^wby^Q zj8vYu@aZW*J7cMCp-63sJw`s*A4y7m<;N(kg<7u)DiBqmOo1u?;rw!3Q=ppN zsS-mVY=P%N%k!a;D^PYIaC<2!mM4^&APE%r4mYOao!^y(r=`0)ki9CS@v5ZpL75|_ zVO@q*!M7mR__eQs2k{ghiSWEhk>`>&F-otTW!@JBCOO~tx9e@+oC}2hZobMdv-8yY7yJ4b*Ybc#oCC3g1a9+PpLITS zq*C%915>_4Fh%G?#GoEOrr5H)`v=oH)}LP{`+KxrxwK3H`BJx&rlD1{UQP z_PnjYZA|iQzQcKAQj!LhADweLaDV1=MqUi zTV*`Rns2y8lIH9%9b9x|W?dv2T(fmrsvfJ*;_zHZe)DM2lT%Sy7drp2?)&KHTd13iB7F&YsJ zn&&&s)o&7|8;_%ThkWgGgX7k$_^kAa#qxmA^YS|KBJzd->au22YiO!f(o3q$lDrl3 zCe6MzjK6_T?pX6J7Dp`X^ zqQ8*q$=MwO_cT$Oh8S_vD1Ng0@KT*OX8z-Ma!l^0;Id%mbFFCgBLl(l>l+C}XC@Sl zYdC_s0Cz6bWOZpBpJxck$+Oq=yWdTXseYU$0zhEn9-2ENU34x9;3-xCurXgl+Cp)8 zkZ7T>ek)$kAyXzoGBfvO@o1adTEOCPWjy{@#dQVnqT%=&e`)@6(*S;bztQhSo8t)j z_)sV_cP=wQ=#1@#$SgTJSBa*taq;`J&mhp#7la$V;B!!#J=Wiq;{PMkqSXCh<4VXy zD5J@H$>FjRTxT!WCIluoDk*Jv16gX-Y!pa4Xfc>VJ}NxuN>TCrmcHnkBGVy+m{r!- zFMf}g?EfCU5p!f^$MpB};o9N0yH#2?QV)&thY1ntmb1JaoEw_>Z*zF{k2mQmuHE-< zgNM#zj5FqbZsxaiD1ts_H9U}dYI*`4D)CLrcj|i3US)9q&nYs7aARDv3g+WcIvMd6 zD$f09lcXh_A6k^w-phycg05AY;QzUTf6tf5eD)c5d+&345aKv!f95$5w2)udXGhqH z+M8#{$i_F&cGl29WvQC|n+)K}m4t)ce<_-WSzsv34d{qmXuhR;(D}!pRHx8800Zbb z&Aa&Z98gjom9KLOsBc;{nX^;Gr? zNk|@MBnA+iX+yxJfUa1`IXwz{d`i)7>MSrW+2%mS%GS(`@i5%^7a3V%i&ZC9Jv5`B zZy%_qKv_%o9atgr04Q9`b!b4{^W zjHBLn$b_vV_;MN++2K`NU2_l=dtvWoV0qu7FO&NdbS8qtod7c`tx&A;WL(ho3ou9` zU@1SszjHxmR5_((!YOKy;97-b5C6KCEuYzoA-pCULulLSN*kF)X`|JxWf`asm`? zECk?T=AQ8}1EDb!5Z9w*P_W+{*A0VVVG50=SgcZ_wY#IAF+eOnx~0w6#`}4#az{uo zF*R=&ol)LETK`X_YOj(2>d8y}fOa8w4}LHc(mdk9-WH0iL^>{B z0?AwMph9*~wDz6;Ebn?Q|>@rpYx# zs&QKV)xpCg*Hu6VieZebfd;9=@afCl=+L&f|1Ni1n;21c5}cq_8W`Rp@5=Uf26FMv z7C^sTb*M|%#O78f2p#Hj-sf3krFXeC)(A*k{J*syACKpFD(Ef%sBlu6?e}l|t`AmK zF%kCC8tb&QMa~$|I1hxMu7x8f&;K0`u#=CDOs0zkwMcVuT=fJkeSqi*;1+$Ld9Tv}2(JxHp4Arvy)QvCDJD*jN)m-q z?((x!n^@bPq!#X4s0021@M8EiYfho?c7ffTE^YzG~TPG9YMV(M{*lv?9Ba8<@ zJU+^UrvFPf)4SXjvrax$UiM0TO(P}tpm6A)0_c_NwUcy=u(w+^f;Ow&ycxAyV^|?f z*~msNRnMai0UNk;CN2$|0sUeR1be{V0*v^t12|CE-RyQ@MYzjz>S=W7P*=$S#CC_C zV;b1)x-0*0rTlZnpI?3WI*f&pWHt}Fg>xX~Myd+Qj5ZWm#V+8LH5LTw{IdWdv%Q}V zXrO1qN4-z%?2FA$t%h8%Q8jFC*fT*TLloQ!2(;JT2ZV2heIIJxK5+wvGhw2jaOB^|^~=;wq?dkw`q*lJFc8-4+ZV0?19}gDDtzi*ffLj$6f-FZK=SP) zZ$L|X$5jacR>0@cwe4Lsdd;j(;)9NfoVYi`gw>`pJ9Hf*_!kxJxj_9j(X>kbRQWO+ zrwa2u#s&&+KfkBwa52ON>5csw z$Jv|)5I9(ow)`Sg3N?n^&rW(!>5vlUtsYQ9Oi9fDv`C4}Pk_JE+R)ornmrAF6NcOk z=niHy~8`xeM8+0|n=G_dn z3#;XoCtMoVCxG#=bQMh!KY@0XSeJ<*o^4(lT&)us(}zq1+bTe=jIyKLjg%{h;*`?3 zfTW_dc3MlO8j`Eqy15`z8lkI4k?;mYEsMUDEu^ zdTDmaR^)rdQrtGq80WJcG9F_wwssPLH%R*EU;Q4?|CaI`o8M4%$HcYTn|UMIYwHHX zi&^zJzC!UR$OSR1J9JzYGH_gOv(Sl(0$8#e^AYuTNd=Qn9z_1ND1VS#u#h2L&8 zJl`oO>LhmjddI@*^pwaLgSrQ#&b`vwi{F=UtCvRhQoSL2soqaV0on!xie9w!zB}~l zagNYw-^#e)cq7^R`?TZ4*d?HYD93ZWJOc>C(0;pO!IO{665@W>FH~0E0mYUF3_|m* z(UFOcwW<2T=->`TcN~+ZT8P{iJWdk~7Bf?wO%ZmQhHugC@PWP0y@zo#*)+P&I2!hvBtOvCc9AAM`dvK_2F`wwfV-KKd( zJwZ>y6EMFj`y4@zXYGK@^@u2JtQXTt0O|k_{|8}j9Tw#py$cTliijdAA*ry9O|wxt z6b0NCvXPJu=@`0U5D6u9tAw;j2n@~83`(hV#{fe}GYmNcOnuLb`+V2$ob$)wAFs=q zdEY12v*KRsUJofKtl0~hXw?qqrWPBN31TX2wFt5BK%sz*+9kt8$KqO>9&f8$7YVVn z&Zvt&y`rij>Fjco-X1QP4AQx#-5@_2b&r*lw5j6|Twasyi=L4=4ewlQA)J%bXg-Wp zO;SlHAaUN_)aP`a8sDvvrRtIP;;(ebF*|2+8a4DN{_7P1pRC`l$O77Z8mjh5y2W<5 zG2!L?ww_5lo8lpF7dz4kf%Kr1ZDds}`i<;Hz*k1j%Bd#5oyGC-)`f%tHiZrkO}oh- zhkI+b#A`PDprgzC7VKCeQ%rp~*KzYeC11)UN6(i$VYQz(YK*t2gf*#(JuCJKH^qa2 z;b#O|!`}KHlaAGC>|^AYLf|jcS*=?c4-i_}U>*LI6qo80PLUB+m92^0oHr4vZZU3{ za-!`6!O-n(6)lPhJbuk5cJXP0M&y05QmX*cnc+wxFnP<8AUl33<;-I^00B^#f)P3u z-_4m+j8NaB7VNgSfZwmTD2!k#F2~wKeiK)D#?{Ygi)&V***D5uY(g|IYiUVfO=+hb zP~(A~w;f23SP4q!Hn(xC%zRA57t%V-rSAycjj;+oWG#3(J+@J*+r9XxcW{YFB-FH( zuiH+P5V_aWA8+WV(@jVF26@As(YUq9u45p7;06l6V9R&7TQ!=E(*HKTqBib{f=h^{ zbY{7S)#=9njZyW%aKbe7`@Ll+loO4_G-rI^kqO_~2xkOGs`;LqjP_Cs3FD<@X-O9q zmRZJ`xaX4u8iF^d-98+StD7Nf2jU9~&Gyl&mKyG|D~|Q6FP~wd1BHS&T+P6%L;!VW zU~>D&N8lohycqeI_1%xFHue-th%A05D0hgS9`XG!&0cPV}PM~dssoU1%S-&JY*RDA}Pl15bCY)+OZK{pANdH?n;Q+@C zXf)h!7%^+ABcXtB^;@2X#J??O;?oC@urjt{mBZz1XJYN*N5@4aaX=<_gr!cG6f}Ac zd$g%cB4`xkniOfjiL~KZ4~ijb6LH5R4?hjNS87rn>=*H|0Tt`DC6$q%*;<3}Pf1qU zv7S@hNVew*)fb&J;RpJZ-s#w&2QQmlvVL(Aw5l)1J?qi6G_wC*7x-#zBew!!m9U4V zHXf4jhXNR4o&n9ftSz{GO=mjME}l>NW#NQEhacJDFDs>KR{fz=qKjZiT+sFEvt~aN z#vluQbdYi56?tA?&LiI!PW;JQ*R-*{&{=WY3ELDT0|VeYXGP#3s&7J-{>Fn!tXO1` zy2$c&Oc&FYPQhhN|K;Uq^IG0B?M?%bk70#Q+Y<|2)S_D8iK+*NP3XwH4Ao<8OcJBW zbn4W~$G&n*T@~A^_s3Z7-t!$C#J`QKJNzcbW^3k&W~zY%e}>GA?u2%e`rH$+3v*ue zzeZMqCfzNl^7FR2y%r4#y3%Qb7crEmOmdrwsUuK{_K=@)PIk(3&}q4D$a2xO@`ZTl zlAVqTL-WGkt7t+m2z760b_GAWGh)Zsxc9B%g)_H<3mLb8d1&jQkx$+gcpemu`;1vt z4=Y1n{A^_i?Qc$W+=CA?5TJyrVh~{=s89b zeY#DEvNpKf3MngZxI~4{;4S%yldK9A(rQDdwuu@BymVeBn{`e$H1yVq786I=9)0df z;GhsY+72G#iFkgq|T53x%>;${!Zz~>^fSI)R0>H1Z}iGlKJ8ClI@c1=CI>Ls$41>}CVNrl2A0QNpLH?B zJ?LT<7wx<=8WqW{x6=WN@C_7$o|pJGBoVw7jT~%c<@u?15y4RZ3DuR6U*Htc`>hU$=RF+{t-+PN?nFbrYi@OzdXU(6Hy4F;^>6} zy*??c8auS{qz{yv_X-!f5f>sCiUrAq+MA?mUXIAe72#{G-c|xSTgD4FLoLeI$7(CQ zP9o3x+8lT7Vu?d&{mOD>Xx9Dt)wS|p@%NZ}z0{&ukne-tG6P@`Oqw6EaeE$XhPO5Q zcxGK{**#yCRyQQLei+l!eS>+_#T|FC9XPV^`l)p@joVT$Wz*V>&O`{U$F4!hOMO~_ z%s>{?ODj~V%m8>OEDh2cHg~^s<5K7U$#-Prs|XPaxsOrwIX4UE<|Yb#Go_Q9|IEt* zVI1R_PU&!4M6tb)$t3ph8}#!=D42bJ_a5*)v%@`>hnN+<%_g1Zy}UW7rK+4a?D2}D zn{A-|Bf2bjGq6>mWd&7*u;FF5z>PR#CR`-G%_NCUYVoXiVvsX_HvbK&`Sbtchh1&o zvg#d3V{>oQiVVuZH1GxA)u-s#!#=qol$33q0aZl?C|M&#^5koSBpb}xL*z|7Z| zx>EXV1Qza5y-TEN-l}H}w%~H*6s@5i_IE_mTTKqahtM} z0mP~C1ZRw41ynj6^5X~w;LdgknhnN4-wp~OqMQSUF!wk~PrKeU`7iaXAN(-`0xj6b zM@JC0p$X3l5GxC~G5!LJe%0GE>Rh}P;fZyzo=W&Tes+z@tj*E$M>q;D^XLt(|24UM z7&G4yXWbFU2d6Yxv>ZB7B2GVhM_Dho28meeVpnp^#v#}z+b^S>amk%*WR5e7Szg>B ztg9J-p2z(I*5bL5@P&nI@&wuw0ZM$Tn@X>}w18^Sk8s{|uwE^;;~h@3F3z9VE?jmk zYXT(Lw{g#!+YZ}Bc9vf2^|df%GB(3(Pli}Pxo7b2|3LfzFt}IW6c(*g^*GI{-kXAA(j2pp^B=)ZsU_rY4p1OdX<=;FX0Voau0$6{fdB zn-ouea)jL}zKS@IRZIXY0PBX5hA^&jCbRi-UpF_BVKTcFO|D&naho-E^TyXtw5;_2 zBF%KIIM;NUhpo3DB0Y#zb+Rtls!76e2PBb?p7ELSMsryIF>Z5rdphNh9ALSf5FY$@ zJ7RvF&D#As@NhoZp6;}30!N>uDu~-ta~N;5JO>F=So668MgNu=@JacvXh8tIv5vJ z@C;C#XNnb6{D@Msm2{Au1=?X$;1(zF@Px|W@8-Boz)k@O?Hna$p3DE*zY?T1&a=+dZsO{#8IBJE; zz0y1%-+K~KZR~F^V%O(>!F;9lQtAh38eg2tX(=A?M5xgLz}F@Fnf*y9XJ8AaWCAed zzypHFb);;i3o@N7=JsufNP&rZAA)}uQyd2sXhN1_=3v&x$B7^@z4$0)A~YO&X?grw9;kFapTTY%f(X_Qc;~7re2L_t|jjK2+9WK5IFG|7x4wzkSi1LAk~U z@1%bmEES9^f%qKOXTB6jUgs=Nh}Wtuo6x-&tdmwKHwj1k?{p--diTAx)E?T85|vmK znevRlN%I&PenEE27&oGktPi~PDAmtU+b^G?7KEOmwyJjkul}$}g6fwL^q2jG9kVmf zm7`}4Gq7VM%6w{T?F$8|Q~PazMD-Qk&#Yj$4+?iK9YL;KRuI3^+t^DN@FnHF=fXA< z-`?CKdbD8Y2ymL83|#8n{;w~hisS*$C%kmH%-b@es88&kmw`St>ngN&*Q z76_ILkVM}Nfn~35`m7;*X2P9r--Ri~xL)LVsn-XCu|yx0CN>w@rKM7)CozNLmHh*9 z&SeeWUV0*@LsT2Cf`XaVb$rkIN0<4@LOVXn7o=@T#zDQP;_iTFz+!p84h4iu<&4B} zY$0u`?#vS7&&tr_Fmo=*TEUu&;wgmPE4u73{i%}sVdecFYstJus{dMNsNM`xp137I zncj77G$crS+!>X?eKf@o+f?C*jkdl&VG*Y6$jp*yU>ubVZ^IjR|G`n{V9WmvH`HIs zzJ>QTKH(IEa?CniFRqb$S(eKV4CT&|et>Zd>HOeE^B^4Sf;@pI3{v)B)4PqhW%8U0 zEO=W*XDm&KpP=vW-iKr!CYogT)%c8c=U4p5far`Jeb7vJkwh78`^v=AJd2$V(Km$T zrV_Uq57}q&puj{X01OKKyPB!76w(Z^QuBd}wLA~jj^{Zt2^_j41UWnydB>zjJBUrg zpT}i#7GCk3YPvf^$z!$Ys|HPEGx+=$lgDRd4R5Pv(2To40y9JbxainrwlOFXDciQpP?21y;w&&V|{09 zuVt{py~^As6=_&?AEM76<}%)RvIc7XkZkSYTwV>{Q*~g@nVj}X^<>++k{uqgY}FL6 zYDlD)f!+vO#h0(si2slXLgcAEc=@{OOst4j8sP%(Y_-`jPu+d}wIMNo2Wx<5}2S;L^oh5zDlHe{H9E z`=wvLfw7Dy6KA%8FjiJPG9yUFYF}`(5o8)F%uK2Z_C7iR!l&1GDrbq?^!yT2idLcx z4_MTBG0=dcRk zpsOhyeGgNUtUn%)H4<;U0kL1DBMRk4ZT&^>L4`tK+3h0i>WvBDxWHQi7xB5Ht75HP zv$rua2uj~1MlV?MrA8m5k4%|DlI7U$HJLixgy`7o#RCe}ELxRA!OHe)ywXUkDXamF z2xz>>aWvq?=I$x1L*NLEJF9@=QS`QcdudhRyd$-J0v&z_i{pi9+L4D52*TmhV9GB? zkC#inJ+T5kb;9t%`wU|*Rf5;Tr$%o?m|j3;!ZR+m@=u{qrvCPrE^`>{EKFMa)2*n! zvQkmj%dCr+tuH)DYyCcPN7`a>t)wvlY1~-HZrPqQXw|v4bs@{PtkGbH@Jpnm5~Z6S zWK2w|Q6@C{J|v4XH_Q>IF2t**;SmP96YXlR&8wX{boHzF9F>S0$qBj(qd9M;P1hZ_ z{99|8fC*P68Bpt8N~~UuZrTNlM~(i~dJyAG^bjAwwaUyL1dPXTJC+5uMU6Oe;W`4w zA+2}9{?rnas$w|$vf6+T(F;W7l9wk^{RiVPytL;sZ0xq#JVkD3#_F|b5w2SEoLbe=MvDvjRV}vme9GNv! zaz%jQa>f$|C{~M(@)yKZuTIFROZr-wc71p`yKObkrO=%k+oAp-zo3H?vwVd?Afhhh zX4FstR{cAuvU^2|=~GE-GjS3!jhxCMCAP`?{>3^q*zsY{T_qdoHMOSw%A9f#h3$x0 zrfE^f3W)!(JRbXq9x>}N^SBK(&HTou52gf8MsCFaZA;QBNVQsvw}iFuw*`}R#Otc!sZ5B0cfKPFUkDn9A8(bA6&0l0I$ zxKoTEevt3mcP3s%<)*QA{I3_*c_bDGYj-EMV6D9xe%B8r3-Kk)h&xWQYD0jWni@>m zi<^aC@3EbdnG33vmnf}ID@+ z+0L%q&)b{$AF6fAZD6$sM_mMLk|UTBJ2CMdyS4{=7N{7*#Ee4voV9DV$A(-goYr{L z<=cJ51m!aPNjUi>L7OF)BDpwU=ee6qfS!#&1$n3DamMr7V;-mWBLB`eYlt6!$r7#@ zKFI(q=y9w`GOv*cSxdvR!?DcDCVG#L?Q$F z7l~!p(wFy>m`DT7;>T*4ZrouAytebr!Q+dwTbB#&0xYowi%c|~aKQ2U+Y?EB(~ZtA z>=g>D9p1zJCyln3$l1xT8+Ws~Uf4)sstgiqFh$G3ttyEv-A}s8DfgQYFB!hN@v<&p zM42bJ76JoS8aUVJ^DeI!B#$anO%!(&IOfP7Y~3`?c}TV8yAy!{HjUVFyAoX$v#lCC z>BcK3M8&i0xyY?rCJJ^Q|wZ1HF7!#;fkO}YwDi>u+bdBJ3F!Zr`w zhA40lj|4UDw;C(iJ%_$e9dDoqN73-spq)0E_ujW@Y2~hO6z_BS?M~fZf7@|gwv^9| zwk%Z2M&0k?2olEo^LeBR=Er-my`=MZ z?o5lQF$yps%0FeFMqX_C;S9e<$}*1>#d!2a0s9LgYw6CQ&|q)JF$11Do)RD{J*%m zEdrUxV6aEpE{uHGlXqj0zzu8ubq+S@+ophAsjFo>t|2n*VzK%U&mLt>Gb}ePbjJ6Q zLU$McQzu!I!CFy64OG8`Cs1)0AfqMj_(Z`aTfA4#a+TalF88?I>-aw-;5d z0%$?wq;^8_!S}9*HjY(bT^2LW=4Yw8@GF& zxlOJiww8=W=jHu_L}9QN{mM}B;|NVY<7$?3AZon^%k8%$I7xL@D{;%TqP5RX>9Vni zKls)t2F~i>`jpGs!5PapnQqV8tmgJP=W35@Gko0&ByA&3O-=BRR^>l#!EC#=vP|9} zJ0pivupBfFVr#+K-XBl4}mq^EC*$esx%}SVcqe>{<;~4SpcYZ3E zkrO#>1A>X!ewUs#>bWv>`A~nHLSDMT{&iJI-w7U`n?_h#gj3zDVNz8wbHNYZ19j=aXKe38#;SR zjT=78p3|0y=!;WOh86M@uLDPhi!C45G#jC}Z1hT|&uGV0_Oy#W(j~*WN|5zr$z-iG z52xwlNY~=aS%3w}{_nx4rYa;K>2ddPyE}3f-_clExF`Y4r8{ zfQx^d>?zIfnucm~T>f>F)3k3(r7X^sAt5mkSBAPJZ8N6gGgVxavUhXVL!y@t9iQB^ z;*lp<8YHWDt)5mMUp-~om8)q4za_DtMDmV+}=X*eDsJ1wG=qURTN zgXD+_GZ98)^pzgxyqi9Qt|$!4FWxo#2x9 zwih``9+y}%UpTNynr?RDvK)0YxhgCNVKO%DrX>6slnpu8Ifv-vz^aVzec4x@RCUs+GC8!yQ$*VU$E! zul+ve<7MMAtW>?Mja*(X#-lnC?Y1#j*4Bl6EDbU{1_p)y7VAhcH5pZl0ko=v#r*1h z1~*oyE|0b5tTV#us;l4K_4efPa`gu@Ot?9zG8JceB~gtb4KA*Vh-mM@>>0>JpVFA; zn%^HJw7A7YZqG+qaS;yd**x2?^jN13COMmgWdT(3-ykvj2aQ{wqU&6CRzc$)T#8iy zTct*68p>s3s914>Ctk#~W8W`80@t_`B$Cm)FHg8)^MMm1++)?i$)9?1a^BbHSBbh` zu1DF`!MNvFUAIgX{I;JH49Zphx}odWIMIzp)v+fe7@gA0-{1X#@AWh0Zsu@)e=0th zxUfD(D-G}#n@!oC*`a1*lTYjFBQhIN?S}d_aD`qAUY!WHxkrcr+R}s+!8Rhn#-xEptz+mkIi`77HkroF*`3kXtM={ zaJOJxt*>V!kJZxWgotUhYSAw=!!1`)d*{O zH5V!}g_>0ctryoMTm6K;%{*>0cIY*^MmQMc3nf(M_%syDUM0RBb+h_%MNi^WNZih| z;BKQAaCN(M)Y4VmS z@WN5bbcSm0BWdXbBk5R#*PfGPdXHor33wxC9bp|Yi=Jj6M`>($n;r&TIFNkLXW_Qh zgv&nR^Vz5nNt=(kf}f)=;rFEMPVzCD4J%Z&Q6)6?G11o2(iQq%&$8u0`ya1yb>Iii z%9}1F<)lQJH!vaQ-B_ySnz2B;S0RyA4Y$S?P0o)_ko ze~VYU#bs1GVMe(B$e!9x;GbZUKwaPe1nO`bV!b=Bnfc{x2eTEqn1oOe zqKN5FV(xh!oJ)SXtY012K2Il|sOwj&6OFq(A+GP7$3)IH@$^%jJFseZ-6Hv_dK#XR z`?l*#eTQ<%U39%V~;WiD^i z59shAvf^y%?d$WJ?__>Lba+b-BIXvpZj+26wLhFDEWrhKFLd;G z1}9>4BoK&z{2+1(wkWV`OSS-h0wl6>0JgWtM;Ooop*pDijCEfCth5IbpU$pYcTY2I z@JH<#?L3G{5IYgJRsUF84a;q=XIm1#VvFfNqabeIInShQMH?LN3uh8sI_E2TX>En5U-fTS(^8tqEsjesTiT=CaOMb`<{8!E7+&<9aZ%wwVI?BV(N&5gwzJX)+gvpPOOd^XOojT8QW#bMN-veTGbJOn>)2*hA9uWDS25IO|^oEt8ac67_S#BMN z+1&uxa_KL@$(UpmcFe17-Px?`&NyTxP*qNMDkG+K>!>bNv?iM5E|V|FWV(Z7M|!z- zR)Eh8#gENcsQRG!<+jttVKrmbr-EyPoTm#)4~OD0^%^YY*pfDxU{KpJd~=OE50?uG z{{l#Qo!@UK*FlJ4w>PLqlspEMLzk;qE6b>6ag9?CB@Vqc>O5+N+Wfeq_k4%_wrkh% zCaAGVeb9jx+UILVy}nfR0nR7*uK?xrdL{aO(5d6&`6MkY)d91&QWd9fOSw1tyoua` z*7jS+>|g*kEY{ClXHcGR2VpoK5Ha?x8}0=h#h3~fqnzn>JbKFpj zH4#y2Jy4&L!Vezf*}&^TZW*zMCeULg_gGc!12)|6O?7&7SQ}X8?otzbP%d%fXpkPI z+(Z@#H9R8LZ|tuTNGtDXUvT~my9-wFUa!z@-R#lauRySp@*8~3Pzh3?hh-*13?mJV zF4M*xqh4F03E}lPrT{>*^~+1eikKLAwGJy;ybIEc=d!(<(PdD#eMsMFgnVC8yBRvN z$Mk;Q%~7S)@^Q$)E^*>zuOfO+4Rug=Q(4t#>hSB!s7r+0R2ANkd;zc|s(ABSzT8gvCNSbwSalmg^pUTywAND(r87o7k9 zl%W85fO7HOWt*+y>qsorih|F!Fd~UkM@{T4#*zrC zX$3YzZ^yKTC%-!gv?%xhN4P1Hu;CouoMp$z=g0sghUKUl6xPfDfi;=qM_4&b(gMo% z=$+-w&CM<60Y%y{I~Fl8J6QXZt|0}8oNx)cS?qV7ryK$=`yL);UZg66FsSuCKh)ZV zWAvhFNnZ8fdM=EilmwI&s0=x?g-;;U%q%m{0`TYopoYUjPCiF!0@mDDe1uY9BdAv{ zhw2{0u0U%Exq9FmQl65mEdI`PlwTlc6o8V1wMcs{KJ>oIYIG;;t5LOcXTrZnyA5@1 zf^psHPnWiF_BxMK3P;1TuY4P33btx@W+-+Wmpk7q&Uo}(h?EWsiHMTe%x<)^$dTBl z)A$Be*MI;>AwXH-rf3yYPBbk80zb_gj*4!%ub)O(*^EN`bUI1y;>lVM!ct4G3WnJv z@t?2(aQ>ehVc}3V5dfdL!em^I$qiWaHA59n=L{h-UwG+Ff-Uj1Y?o;~O;z6cBB)m? z6N1KTcNP?d?O%^XmR;Sv{)*Q7Ki{dge@fC61yL9qc?F%6p{vyX8HC0}{ynB!;PZ41 zH;z(h`twIwT*<{SG;H3HxHsC{b1ZHg<#v$~@&}F@QGpEKdFrv4Y9=V{wz9r=O#q?9 z^FKdMI!8TrqveC5PY*S4f85qc+C}rl(W8GCsYifEceCAgG*$~kXWtmqgHH9<&i~n- zA^RfqwevJFETCJjEkPMil+5No!iKjwNqPXH76Z3Eay>grFT}h(2t$MXl2i9wRA<~j z_1drm(=M3!F>I1O4>D6T{OH|Bc|ggli;6owy8L8*MYm60&u$L(oDb>OKJzRiki6ye z9#XuLDo2uQbqiw~vM5p=6sOnec99(@V6}A&l)VI!p?oBvY}d$)Ni1yT8-T7lzE;Mu zdHrvr+t_p(Lc8lYz$Pk>c2FZ}lheH1X$s{`SOW5>=uTG%1~c#2?I%(W`Zp;Dyk3Ls zFW761_u!k`t)iHk3xp37;_;yXISLzcqch)~f;yHh6=QA&)B=a^`7LR1RSC%I{bEAU zUDYScB1l~iL2}2$l*ji1z`CP3hNVvV&c8k{R26>AaX%jF^bEXd8bVj2WzwM1v z6HR;4X-kn6b{)}IY^x(cdHh&WY#Mavn3iQ{hfwA5c3~JY%*j) zgNcid0@$rBtTV=xq1lYQ-{vfxZ8fr+PL|T;A9s6(39=F>4q7$G1Qn#`jZ)5}^%$+g zrLuYKRG{)EnCNBDOwh}+9qu=RZyNYmpZ(d6(d5;$W;Q+gcOq)v6}Me0#lN$Z#cg_w znkXw`P-mr`GU{FQJ2qvDN={}3_-#OaeYR_L*v2%j2hgkq;22Y>6vE68+N3wl3GM1ecNCVtL(t;XpYG%C{o{ylR<%EWJ z_rSf6XBRR2x>yp4Qo%fXyn~Mp{!}gzS-Diq8Zkf7R_C_>FN|_FuY_8d!%9zr)9NW$;F#U* z9#$ZwTwnSA%)>`Hw{=_?gARZF@O1U}ztkaiTtSDogbIDFsWm9=uo#GZ|h)n603hwMJttNDfV=Vx_HPu5}=jwBNY3o-i6xsKKRWcP!^Us zxE=`buN5YV1lmR+4#N`4;B*W17;md+a=EFONw_Bb>%XDG)k=U+W zEm}26UpHRk)V!s&!z*(X*IjV+;w5Q>sM?@$SWz{#F~h;1Hy%%`(w((o=v{bH!y8Jl z!qzIP?s?XEP^HHSf-z#pvD%ErPhIGz@+lrtmo|25GQ`)f72Xi9^bptQ>R5}Og};&t z5o$f&{*oE;Bu@VUw2_hYhf6o%w7^;NffM)8&xw6m+~j!0%J9O1Qxt;8FGj9E!GdOD z$E)rf=zg`m9^c8sUO;Sc+^eZE(vKza&@JD;?w@;Zoum4EuR0T-^ScZ=T3du}M-~`f zIbP!vyGQM(>g(yzGJSqtF4M;q%$AB%XkQC(!_}XHF$K;t3LChbv*cX0oLwZmkhKhb z$cZgJg>Z~V>|hGN*_q!svMMsKz}lJK4OpNb9DK&aJGYj3ycvWxr#>7glL)}w68hD1 zkT;lf|IOIF+J9t2C-eC?G@hb0*q!~1*f!fQ%-TN{P}OzFo?L5!3smNr+Axx49%{@8Tb4M!F*YUR;!xxs8R+*{Uu-19ta-r^3xG+BpFPus!rM!T5S3t%m)! zx-GByF_(kn!!kdf@L>r=b<-U+i4Mwrr+M2FiNuamJs&WS=(B&j#9o3xOfv+Py6LfY zU&!kN|8PHdYiJu821D755}wI-?N$$8%fr&9bxZ1ZyU|5PaSpR7)1Fp_g-oH@-1~14 z6t$^&BgC%eNDwwHN_cS;MB5YY>-7e7WO4?&L0HnvkIduMDPqM3*P6N>|08fzf@ay` zfi?5v3_vEGkMphb{Bc{8IyVgkt+Lv zzjh=(E2{YFbdX$Rf?Z1lUp1C+M{yF*kLC?GZ2--1-#oxaOft@Ep4;1hvWzmv)e6+* zqD*4gvhKd6%+EigTJY_w(&S7@F z3La?1ao^i0oO`%1c0yiL-C3R~HVBPh=_NR0ryQP!r>aihHy#X7C3O{W^iT2nJhhW` zkV=bQnhT<9KeDiyTHtj~VU|hU?9DA_bAc0>EhHQm&0Q55XYRd3v%P%EJ|+BL?J4e( z=&kVRbn1XUsO}Vx!nH|F4*t;s>N)7$4V)}{+!XvQ zY+%c{$mmSRi+;}*NBt7&B|1qNag&B5aZ}@iERUrgqd}yiPp&p0LCokJOr*&JXJ|N#wF?7}~;s+AUvQ`4rUi_B;hU#1Ds4_FuR9z7n41IW=b%DZcWl1EV&P?!?nrETF^iR~mn3@8gG` z6@@Q9eY&f@KjgqWpz~qL$k}lzj_=t`D<|7pSC+I_l;GvQtU6rUD#$Nn{q({ua-)n? z5g8+bRN5fk`L945W<063!gf&d)uyc4%%qyN3fvmNMu?-Z!~YUF{C%-*=%`4dge}fk zC?r-=4vw2ZGNlVKMB&Kyudr-X3QK;Q8^f1ARV~&Hn__#wf85rg}kgP*rEt zti^}Ose&s%)b|6-{p(Ol4{`6IOs#<`{2mB2JRk0N`bWDd&o>E+L<+GTK79CaNZETQ zj&FQaW6jKWtF3Ov)yR74W%$hX>YUrB=55yQUb=`8J5kyne9$jr@z~8s`+&2x(Yk(SC13vi{D-hT=i*}d!M;iqJ`X9@ z6n{dU*NTi@{kn?I+IkVc-xNhVaST=}bEK%woJ5Q>u?62?zV(xC^Xq-d3DN8Jo@V@7 zU&LYQV@-`~r0RYJHkl8Fu8Ln^E|tiAs&M+!utW69oL{>Y8yCBgil$v-)s5gS|B0fw@&=+QkE+55t$1ZMaTlX*=YDd{h&^I$KOoF1K&TfyNl0 z?z<-!u$+FcxM$&8ch0>OS834ZG}k|7F>g!{D~ja+C;&{12{Bt&2s%d;;5PFX7Y8an zJSo3Ep+lSl_(q{HCr@}iTZqP3RRDh4aJj1C1?~-xNu=>~TwR9XBiI^b$A@N;@t?ar>WY|`YpzZyeoZWqOxinyUbfHeLqCXfnXmBRPK6Gh zj*RNi;L00>n}7iT%AlcI;#mpLYrhpB8)ypc~RDe<^do>vR3e`{4| z(cf!$)PLoPAUS+P-IoWe$hKHq#pm&qqCwKf#bqf55H^tAn!biEUsRSqMb#Qq@gg%L zK@A%0_=}_EV*F-ix3TEcAf#-VFC3F8tCl+$9bMJ&shrsIp$`44Ve5PF;q&o2YIZuL78Pt_jj6QRbIJ)c;JQ; zgh3fVeUM?2gfMiejN@q=!R6%SG-SZ~9eQIrmY2o*6wi(I@f$G!jpKj51dV?=28zC7QpJ#9Gh$Wp={u3k(6V^G82O8rvw)OgI?HH9~mgr!m7h@oT ze~cK|E8Bw)`m0U0#Z6Ryj-iA*$<7~U78m&x|B)3eii$$BUYPj1gSedD7*Ibw;$Kf5 zcp%oY;!P8XWas`tp=R%$zq(!oHeXjBz;+tFUon zU7&Lf)KV`b+&)xUeHtkFtLG<;b8f$ac0!j*o5MQ7LPm}dkM_7t&XJCU`!%~i?i*Cp zpZi59klV2RZg`uAbiNK{)e*N&&t7Ynr4;iMnK@58q5qVQ9#(loQg4si1}FxN z)J;yN{`+-<95rk*$f~rPETQ@P-56C(k-elS-22GCQy+wl`90VNRfr9QO&F{YvPdCs zuaX(vGYZ1Y{X{0cEsd?{B(u%eMvyDbyPh1!BKLi^pbgX0>ggQ?X$3}CG7lc>1q<|<_7q!2KL>T!-(E_?4fc1F*n6$9T=LT zBeH_f-}|TDtKVaox6{1B8;k1oTl-}fsnSKe3LG0)-vsLw5Xi9!kr_k$x8N4y0_S~` zz|uBE$piNk*35h){QrPuC^dWvgQp~YUlbxM2W>y+w(%2LHYStMle1h{kdrt%wJ|Kf zf4Je}>R%@#Aof1e1f;FZ6^XMyLDBHh4DJF)CbNp^;STDDRPaVP8<%YL7_&mpwRTxx z03ebkXl;5De5H};KI?^oka=vcMIKZ^ckkMxu-{Z6z<`vE(Y4XI~mq9`o(4zk%b&@-Q~XTcdzk*oqe-!Pi| zexK*PQo@mJSBa~8qh|Q)w>EA(kI;seaQcGLRf(?d*t_gU81g9O0e$q{pN&*JdzWDaUi$rKBfSesKF>tVwS$MhGm~uDEbWweGROv$J@}eY*ZiuTK^~_O=^1xv&^% zumzGRmxir&(O>|<~x{xZW^Bx=@nMq_b|_R}9c{JPeuMebF#`Zsn@>U$Wd3wcE_C*j z9(yxe4@aS=P*~$ag3)S0NWC+C(BLE4VZJ*R%ySPC#fQUNVuh0|-a|rw09S-O$v+l{ zu+>y22WEmzmh6GF(v<~R%?C?Hm+yDR>Nn~NH?~|1Z+1|lha0*lZgEy$B;gioEXJS* z(0&WRF}ZI8+EBU9@1HZq8j8cQO^qvSonJQq?{KYYaUyoX=)&+fA8e41bL}%mH@B39 z=8GDy!E8nV#Y%CY_{Wcl?d##6kL2eeBtKP3o3Y+MA&Hr&^{}1V>5r>@=D1)`VnAmc z=-k!uK6^F`Pkn1T>Dh_BGD$B++4 zkT4a0hGMyB)m)!69xN=S2NbUyc2B4-ftCU3bqg*SFgg9=OX4mf6Y82{qA;5wFh_HW zI^!nl^=l^;wSmEFTDjT~sX;OhTBg%?Gr8&DWl`0l;Lh-$y7i!!L%@`~taD~3COQgh z*=#haCvO*_4WiDF*qyKAuWrrDt#YP zMt+}|tqi4PjYnjsGNgO@ZAhk}R?M)1je2}jo%hdfz~R_x zJ@3_7*5lEuJnC6DAE&r#ip>x5lrD35D!dfMjs`;#21AnMn#0aaew#Gr_&4rfJFlY= zoq4m)%5)R4Mb$_+# zbD=O~o)=O*8fn0l$jsC>H*#X+n}yd>JnCh-7M84x+GKig;AS>LFN-2rNS5>?1Emuk zZGQnu9mXgCjdAP8e7vgZsCO+;uM{^f)3qgq{$+E`B!5MpoLz+7cH5B)xu zUPtFy;V;*P?S-O8+rKvhYIq5xL{GqfIjgP%cq%~B7q)^@{sc9(IM0dW3g58q-;Im^ ziLe0RO2}9CS-V>G?dt=OfLY5nc<-&Uo`YG<543^MpzXs*g`&^&N0+Hu>DcmWr}2Mb z23u*4qXRZTlQ+*qU)t3#u%e4BF>Xq|S|IjL^Y2PTQ}#IqwBhMsp$jS%mG8&opcoez z@lh3Tx!dS`AayXAFmT=??u0e6MJzssw(u>a)CRJitG{V>b4#(&%Ouk z>jh|EL%gnl;m)4_y4*c1)5k`Qb6|IUmGJI}8@%6_#Q>A+f_AOBjtvZMQ$bGI zBt;c~HX0v}o`2NgX$>S2VJ$dtAUNV8pwRN`a{kfGuYg5^W#S=eAPbVkB0pt6gx>u0 z$n-Y>G^}~~mGF%5Q&_yat`opgmJ$-q!J12t9vTGMkN&@aSXOEFq^bD*6q} zTvwrSnLmQYb$I5n*65;^n0T%>WLkeu_EsZ5{4Hoj#*S8`xK$unX!kVq0EvTMn1zLli)eubB>54sN53}=YqAwa z>|X#2=lhy9bV0Y7jVgX2v|k&dgGoMwW`0X6O6(F{$X1yxwrPU=rLFCTIPfatLH|S$ zlN^l#jAQJ@moG(P?!I1r@+NW!mDrci$_Dc%dYphoL_==^-!WjwYV-a+|MaAh3nS$+ zq~7R`Tv8aU?k}B_DjwR50pNVx5RU={QO69SN%TRJfWbnF@3Ol-ZCQMrrj*1JG%^F9?9R>^Hw6HB(-J1jszb!Oop8v*N6m2=<=kMmW zj^RJrJcj=^KwNOWi@ujhA$!$p5*khsxYrCCPN@rF9iyLOmXz{f{zw!WAw>t|(#yl# zp+IkoTetb!V`w~kzv+{(5ugYlIKo;iULRVGBF_IFRQze~CMSDyK?rmNN8*1U3beK(TX>MA|V^8o|^z+g_VfTUM> zcW5(0sijtCXbKQm34O*Rc&sNGxHayTiZ;-ZyM_Kw7*9*<*uiln7(t1Yr-o4r=@VwEeO$hnw zHF889TUBGTc8~&g+#goGezHCGg;!Z1>C(wB9*KvMXc)5QDOKJH7}l7t)!ZipgD7XqzWh`?~rLHS4hWS3zfQZL;P+}aSrj7 zYKM+pr^d7lJimNm{$ulKS+{(P(YfhO*k}@g<{~mOZQXu$p?&Bol%c5kc0ZsHNH*a7{B3ao=-}xA&Pv6 zEd@~{Rbd}K5CcH+U=mRjvZr8SbnxLK)HoO!QX8mX-p0Vl;T@8<-dSZel^UZJpw(a<7i=?N81L`1zLI80zd5Cf$$B!JYC#XdT&*B?w|fud74{bmQATD9d{ z+E6sl*Q`j=E@{Yqv__=K^u|k%WuULNUMN}~h7Km~8>S3~t$ncPR=_UYC@1oj$KDFG zoSIB%_7$vaTz!h7tAAddl``m0C7avb71M93Bc$nSir_lXhtSgWJE`Up)+MlnNh#dG zlt|RF-pI#^vnTE8=6N`g!(Jtj(jflgjf7_9&x;RnXp?e5%D#Sh>FS`$he5hwsE5Oh@JSnMC!Ad7X1Fo_LzqH# z#sQ(mnL;F>7xhmZFbyT|JB4_#dj9B-M~`ax+?;yu+QjR3e@K%x=LyU*wIH;)zTMRn zFrrT3unWdEhASZ)7+25cpL&G<$zhk}+oszVgsr>LXOy*1USP(fkf*T`|2g@O*{@%F z4Qiz03$Gyf1tA-;&2?gFx;-J;b5&-yoK$;4kWFX5ej@o?630nQ;*?d_^bXrSjls^g znA^}t{9`ADaH4pRK=OKuE!~Oo*q**D_R%YAU**%u!O7YK*xwsBM#UIe&2=eJUl_7~iJ6{n z5_lf0XFnJcJ(!wnN8!UXLyL?|bc?+T=d_<$PerfCZ1DAp?HDXZM7mn$4e@jr&1zG+ zlLYra*R5OTILFyGQuk=Y?ki@^s6SP=rcj!G89Lo=WYSK)bYHl!xOUy@C-y3ej6YIH z%|flr`Nz_4n=dBC>*KY`U)a<2DM~k;Z!sS7;I)3z4NEPj>9q$a2k3vLlJcVH6(_KP zBW13&fxt?zTQ=-8TOBw{r}*Ytn}4;|p^SL$Z;|8|;f2Iy7r%$J>At8b@Q`WrHh6uZ zJ$rAp2=oo*utSN;M{ir$BM8mre)CUFKKI2xn*_`*ROEctEUT!H9kb3gvye_s_gJ;V zsdrAR3CLrF?C4Q0MWTuRKK$M_u8bdKu!r1UCQK#6s%eF8%)aKuyMDy^^NU&XO=Iz{ zFT=i<`cRwk3={vjNs!V$s}-|;v(`JGY_#x;ZrHQ&{_El?JNn$Jx9uD}+wyIwn+7)U zwWP0$4}W!k>L)8&nr7rQu9mg6eo|;?9ZME6G-vj}df$X(5q7PXB}y7X&NJh$?eL0& zidjWf&E6+h=e3JK-9x0uJ`4F%Ja)Dqq#ny3jDS zDA;h;0@|-1OLqxeOp4&^w381TQ5G0pGO_QvBw;NzfPz}Sk*RGm-k=kQ5 z-R{N+{Wc(}@scO$F!mVbvip}&L@Ro<+FC-l4k2|xRXsX@@)&Aw2gN3+Vk)Owr_)B3 z)GGt$?32aZv$|^!;8n4KZApV`>w|r!lB#ND8Zp`ffIAEPol}E-#rNo-&J`psVl$*0t7&wZ zr9TRF&SiN!9p5ZU!xf?@DqO(bz7WB zSo0f=f1f6gqW@uMpAS*s@u5c4uiKr#;#Zc+%g)8DOW50v3J@3-P_${1h8E>C`ZwV2EOpJO*kYHE>!Q5O~Z9&)kEhcGH4Sy>- zS8(*pve5KD;)7AIR zVV*?|0IyVx@)=tqyQazAxytF(%N*q`~Va}ySx8;w3%tt?E88%)ZYb7nqeQV ziN6>LnD-9uw?soKlA4=CHSr$q`VWX68Tg)F{^|pGLa9pvY>FKA1xKdpL*?$m@16vQ zNJ*c226ENiGq06NwnxYT2e$szvICjs6buOs@m5|->30hJE@lEkq6C-o>6nP=MOp$V zO8pxs?zOCYyZU)?TIu(As$`r>N4IzQ=+g&jX7#@&mu?#zeM9vpsx{d`mHS$>`*%EP zZK`dhXxt?aIM)ohzwP;6fY5OkULfoI<%TqODGW-eEw|%ugvG%KJtJkU)9p3;Yi)!2 zrm9rL1u9Wac!pKV9p5n0~)of4>Oh@=I>G?KyiSK z6eh=5Fk<>~0#Cg4IdiWZXX~=0#)VeH-HJ`|ESL2(^jXvS$Un-$^RB5qi@8}KyLMYV zcv+kUW-zWdFJ2xAz*kxZy=)KMfAJTsyPSu^Cs;cE=h_M8^;D7^UVYC^{OZXcBaGlm zy;xeu)W(3BEu!qxn#RGrI*h+^wC`YaO`kuOa4XzeJEpZF@DcvivUWfS?U@`!qc(w2 z71%Q(f*7W_&etY5vfS;-;h_aTckSp~S(SXad92Y-;BG^jjzIWV1TL5pxZRTMLr$&{ za%DY{WqW;9rfE}dD$LAg0rRG^Yj<%PgHOV0Z`3BV{-o)iJKvJjZ(1UJ|NHG_i#<2n zF+0iPQQ^1n?wD>#m`fmkx367n*^LaoVuYHO&$}7}CFg=HAyYg;Bn2TtprP)qa=kFiNwTRU{ zd$Puv`ZQ{|AD~sBx`22JBnSj>efWUk?;^R->xL?KlOzgE9*u5jTUjOyos?R0r#id1 zzmpkq5o$=wOCaCiuRrnySh%OqYap12vf}3qq|p3h7iGSD%TUBLwPBK^Vb#84Wn}@z z@_y5^8=-+Q_^|gO-!v}cwIaT0?$N@OJ|j?}gIROI6iUZLRil49@~#{@BhiyMEum1e ze0!-34?hl#Q6u?;_k-7o`3YXfzp@LS-JLu*DQ~4sVNu&_gJy5DY({4vmPFALIqd0u z6~;=n*q{xgzi>kI@x9#jyt$*j`pZA2Zr<-~J|~bKpvvcTyS8T0H}r#oK%(|dOGSi| zmg$Q6bVgAu zwW)PfTG}l~d^fDkUNQMd>HKL`PTWIb zYJ*1iSH{Z2i5P(q|M;c^`N8{SNLdhZwCZfGro0`U_X_@Op`+$=-lT#;_=7N1`{4`S z>s$xp3*kYftLv`@HHupeX=%%Pd7(6Lo8@A~sy{7XuXvYQ%`&zod1DpLRA=pNPA%FH z`(;Q-UV>x(7iQsp5MhST25b?6;ve$)A2}~uz7Y>O##uX(T-vU>eDM~yf#CW@FTdhH z;k~^9>s~_rS~piS7j#h_3YY82ewA}jI0271nd4gZ3lX^p*{d>fmVnTL`S)*}l zD)PomnN*WX8`}JVtGaQ)uDa{aSaIBsQ;=By`Fbt8ltgcFSczSpR691O=AGpZM=4=p z>&2$J+l=*Mz8li+#wV>bV`|jPdey6l=lopd>30-3du~U$*kF1++++%^t6>TBY|(?1 z(Gg)ZeEkpQuAevG6r(j{akh2SjlK_t=AU-U4(N*!HHbEJ@0!4#Bb=l=?ON8m5y+9_ zh$Ga&5{)%=*})HvS2!IS0}E}h06+Bga^Rz7;;I~qlqVi`B7IUSf1Tl#xf+;MVb*S1 zIDBZGk@*|8gv*8!7_d6dys=YA+7LDZ$}q!1NZ`ixZ0u?twmBl%Jn!DsQ=aeF&-;;} z8@TZdt&O0is@Kbz<8-4`kje~oUApfSSuMC4%9ylok0@fUAy@2s(qoNIHq{*~_w?+o zDn~7s+Hso~GdwN~+?FHWw>1-QD*i={NIdht$L*-N?@F}zhmOg1S-ec)pYqr9QVmL5 zJ^VEV*Bd7lOms15bIdG*hJ*q?$BQWvHEAtOGnV+&-ON;qrTN?7g3w6H69Yo@I2a>; z7;~j|uFjshcRGxRJiEGuye=J<9r96==5(t{K@3A;rU-aywd%<}Sh z3uw~-gSjz}OqYb^`8xX%V<|JvDc*1})WwJZgp3z$V4lPX?DLM{wrI|1lshK&smT`H{;Fd3u_0T05C<~s)ppXI_plICsMg|ihjm6_gl2t4H zy=ozp>Oqt?9lDX&M^YYn*+@D%cMHq&gw)4TIIp3>I0KS^j=^VLxV8IpQ3(qqE3|K< zb8wIZblG!q?q;lDBn6dJn=h@hYIjn~7rhp@I1kELu2tdcT1LqMw;#9NvY1Y@3!_() zT4nFaK-w7VitC{u2}kMR{iuCyk5`(}0WQd=cfI3si0qAdW$BQD1C7n&9l5|c0KZ=E zkGPYa(WDOH8LHyD$INCjnWZigLwpg)VG%^8N6pZ!xt_#~OOX5^DlFyzh{_)d++kk! ze~{NfRk}0kVzF7nu}iflD=v&`61sYWeD4154Wug~ito@!M!T7o2=z5- z{g-OCDwfTl@r}Y} z0bA|C)S2$Qk4@j0Q^cOVev5?< zj>=SJQwK4MTJR;e@=!y_z>^An7W!w_VXRkMy`N9uHUM*9VND=h9Zy7M)GiERH=rBp zz!wdJx}TAM#nEF3m=H?&kGk^(`Hot{Oq;Kl z@34q8HNdG?dbtI~)?a^6>^d(y#HVb^5y-+sMWs0%SZz9-xVT&m2bqF7kSVxG331;c zd21G+x!g^la47q4JJc+89`S8gkayHMmUj2Yu2mbdSowbRxs6^}-y{M(Cj=1-}NnWLKlm8T@2=`iQF0Qb1}=Ad#49^H3#{X!;Z&}%WV|Fk1%TJPHRr`#CGvJhZ` zVx$_F0VjkfV+*DgRX>fY{{zjL;O!C%>;C>C094qssk2GJvT!nREzKqs1Om}L-asO* zEpH34%m#!ML?U$@EV0YCf0iC;3;l!L-?T<*v~e0Zq!Q{~Y4>uQ|Cp;M#}p{b4# z2Q@aBoGCm^n+{uZX~`BAIe^y+nX;$~TJc$(CzBUm0Gb9!Ep!27wIvs+q1^eqCJ%(C zYcJZicJ)3tL}sEu8u|q6qXZoPad5w~kZJx}UO|S;zKzRAX9ftj>d&=-YxClENZhpf z)S_7X%yb9kwa@bHTlqtXke282JHv%Yl>zcPSW#BpHxLqrbiPx2$ES=oizw{C3bT=K`aoT5YO zLiGzzmA7&OPxhJS2lrDzdhxs{pmDHY_=z&eUu#K+^zEa;IaPqZ&TndPLLSm1O?&Pw)lH1 zNDSq1)_HA&s(^M`iEma5e*<=jl9sJ?LNR#T%`7^2Dr&h&Ud*tzYHs2Jd?QD88-Gz> zrha=j(6Al~8s2{RM)F)psfx7wD^u_qSu9!z_{5dwKoVxdbtAE0cQ^{Bm7P%0AN)_( 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

    REBxjN~vQ6S&qvF18BZDyV+&Is;HRJH^<)+XJa zR0mRs=LzQUmYmhF{Spb4i!4Pm+6IX%%k^-7>85&i3OpjV@6 zhgi4%3MHwd@^yFnmW#9x<>38}tv&W@EY~dkVF!2KaN0o6SX&s!kl0rmd_5tzH1?*B zL#zjRQi}ruHTcW}zFA+8QE2(5-pr70QC1)_F>vWcB6sp(iGEJ~2XvIc8}E{#J~lQ@ z1le||w;p=o`NJn?Qbhh@P2A2#uN7nW`su`(dbvY0F`zbap=Q( z6+A9eXbzkC@_MS>K+bL?(iAV`LZExLrmtPt|2<(SBiZC5v2QvofXPpb!l2XDah{tp z*z+S;)4n|T-)rVIiquL0x?0dN7wH2@ndE0uy3X&gHzEx0V!N{@-Qbc|NhqS55;FC| zT6kYs!pJ9vPLPXqACrtff-!VqZL+p!gBRXg4FJj2+%7sf$q5SXYSJvcyEhcpb>>;+ zt@dya4aAZcEIvp;Th<4RxuuhV^(~8GP%!Mf+GBW2ULDKM1G4N9*~4N}oKO||;g{}VJy>92tR_}K4b4R{B14&L z^GtVEb!|ItwRTo#O(7nIZlo`M|(4eAoy{|Bja(@cr6{TJCu7v6j zp4;toEA*|R_L6&kOBchtPvasV=`g>hx3NW3E_5O{8lp{zj)e#$(bX*<0Y z&f2amrib=_ASemH2Y7hwVrCo^^r8kIam4R(fA!}dUY)R%xcudyb6?r%sK0QRZql8M z-%PBW){A3Y)H?ISvo9r9Xm0)?f||kmQpP)fHGWx%$FQK-e>_NsyD zeJDFHW;1&EN}|!1N&$63vdKs^sgp8SE$E_Mc0k?qdS*wyDbwkd_mxcZ8t>V)Bbwf= ze-9XR*_tqzQu4>DwPC7yW7r#LLf*kq1Rx!EbZuF1@xS{R072>zGURP$6r0QsO z$`;)yeqVN*)%3qZ@Lh+yhq=1_ySwkD(71eG^qewEZmkNc6_&X)?O?us=#lC5KGn1s zA$d#crGD4GJK5@)?n&V%i;l**V#RZA=?^PwnI1d89p)u9W%o3Z{VoD+8cA@@ z7D)XryS}c_cXQHHFGhpO&w}UwO8Iz7yFRkE{@2&*tOtNf4{Qm3%f=Aw3|zbE*z?w^ z=*fv4%VxeaTq&6c+K$71VEw*ddqL~^LPH@-6%2NBHat}7V6f1tdYIJNb^ix&%I+fD zuOA;D9}NwU1#Zj+fz7w8xfq@;dAfhwp1*(N_kEfkDgoO53!G8N1D@e$sTIno4%)o` zNZtOYCnH1xcuYxyWzN<0>$U7YH1dbscmMJG%;obOpnDa73+%-}yU!B^|NT4m|A+L^ zYT&l+SA|@STbse<6ZljQgX6JfH&c(k$`0@6Z0wi2DglffnGb%x+Scv&s#bF~)_>Y=uX(TX zc{+H33xfghynV3ufCY}wdrhz|Ad?HaTmrcC1bPD#NPbih*Z>@g0rKB|!~ZQ|pTw$b PKoRWe>gTe~DWM4f7=J7| literal 0 HcmV?d00001 diff --git a/content/learn/03.programming/06.memory-guide/assets/memory-guide-003.png b/content/learn/03.programming/06.memory-guide/assets/memory-guide-003.png new file mode 100644 index 0000000000000000000000000000000000000000..8e4a7612063332cbbf841bb21b940099caf85cd5 GIT binary patch literal 46590 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 t0*LOW@U0M>K Date: Wed, 6 Apr 2022 15:49:53 +0200 Subject: [PATCH 29/36] final image --- .../learn/03.programming/06.memory-guide/memory-guide.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 284ca3b356..2fd15bd91b 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -20,6 +20,8 @@ Memory blocks are essential parts of modern embedded systems, especially microco As shown in the image below, memory blocks in microcontrollers are usually described as **arrays**. Memory arrays are divided into **cells** that can store data and be accessed using a unique identifier representing its **address** or position relative to the memory array. Information in memory cells is stored using binary digits (bits), usually organized in bytes (8-bits); it can also be retrieved later by the MCU or other components of a microcontroller-based system. +![Memory blocks.](assets/memory-guide-001.png) + Memory in computing systems can be **volatile** or **non-volatile**. Volatile memory is a **temporary memory**, this means that data is stored while the system is running, but it is lost forever when the system is turned off. Non-volatile memory is **permanent memory**; data is not lost even if the system is turned off. ## Memory Architectures 101 @@ -115,11 +117,13 @@ The `text` section contains instructions loaded into the flash memory; `data` se In hybrid ARM architectures, a so called **memory map** is implemented, with a different address map configuration of 32-bit, 36-bit, and 40-bit that depends on the requirement of System On a Chip (SoC) address space with extra DRAM. The Memory Map grants interface with SoC design, while having most system control on a high level coding. Memory access instructions can be used on high level code to manage interrupt modules and built-in peripherals. All of this controlled by **Memory Management Unit (MMU)**. +![Hybrid architectures.](assets/memory-guide-004.png) + The memory resource is handled by the MMU. The main role of the MMU is to enable the processor to run multiple tasks independently in its own virtual memory space; the MMU then uses translation tables to establish a bridge between the virtual and the physical memory addresses. Virtual Address is managed via software with memory instructions, and Physical address is the memory system that is controlled depending on the Translation Table input given by the Virtual Address. An example of how memory is organized in ARM-based microcontrollers, virtually and physically, is shown in the image below: -![Memory organization in ARM-based microcontrollers.]() +![Memory organization in ARM-based microcontrollers.](assets/memory-guide-002.png) The ARM-based microcontroller's memory department is organized into the following sections respectively within the address type mentioned previously: From 98d6c8b63269ac420575915264ea31d7d9ff3d06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20S=C3=B6derby?= <35461661+karlsoderby@users.noreply.github.com> Date: Wed, 6 Apr 2022 17:36:55 +0200 Subject: [PATCH 30/36] Update memory-guide.md --- content/learn/03.programming/06.memory-guide/memory-guide.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index ad1ab9b91d..f07dcaa698 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -238,8 +238,6 @@ Remember that the `heap` section is where variables created during the run time - **`__heap_start`**: the beginning of the `heap` section. - **`__brkval`**: the last memory address pointer used by the `heap`. -**ADD REFERENCE HERE, DOES THIS WORKS FOR ARM ALSO?** - ### EEPROM Memory Measurement EEPROM memory management can be done easily using native libraries already installed into the Arduino IDE. The `EEPROM` library can be used to read, write and erase the EEPROM memory. The following code shows how a byte of information can be stored in the EEPROM memory and then read using the `write` and `read` functions: From b39a0a069854b7bcfd9a725e43a6488b149817ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20S=C3=B6derby?= <35461661+karlsoderby@users.noreply.github.com> Date: Wed, 6 Apr 2022 17:54:04 +0200 Subject: [PATCH 31/36] Update memory-guide.md --- .../06.memory-guide/memory-guide.md | 29 ++++--------------- 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index f07dcaa698..619a7b2c5b 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -36,8 +36,6 @@ The von Neumann architecture, named after the mathematician, physicist, and comp Both are accessed by the CPU using the same communications bus, as shown below. Von Neumann's architecture is fundamental since nearly all digital computers design have been based on this architecture. -**ADD IMAGE HERE** - ### Harvard Architecture The Harvard architecture, named after the Harvard Mark I relay-based computer, was first introduced in the mid-'40s. This architecture's main characteristic is that it uses **two separate memory units**, one for storing program instructions and one for storing program data. Both memory units in the Harvard architecture are accessed by the CPU using different communication buses. @@ -127,21 +125,6 @@ An example of how memory is organized in ARM-based microcontrollers, virtually a ![Memory organization in ARM-based microcontrollers.](assets/memory-guide-002.png) -The ARM-based microcontroller's memory department is organized into the following sections respectively within the address type mentioned previously: - -**Virtual Address** - - - `Kernel Code & Data` - - `Application Code & Data` - -**Physical Address** - -In hybrid ARM architectures, a **memory map** is implemented with different address map configurations of 32-bit, 36-bit, and 40-bit. ARM's memory map grants an interface with the barebones of the microcontroller while having the most control over memory with high-level coding. Memory access instructions can be used on high-level code to manage interrupt modules and built-in peripherals—all of this controlled by the **Memory Management Unit** (MMU). The main role of the MMU is to enable the processor to run multiple tasks independently in its own virtual memory space; the MMU then uses translation tables to establish a bridge between the virtual and the physical memory addresses. Virtual memory is managed via software with memory instructions, and the physical address is the memory system that is controlled depending on the Translation Table input given by the Virtual Address. - -An example of how memory is organized in ARM-based microcontrollers, virtually and physically, is shown in the image below: - -**ADD IMAGE HERE** - The ARM-based microcontroller's memory is organized into the following sections within the address type mentioned previously: - **Virtual address:** @@ -187,12 +170,8 @@ The following table summarizes a specific Arduino® board's memory allocation: Memory usage statistics help comprehend the insight of resource management affected by the designed code structure. Memory load demand is one statistic that will give you an insight into how efficient the code is design|ed. It is a crucial development consideration element because the resources are finite inside a microcontroller-based system; **software should always perform without reaching maximum load capacity to avoid problems or issues**. Memory load could be observed either as **available RAM** at disposal for specific tasks or **flash storage remaining capacity** for required headroom. -Let us talk more about memory usage measurement in Arduino boards. - ### SRAM & DRAM: Quick Differentiation Specification -Memory usage statistics help comprehend the insight of resource management affected by the designed code structure. Memory load demand is one statistic that will give you an insight into how efficient the code is designed. It is a crucial development consideration element because the resources in microcontroller-based systems are constrained and finite. Memory load could be observed either as **available RAM** at disposal for specific tasks or **Flash storage remaining capacity** for required headroom. - ***To avoid run-time problems, microcontroller-based systems should always run without reaching their maximum memory capacity.*** Let us talk more about **memory usage measurement** in Arduino® boards. @@ -289,6 +268,7 @@ Let us talk about some memory usage optimization techniques. Flash memory optimization is the most likely straightforward optimization possible source. Flash memory is where the capacity used by compiled code can be significantly reduced by considering some details. #### Detach Unused Sources + Detaching new sources includes **unused libraries** and **code residues**. Code residues can be composed of no-longer-used functions and floating variables that take up the unnecessary space in memory. This will vastly improve the compiled code size and make a more clear compilation process. @@ -310,6 +290,7 @@ The ideal way to use the Print Line command is to use the `F()` String Wrapper a ```arduino Serial.println(F("Something")); ``` + Wrapping the String `Something` with the `F()` wrapper will **move the Strings to Flash memory only rather than to use SRAM space** also. Using the `F()` wrapper can be observed as offloading such data to Flash memory instead of SRAM. Flash memory is much more spacious than SRAM, so it is better to use Flash memory space than SRAM, which will use `heap` section. This does not mean that memory space will always be available, as Flash memory does have limited space. It is not recommended to clog code with `Serial.print()` or `Serial.println()` instructions, but use them where they most matter inside the code. #### PROGMEM @@ -339,11 +320,11 @@ const char greetMessage[] PROGMEM = {"Something"}; Dynamic memory allocation is usually a suitable method if the RAM size of the system is big enough to get around with; however, for microcontroller-based systems, such as embedded systems, counting every Byte of RAM is not recommended. -Dynamic memory allocations cause **`heap` fragmentation**. With `heap` fragmentation, many areas of RAM affected by it cannot be reused again, leaving dead Bytes that can be taken as an advantage for other tasks. On top of it, when dynamic memory allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the `heap` size. So to avoid `heap` or RAM fragmentation as much as possible, the following rules can be followed: +Dynamic memory allocations cause **heap fragmentation**. With heap fragmentation, many areas of RAM affected by it cannot be reused again, leaving dead Bytes that can be taken as an advantage for other tasks. On top of it, when dynamic memory allocation proceeds to de-allocate to free up the space, it does not necessarily reduce the heap size. So to avoid heap or RAM fragmentation as much as possible, the following rules can be followed: -- **Prioritize using the `stack` rather than the `heap`**: +- **Prioritize using the stack rather than the heap**: - - `Stack` memory is fragmentation-free and can be freed up thoroughly when the function returns. `Heap`, in contrast, may not free up the space even though it was instructed to do so. Using local variables will help to do this and try not to use dynamic memory allocation, composed of different calls: `malloc, calloc, realloc`. + - **Stack** memory is fragmentation-free and can be freed up thoroughly when the function returns. Heap, in contrast, may not free up the space even though it was instructed to do so. Using local variables will help to do this and try not to use dynamic memory allocation, composed of different calls: `malloc, calloc, realloc`. - **Reduced global and static data (if possible)**: From 8c76aae25874a8d95022276cb916f057108a95ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Thu, 7 Apr 2022 10:32:46 -0600 Subject: [PATCH 32/36] Tutorial update based on comments --- .../06.memory-guide/memory-guide.md | 102 +++++++++--------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 619a7b2c5b..ebb04fe005 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -20,8 +20,6 @@ Memory blocks are essential parts of modern embedded systems, especially microco As shown in the image below, memory blocks in microcontrollers are usually described as **arrays**. Memory arrays are divided into **cells** that can store data and be accessed using a unique identifier representing its **address** or position relative to the memory array. Information in memory cells is stored using binary digits (bits), usually organized in bytes (8-bits); it can also be retrieved later by the MCU or other components of a microcontroller-based system. -![Memory blocks.](assets/memory-guide-001.png) - Memory in computing systems can be **volatile** or **non-volatile**. Volatile memory is a **temporary memory**, this means that data is stored while the system is running, but it is lost forever when the system is turned off. Non-volatile memory is **permanent memory**; data is not lost even if the system is turned off. ## Memory Architectures 101 @@ -34,12 +32,16 @@ In the early days of computing, two computer architectures, i.e., the organizati The von Neumann architecture, named after the mathematician, physicist, and computer scientist John von Neumann, was first introduced in the mid-'40s; it is also known as the Princeton architecture. This architecture stores program data and instructions in the same memory unit. +![Von Neumann architecture.](assets/memory-guide-004.png) + Both are accessed by the CPU using the same communications bus, as shown below. Von Neumann's architecture is fundamental since nearly all digital computers design have been based on this architecture. ### Harvard Architecture The Harvard architecture, named after the Harvard Mark I relay-based computer, was first introduced in the mid-'40s. This architecture's main characteristic is that it uses **two separate memory units**, one for storing program instructions and one for storing program data. Both memory units in the Harvard architecture are accessed by the CPU using different communication buses. +![Harvard architecture.](assets/memory-guide-003.png) + ### Modern Architectures: Hybrids Modern computing systems use **hybrid architectures** models that maximize performance using the best of both worlds, the von Neumann and the Harvard models. @@ -103,7 +105,7 @@ In microcontroller-based systems, Erasable Programmable Read-Only Memory, or EEP As stated before, Arduino® boards are mainly based on two families of microcontrollers, AVR® and ARM®; it is important to know that **memory allocation differs in both architectures**. In Harvard-based AVR architecture, memory is organized as shown in the image below: -![Memory using Harvard architecture.](assets/memory-guide-003.png) +![AVR memory map.](assets/memory-guide-001.png) Important to mention about AVR-based Arduino boards is how their SRAM is organized into different sections: @@ -117,8 +119,6 @@ The `text` section contains instructions loaded into the flash memory; `data` se In hybrid ARM architectures, a so called **memory map** is implemented, with a different address map configuration of 32-bit, 36-bit, and 40-bit that depends on the requirement of System On a Chip (SoC) address space with extra DRAM. The Memory Map grants interface with SoC design, while having most system control on a high level coding. Memory access instructions can be used on high level code to manage interrupt modules and built-in peripherals. All of this controlled by **Memory Management Unit (MMU)**. -![Hybrid architectures.](assets/memory-guide-004.png) - The memory resource is handled by the MMU. The main role of the MMU is to enable the processor to run multiple tasks independently in its own virtual memory space; the MMU then uses translation tables to establish a bridge between the virtual and the physical memory addresses. Virtual Address is managed via software with memory instructions, and Physical address is the memory system that is controlled depending on the Translation Table input given by the Virtual Address. An example of how memory is organized in ARM-based microcontrollers, virtually and physically, is shown in the image below: @@ -139,32 +139,34 @@ The ARM-based microcontroller's memory is organized into the following sections The following table summarizes a specific Arduino® board's memory allocation: -| **Board** | **Microcontroller** | **Family** | **Architecture** | **Flash** | **SRAM** | **EEPROM** | -|:-------------------:|:-------------------:|:----------------:|:----------------:|:---------:|:--------:|:----------:| -| UNO Mini | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | -| UNO Rev3 | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | -| UNO WiFi Rev2 | ATmega4809 | AVR | Harvard | 48kB | 6kB | 256B | -| UNO Rev3 SMD | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | -| Leonardo | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | -| Mega 2560 Rev3 | ATmega2560 | AVR | Harvard | 256kB | 8kB | 4kB | -| Micro | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | -| Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| Portenta H7* | STM32H747 | ARM Cortex M4/M7 | Harvard | 16MB | 8MB | - | -| Nicla Sense ME | nRF52832 | ARM Cortex M4 | Harvard | 512kB | 64kB | - | -| Nano RP2040 Connect | RP2040 | ARM Cortex M0+ | Von Neumann | - | 264kB | - | -| MKR FOX 1200 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| MKR NB 1500 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| MKR Vidor 4000 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| MKR WiFi 1010 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| MKR Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| MKR1000 WIFI | ATSAMW25H18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| MKR WAN 1300 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| MKR WAN 1310 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| Nano | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | -| Nano Every | ATmega4809 | AVR | Harvard | 48kB | 6kB | 256B | -| Nano 33 IoT | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | -| Nano 33 BLE | nRF52840 | ARM Cortex M4 | Harvard | 1MB | 256kB | - | -| Nano 33 BLE Sense | nRF52840 | ARM Cortex M4 | Harvard | 1MB | 256kB | - | +| **Board** | **Microcontroller** | **Family** | **Architecture** | **Flash** | **SRAM** | **EEPROM** | +|:---------------------------------:|:-------------------:|:----------------:|:----------------:|:---------:|:--------:|:----------:| +| UNO Mini | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | +| UNO Rev3 | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | +| UNO WiFi Rev2 | ATmega4809 | AVR | Harvard | 48kB | 6kB | 256B | +| UNO Rev3 SMD | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | +| Leonardo | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | +| Mega 2560 Rev3 | ATmega2560 | AVR | Harvard | 256kB | 8kB | 4kB | +| Micro | ATmega32u4 | AVR | Harvard | 32kB | 2.5kB | 1kB | +| Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| Portenta H7 (basic configuration) | STM32H747 | ARM Cortex M4/M7 | Harvard | 16MB | 8MB | - | +| Nicla Sense ME | nRF52832 | ARM Cortex M4 | Harvard | 512kB | 64kB | - | +| Nano RP2040 Connect | RP2040 | ARM Cortex M0+ | Von Neumann | - | 264kB | - | +| MKR FOX 1200 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR NB 1500 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR Vidor 4000 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR WiFi 1010 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR Zero | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR1000 WIFI | ATSAMW25H18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR WAN 1300 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| MKR WAN 1310 | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| Nano | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | +| Nano Every | ATmega4809 | AVR | Harvard | 48kB | 6kB | 256B | +| Nano 33 IoT | ATSAMD21G18 | ARM Cortex M0+ | Von Neumann | 256kB | 32kB | - | +| Nano 33 BLE | nRF52840 | ARM Cortex M4 | Harvard | 1MB | 256kB | - | +| Nano 33 BLE Sense | nRF52840 | ARM Cortex M4 | Harvard | 1MB | 256kB | - | + +***Pro hardware SDRAM and Flash memory are highly customizable in volumes. Check out the [Pro site](https://www.arduino.cc/pro/) for more information.*** ## Measuring Memory Usage in Arduino® Boards @@ -314,7 +316,7 @@ const PROGMEM uint16_t NumSet[] = {0, 1, 1, 2, 3, 5, 8 ...}; const char greetMessage[] PROGMEM = {"Something"}; ``` -***You can read more about PROGMEM in the [language reference](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/).*** +***You can read more about PROGMEM in the [lArduino Language Reference](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/).*** #### Non-Dynamic Memory Allocation @@ -349,7 +351,7 @@ String_Variable.reserve(Alloc_Size); ``` -***For more information about the `reserve()` function, visit [this article](https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/reserve/).*** +***For more information about the `reserve()` function, visit [Arduino Language Reference](https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/reserve/).*** #### Buffer Size Control @@ -374,27 +376,25 @@ Data types exist to ease data stream format and to be handled without making ill The following table shows basic value data types in Arduino: -| Data Type | Byte Size | Range | Format Specifier | -| :--------------------: | :---------: | :-----------------------------------: | :-----------------: | -| **char, signed char** | 1 | -128 ~ 127 | %c | -| **unsigned char** | 1 | 0 ~ 255 | %c | -| **int, signed int** | 2 , 4 | -32,768 ~ 32,767 | %d, %i | -| **unsigned int** | 2 , 4 | 0 ~ 65,535 | %u | -| **signed short int** | 2 | -32,768 ~ 32,767 | %hd | -| **unsigned short int** | 2 | 0 ~ 65,535 | %hu | -| **long int** | 4 | -2,147,483,648 ~ 2,147,483,647 | %ld, %li | -| **long long int** | 8 | -(2^63-1) ~ 2^63-1 (C99 Standard) | %lld, %lli | -| **unsigned long int** | 4 | 0 to 4,294,967,295 | %lu | -| **unsigned long long int** | 8 | 2^64-1 (C99 standard) | %llu | -| **float** | 4 | 1E-37 ~ 1E+37 + 6 Digit Precision | %f | -| **double** | 8 | 1E-37 ~ 1E+37 + 10 Digit Precision | %lf | -| **long double** | 10 | 1E-37 ~ 1E+37 + 10 Digit Precision | %Lf | +| **Type** | **Byte Length** | **Range of Values** | +|:---------------:|:---------------:|:-------------------------------:| +| `boolean` | 1 | Limited to logic true and false | +| `char` | 1 | -128 to 128 | +| `unsigned char` | 1 | 0 to 255 | +| `byte` | 1 | o to 255 | +| `int` | 2 | -32,768 to 32,767 | +| `unsigned int` | 2 | 0 to 65,535 | +| `word` | 2 | 0 to 65,535 | +| `long` | 4 | -2,147,483,648 to 2,147,483,647 | +| `unsigned long` | 4 | 0 to 4,294,967,295 | +| `float` | 4 | -3.4028235E+38 to 3.4028235E+38 | +| `double` | 4 | -3.4028235E+38 to 3.4028235E+38 | ### EEPROM Memory Optimization -EEPROM memory optimization usually is not required, as it will be used mainly to store external module tuning constant. The data which are to be used by EEPROM space are the ones does not really need flash memory as storage source. On top of it, it is not a good practice to offload SRAM data on EEPROM space. SRAM data are placed within volatility in mind, so offloading to EERPOM space, which is non-volatile memory, will mean the offloaded data will be engraved into EEPROM space. As result, the it is impractical use of storage and the variable will change in its value, making the old data unusable. +EEPROM memory optimization is usually not required; data that are to be used by EEPROM space do not need Flash memory as a storage source. On top of it, **it is not a good practice to offload SRAM data on EEPROM**. SRAM data are placed within volatility in mind, so offloading to EEPROM space, which is non-volatile memory, will mean the offloaded data will be engraved into EEPROM space. -One thing to consider with EEPROM is the read and write operation cycles. With EEPROM, it is crucial to know that write operation is limited. The read operation is unlimited for EEPROM. However, the write operation is finite and capped to 100,000 cycles of operation usually. Thus, it is important to save only parameters that are absolutely important for sensors or modules to work with mostly unchanging data. Additionally avoid implementing in a loop code, to avoid constant write operation, as it will wipe out, most likely in instant. +With EEPROM, it is crucial to know that `write` operation is limited. The `read` operation is unlimited for EEPROM; however, the `write` operation is finite and usually capped at 100,000 cycles. Thus, it is essential to save only essential parameters for sensors or modules to work with primarily unchanging data. Additionally, avoid implementing `write` operations into loops to avoid constant `write` operations while the system is working. ### EEPROM Emulation with Flash Memory @@ -404,4 +404,4 @@ Sometimes the developer would have to use the EEPROM as an alternative storage f ***Find out more in the [FlashStorage](https://github.com/cmaglie/FlashStorage) library by Christian Maglie.*** -The FlashStorage library will help you to use the Flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As it is for EEPROM, the Flash memory is also limited in write operation cycle. With two new additional functions stated in the library, one of them being `EEPROM.commit()` should not be called inside a loop function. Otherwise, it will wipe out the Flash memory's write operation cycles, thus loss of data retention ability. +The FlashStorage library will help you to use the Flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As it is for EEPROM, the Flash memory is also limited in write operation cycle. With two new additional functions stated in the library, one of them being `EEPROM.commit()` should not be called inside a loop function. Otherwise, it will wipe out the Flash memory's write operation cycles, thus loss of data retention ability. \ No newline at end of file From c2a7bb32555a6ed6ad7c80f835fe28e479999229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Thu, 7 Apr 2022 14:44:17 -0600 Subject: [PATCH 33/36] Tutorial update based on comments --- .../06.memory-guide/memory-guide.md | 49 ++++++++++++++----- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index ebb04fe005..6a5cc5e72c 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -172,8 +172,6 @@ The following table summarizes a specific Arduino® board's memory allocation: Memory usage statistics help comprehend the insight of resource management affected by the designed code structure. Memory load demand is one statistic that will give you an insight into how efficient the code is design|ed. It is a crucial development consideration element because the resources are finite inside a microcontroller-based system; **software should always perform without reaching maximum load capacity to avoid problems or issues**. Memory load could be observed either as **available RAM** at disposal for specific tasks or **flash storage remaining capacity** for required headroom. -### SRAM & DRAM: Quick Differentiation Specification - ***To avoid run-time problems, microcontroller-based systems should always run without reaching their maximum memory capacity.*** Let us talk more about **memory usage measurement** in Arduino® boards. @@ -198,7 +196,7 @@ Notice that the compiler's output changes depending on if the board is AVR-based ### SRAM Memory Measurement -Sometimes, there are situations where even when code is compiled and uploaded successfully by the IDE into a board, it suffers from sudden halts. These issues are likely due to memory resource-hogging or insufficient memory to allocate. It is necessary to understand which code sector the memory demand is going beyond the available resources to solve this. The following example code can be used to **measure SRAM usage**: +Sometimes, there are situations where even when code is compiled and uploaded successfully by the IDE into a board, it suffers from sudden halts. These issues are likely due to memory resource-hogging or insufficient memory to allocate. It is necessary to understand which code sector the memory demand is going beyond the available resources to solve this. The following example code can be used to **measure SRAM usage in AVR-based Arduino® boards**: ```arduino void display_freeram() { @@ -219,6 +217,24 @@ Remember that the `heap` section is where variables created during the run time - **`__heap_start`**: the beginning of the `heap` section. - **`__brkval`**: the last memory address pointer used by the `heap`. +The following example code can be used to **measure SRAM usage in ARM-based Arduino® boards**: + +```arduino +extern "C" char* sbrk(int incr); + +void display_freeram(){ + Serial.print(F("- SRAM left: ")); + Serial.println(freeRam()); +} + +int freeRam() { + char top; + return &top - reinterpret_cast(sbrk(0)); +} +``` + +The code above is taken from Michael P. Flaga's library [Arduino-MemoryFree](https://github.com/mpflaga/Arduino-MemoryFree). + ### EEPROM Memory Measurement EEPROM memory management can be done easily using native libraries already installed into the Arduino IDE. The `EEPROM` library can be used to read, write and erase the EEPROM memory. The following code shows how a byte of information can be stored in the EEPROM memory and then read using the `write` and `read` functions: @@ -316,7 +332,7 @@ const PROGMEM uint16_t NumSet[] = {0, 1, 1, 2, 3, 5, 8 ...}; const char greetMessage[] PROGMEM = {"Something"}; ``` -***You can read more about PROGMEM in the [lArduino Language Reference](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/).*** +***You can read more about PROGMEM in the [Arduino Language Reference](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/).*** #### Non-Dynamic Memory Allocation @@ -366,7 +382,7 @@ Let us discuss an example: serial communications in Arduino. Serial communicatio #define SERIAL_RX_BUFFER_SIZE 64 ``` -External libraries can usually be modified to optimize buffer sizes used for performing specific tasks of the libraries. +***External libraries can usually be modified to optimize buffer sizes used for performing specific tasks of the libraries.*** #### Corrective Data Type Usage @@ -394,14 +410,25 @@ The following table shows basic value data types in Arduino: EEPROM memory optimization is usually not required; data that are to be used by EEPROM space do not need Flash memory as a storage source. On top of it, **it is not a good practice to offload SRAM data on EEPROM**. SRAM data are placed within volatility in mind, so offloading to EEPROM space, which is non-volatile memory, will mean the offloaded data will be engraved into EEPROM space. -With EEPROM, it is crucial to know that `write` operation is limited. The `read` operation is unlimited for EEPROM; however, the `write` operation is finite and usually capped at 100,000 cycles. Thus, it is essential to save only essential parameters for sensors or modules to work with primarily unchanging data. Additionally, avoid implementing `write` operations into loops to avoid constant `write` operations while the system is working. +With EEPROM, it is crucial to know that `write` operation is limited. The `read` operation is unlimited for EEPROM; however, the `write` operation is finite and usually capped at 100,000 cycles. Thus, it is essential to save only essential parameters for sensors or modules to work with primarily unchanging data. Additionally, avoid implementing `write` operations into loops to avoid constant `write` operations, these operations should be minimized while the system is working. + +#### EEPROM Emulation with Flash Memory + +As EEPROM is limited with the write operation cycle, it also applies to Flash memory. Both of them are subjected to data retention loss after the manufacturer's defined life cycle. EEPROM is based on NOR-type memory, while the Flash memory is NAND type, making the EEPROM more costly than Flash memory. EEPROM works by accessing the data byte-wise, whereas Flash memory accesses block by block. + +Sometimes the developer would have to use the EEPROM as alternative storage for task operations, but we know it will be impractical coding due to its size and behavior properties. It is possible to use Flash memory to emulate the EEPROM to solve this. Thanks to the [FlashStorage](https://github.com/cmaglie/FlashStorage) library created by Chrisitan Maglie, it is possible to emulate the EEPROM by using Flash memory. + +***The FlashStorage library will help you to use the Flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As for EEPROM, the Flash memory is also limited in the `write` cycles. With two new additional functions stated in the library, `EEPROM.commit()` should not be called inside a loop function; otherwise, it will wipe out the Flash memory's `write` operation cycles, thus losing data retention ability.*** -### EEPROM Emulation with Flash Memory +### Further Reading and Resources -As EEPROM is limited with write operatin cycle, it also applies same to Flash memory. Both of them are subjected to loss of data retention after the manufacturer's defined life cycle. EEPROM is based of NOR type memory, while the Flash memory is NAND type, making the EEPROM more costly than Flash memory. EEPROM works by accessing the data byte-wise, whereas Flash memory accesses block by block. +Memory architectures in microcontroller-based systems is a pretty vast topic; if you want to learn more about this topic, check out the following links: -Sometimes the developer would have to use the EEPROM as an alternative storage for task operations, but we clearly know that it will be impractical coding due to its size and behaviour properties. To solve this, it is possible to use Flash memory to emulate the EEPROM. Thanks to [FlashStorage](https://github.com/cmaglie/FlashStorage) library created by Chrisitan Maglie, it is possible to emulate the EEPROM by using Flash memory. +- 8-bit AVR® Core documentation in the [Microchip® Developer help site](https://microchipdeveloper.com/8avr:avrcore). Here you can find detailed information of the 8-bit AVR® Central Processing Unit (CPU). +- ARM architecture [documentation site](https://developer.arm.com/documentation/). Here you can find detailed information of the different ARM processors. Check out the Cortex-M0+ and Cortex-M4 Technical Reference Manuals. -***Find out more in the [FlashStorage](https://github.com/cmaglie/FlashStorage) library by Christian Maglie.*** +### References -The FlashStorage library will help you to use the Flash memory to emulate the EEPROM, but of course, please remember the EEPROM's properties when using the library. As it is for EEPROM, the Flash memory is also limited in write operation cycle. With two new additional functions stated in the library, one of them being `EEPROM.commit()` should not be called inside a loop function. Otherwise, it will wipe out the Flash memory's write operation cycles, thus loss of data retention ability. \ No newline at end of file +[1] S. F. Barrett and D. J. Pack, Microchip AVR® Microcontroller Primer: Programming and Interfacing, Third Edition (Synthesis Lectures on Digital Circuits and Systems), Morgan & Claypool, 2019.
    +[2] J. Y. Yiu, The Definitive Guide to ARM Cortex -M0 and Cortex-M0+ Processors, Second ed., Newnes, 2015.
    +[3] J. Yiu, The Definitive Guide to ARM® Cortex®-M3 and Cortex®-M4 Processors, Third ed., Newnes, 2014.
    \ No newline at end of file From 40fab3d6395ebdfb3333c9c0b9db47ebb1b72913 Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Thu, 7 Apr 2022 15:15:37 -0600 Subject: [PATCH 34/36] Minor Content Update: Based on Comments --- .../06.memory-guide/memory-guide.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 6a5cc5e72c..2c5626d113 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -317,7 +317,7 @@ Not only Strings occupy SRAM space, but **global variables** also take up quite `PROGMEM`, which stands for **Program Memory**, can be used to store variable data into Flash memory space, just as the `F()` wrapper described before, but the use of `PROGMEM` presents one disadvantage: data read speed. Using RAM will provide a much faster data read speed, but `PROGMEM`, as it uses Flash memory, will be slower than RAM, given the same data size. Thus, it is essential to design code knowing which variables are crucial and which do not or have a lower priority. -The use of `PROGMEM` in an AVR-based Arduino board is shown in the example code below: +The use of `PROGMEM` in an **AVR-based Arduino® board** is shown in the example code below: ```arduino #include @@ -332,6 +332,22 @@ const PROGMEM uint16_t NumSet[] = {0, 1, 1, 2, 3, 5, 8 ...}; const char greetMessage[] PROGMEM = {"Something"}; ``` +For **ARM-based Arduino® board**, to implement similar solution, we will need to use `static const` over the variables. + +```arduino +static const int Variable = Data; +``` + +The usage differs in different levels summarized as following: +- *Namespace Level* + - At Namespace level, we are pointing at the variables and it is differed whether `static` is declared or not. If declared, it infers that the variable is explicit static; on the other hand, it is implicit static declaration. + +- *Function Level* + - If it is declared within `static`, any type of applicable data that is to be managed will be between function calls. + +- *Class Level* + - On a Class level, `static` declaration will mean any type of applicable data that is handled will be shared in between the instances. + ***You can read more about PROGMEM in the [Arduino Language Reference](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/).*** #### Non-Dynamic Memory Allocation From f0ec61b6ba8fbaac5a41fd54ed71b45132f45693 Mon Sep 17 00:00:00 2001 From: jho1213gt Date: Thu, 7 Apr 2022 15:24:09 -0600 Subject: [PATCH 35/36] Minor Content Struct Update: Based on Comments --- content/learn/03.programming/06.memory-guide/memory-guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 2c5626d113..5b55c563fb 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -332,6 +332,8 @@ const PROGMEM uint16_t NumSet[] = {0, 1, 1, 2, 3, 5, 8 ...}; const char greetMessage[] PROGMEM = {"Something"}; ``` +***You can read more about PROGMEM in the [Arduino Language Reference](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/).*** + For **ARM-based Arduino® board**, to implement similar solution, we will need to use `static const` over the variables. ```arduino @@ -348,8 +350,6 @@ The usage differs in different levels summarized as following: - *Class Level* - On a Class level, `static` declaration will mean any type of applicable data that is handled will be shared in between the instances. -***You can read more about PROGMEM in the [Arduino Language Reference](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/).*** - #### Non-Dynamic Memory Allocation Dynamic memory allocation is usually a suitable method if the RAM size of the system is big enough to get around with; however, for microcontroller-based systems, such as embedded systems, counting every Byte of RAM is not recommended. From 7d47b10393ecd549cdb96f03b9d0c4d67ce2f52e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Bagur=20N=C3=A1jera?= Date: Fri, 8 Apr 2022 08:54:28 -0600 Subject: [PATCH 36/36] Tables update --- .../learn/03.programming/06.memory-guide/memory-guide.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/learn/03.programming/06.memory-guide/memory-guide.md b/content/learn/03.programming/06.memory-guide/memory-guide.md index 5b55c563fb..bed73b18b0 100644 --- a/content/learn/03.programming/06.memory-guide/memory-guide.md +++ b/content/learn/03.programming/06.memory-guide/memory-guide.md @@ -53,7 +53,7 @@ Microcontrollers are usually used in embedded applications. They must perform de Arduino® boards are mainly based on two families of microcontrollers: **AVR®** and **ARM®**. While AVR® family microcontrollers are based on the Harvard architecture model, ARM® family microcontrollers can be based on either von Neuman or Harvard architectures models. The following table summarizes Arduino boards microcontrollers architectures: | **Board** | **Microcontroller** | **Family** | **Architecture** | -|:-------------------:|:-------------------:|:----------------:|:----------------:| +|---------------------|---------------------|------------------|------------------| | UNO Mini | ATmega328P | AVR | Harvard | | UNO Rev3 | ATmega328P | AVR | Harvard | | UNO WiFi Rev2 | ATmega4809 | AVR | Harvard | @@ -140,7 +140,7 @@ The ARM-based microcontroller's memory is organized into the following sections The following table summarizes a specific Arduino® board's memory allocation: | **Board** | **Microcontroller** | **Family** | **Architecture** | **Flash** | **SRAM** | **EEPROM** | -|:---------------------------------:|:-------------------:|:----------------:|:----------------:|:---------:|:--------:|:----------:| +|-----------------------------------|---------------------|------------------|------------------|-----------|----------|------------| | UNO Mini | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | | UNO Rev3 | ATmega328P | AVR | Harvard | 32kB | 2kB | 1kB | | UNO WiFi Rev2 | ATmega4809 | AVR | Harvard | 48kB | 6kB | 256B | @@ -180,7 +180,7 @@ Let us talk more about **memory usage measurement** in Arduino® boards. Flash memory on Arduino® boards can be measured with the help of the Arduino IDE. As stated before, Flash memory is where the application code is stored; **the Arduino IDE reports Flash memory usage through its compiler output console** to let developers know how much Flash memory resources are being used. -For example, the IDE's compiler output console an AVR-based Arduino® board, the UNO, with the `Blink.ino` example sketch uploaded, is shown in the image below: +For example, the IDE's compiler output console an AVR-based Arduino® board, the UNO, is shown in the image below: ![Flash memory memory measurement in an AVR-based Arduino® board](assets/avr_nano.png)