From 7e8650dd6587451557c3922f45d4659c87db9de2 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 10 Sep 2018 21:13:15 +0800 Subject: [PATCH] feat(esp8266): Refactor task watch dog 1. Remove old watch dog function 2. Put WIFI NVS index table from RAM to flash --- components/esp8266/Kconfig | 39 +++++++ .../esp8266/include/esp8266/eagle_soc.h | 21 ++++ components/esp8266/include/esp_task_wdt.h | 37 +++++++ components/esp8266/include/esp_wifi_osi.h | 2 + components/esp8266/lib/VERSION | 14 +-- components/esp8266/lib/libcore.a | Bin 72160 -> 71358 bytes components/esp8266/lib/libespnow.a | Bin 35428 -> 35376 bytes components/esp8266/lib/libnet80211.a | Bin 359890 -> 359890 bytes components/esp8266/lib/libpp.a | Bin 242828 -> 238074 bytes components/esp8266/lib/libsmartconfig.a | Bin 94602 -> 94602 bytes components/esp8266/lib/libwpa.a | Bin 128852 -> 128848 bytes components/esp8266/lib/libwps.a | Bin 272782 -> 272782 bytes .../esp8266/source/esp_wifi_os_adapter.c | 7 ++ components/esp8266/source/startup.c | 6 +- components/esp8266/source/task_wdt.c | 102 ++++++++++++++++++ components/freertos/port/esp8266/panic.c | 16 +-- components/freertos/port/esp8266/port.c | 9 ++ .../freertos/port/esp8266/xtensa_vectors.S | 91 +--------------- components/spi_flash/src/spi_flash.c | 8 +- 19 files changed, 242 insertions(+), 110 deletions(-) create mode 100644 components/esp8266/include/esp_task_wdt.h create mode 100644 components/esp8266/source/task_wdt.c diff --git a/components/esp8266/Kconfig b/components/esp8266/Kconfig index 711b2bf1..98900d5a 100644 --- a/components/esp8266/Kconfig +++ b/components/esp8266/Kconfig @@ -71,6 +71,45 @@ config MAIN_TASK_STACK_SIZE which calls app_main(). If app_main() returns then this task is deleted and its stack memory is freed. +config TASK_WDT + bool "Initialize Task Watchdog Timer on startup" + default y + help + The Task Watchdog Timer can be used to make sure individual tasks are still + running. Enabling this option will cause the Task Watchdog Timer to be + initialized automatically at startup. The Task Watchdog timer can be + initialized after startup as well. + +config TASK_WDT_PANIC + bool "Invoke panic handler on Task Watchdog timeout" + depends on TASK_WDT + default n + help + If this option is enabled, the Task Watchdog Timer will be configured to + trigger the panic handler when it times out. And it may cost some time. + +choice TASK_WDT_TIMEOUT_S + prompt "Task Watchdog timeout period (seconds)" + depends on TASK_WDT + default TASK_WDT_TIMEOUT_13N + help + Timeout period configuration for the Task Watchdog Timer in seconds. + This is also configurable at run time. + +config TASK_WDT_TIMEOUT_13N + bool "6.5536s" +config TASK_WDT_TIMEOUT_14N + bool "13.1072s" +config TASK_WDT_TIMEOUT_15N + bool "26.2144s" +endchoice + +config TASK_WDT_TIMEOUT_S + int + default 13 if TASK_WDT_TIMEOUT_13N + default 14 if TASK_WDT_TIMEOUT_14N + default 15 if TASK_WDT_TIMEOUT_15N + endmenu menu WIFI diff --git a/components/esp8266/include/esp8266/eagle_soc.h b/components/esp8266/include/esp8266/eagle_soc.h index 1a49b12c..28d105a8 100644 --- a/components/esp8266/include/esp8266/eagle_soc.h +++ b/components/esp8266/include/esp8266/eagle_soc.h @@ -117,10 +117,31 @@ //Interrupt remap control registers define{{ #define EDGE_INT_ENABLE_REG (PERIPHS_DPORT_BASEADDR + 0x04) +#define WDT_EDGE_INT_ENABLE() SET_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT0) #define TM1_EDGE_INT_ENABLE() SET_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1) #define TM1_EDGE_INT_DISABLE() CLEAR_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1) //}} + +//Watch dog reg {{ +#define PERIPHS_WDT_BASEADDR 0x60000900 + +#define WDT_CTL_ADDRESS 0 +#define WDT_OP_ADDRESS 0x4 +#define WDT_OP_ND_ADDRESS 0x8 +#define WDT_RST_ADDRESS 0x14 + +#define WDT_CTL_RSTLEN_MASK 0x38 +#define WDT_CTL_RSPMOD_MASK 0x6 +#define WDT_CTL_EN_MASK 0x1 + +#define WDT_CTL_RSTLEN_LSB 0x3 +#define WDT_CTL_RSPMOD_LSB 0x1 +#define WDT_CTL_EN_LSB 0 + +#define WDT_FEED_VALUE 0x73 +//}} + //RTC reg {{ #define REG_RTC_BASE PERIPHS_RTC_BASEADDR diff --git a/components/esp8266/include/esp_task_wdt.h b/components/esp8266/include/esp_task_wdt.h new file mode 100644 index 00000000..1a7edcc1 --- /dev/null +++ b/components/esp8266/include/esp_task_wdt.h @@ -0,0 +1,37 @@ +// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include +#include "esp_err.h" + +/** + * @brief Initialize the Task Watchdog Timer (TWDT) + * + * @return + * - ESP_OK: Initialization was successful + * - ESP_ERR_NO_MEM: Initialization failed due to lack of memory + * + * @note esp_task_wdt_init() must only be called after the scheduler + * started + */ +esp_err_t esp_task_wdt_init(void); + +/** + * @brief Reset(Feed) the Task Watchdog Timer (TWDT) on behalf of the currently + * running task + */ +void esp_task_wdt_reset(void); diff --git a/components/esp8266/include/esp_wifi_osi.h b/components/esp8266/include/esp_wifi_osi.h index 9e19dcc9..763d6f28 100644 --- a/components/esp8266/include/esp_wifi_osi.h +++ b/components/esp8266/include/esp_wifi_osi.h @@ -149,6 +149,8 @@ extern wifi_osi_funcs_t s_wifi_osi_funcs; #define wifi_rand() \ s_wifi_osi_funcs.rand() +void *osi_task_top_sp(void); + #ifdef __cplusplus } #endif diff --git a/components/esp8266/lib/VERSION b/components/esp8266/lib/VERSION index 3d43a58f..b70096dd 100644 --- a/components/esp8266/lib/VERSION +++ b/components/esp8266/lib/VERSION @@ -1,9 +1,9 @@ gwen: - core: b9f2d3e - net80211: 48cd36b - pp: 82269d9 - smartconfig:eca7811 - wpa: b9f2d3e - espnow: 95a55d0 - wps: 48cd36b + core: 103fbb8 + net80211: 103fbb8 + pp: 103fbb8 + smartconfig:103fbb8 + wpa: 103fbb8 + espnow: 103fbb8 + wps: 103fbb8 phy: 1055_8 \ No newline at end of file diff --git a/components/esp8266/lib/libcore.a b/components/esp8266/lib/libcore.a index 7a8b7c4f916cd9eca92773b545409991bbcf251a..6083e5ad93b4d9344c2a30cd6a5e9c6f87c78948 100644 GIT binary patch delta 3318 zcmcIle`r-@82;XK@7?b8+-+yOYns{h`eSpN&Slqak=3MSVp>C|=@K^jA*~-~W&Tm* zG5-iEgz}JIXiAMj2o>Q9W`z=g_=l`PMlmE@fAj;521Nud>Uqw658mB^EbxW*ywCf* z&-b10eCIvixlo9oJRE;*n%~jd)|PL}ky8tB_P@WjJUhdf^Q!eBH#Cm2gt2Fa>L6~$gFbXHY6ii6Io zhQgyYZ|9<#*XmT4)>>}6l!x;2+aXeKyG0&9{(;B=r?DP=eMyX&jd;{CCXRRp(L)^9yxG1QmuGxRrP-Kn z$nOH)3AextA5G7(9;U>Whhw{dX-PQoHHe&N1F)<3q01WIFqx}` zU6%`nc#87xmGH!zd=P#(;<1S6Ik})?;Q3%X;e2iy7ai>ZHD7_BZMushZb~GIHi#k< zGlqc^H3QQ)5pfcjnpWVcz|^dW?WvT8<3knlfXIsA@Sa%}`C4NRC2Vg}W;)wryB9YE zp7jztFeqV1DxZi(AvjHlyvGh$+Ug)yDM()%*@ zP)fYSmdVES+fPz5D{&GP&;CF-4A!%?lK_XX%3ah4Lv3C~4-UF9C;0l!nTf6%K>Jim zGC{Vz#g0sp?qFrRXXm-n%hwV1N(h+1*gGxoe)xHK9rmUpn7ennzYbYsRBeh9MCRMd z@|Vl<-DUY;S$?Q2KQ%G;&Dn{B`LZk@Ez8Hs^54tyB>J4~(*v(Fm8Mbqo-#hrBINvD z_JwsnX6`5xtU}I@Vt*)znf|i+lV$lfb3qKf*j1sG)JgBFs&aYWtigoBTD<*Ta{<*D3Bq>{Hx@_?Y75h%YE!iFgC<&9S`a zQpG$kx)pO>&nxD7Us24%hUW*y-fezE;SDW}0}qyn-Y>!2VBUe%!Gm zwbJh6d#3Gylg=r2m48e5#i;SsNF6S)cj45NBX*VNE0YW^u%mEl$Pv5B&j*e)*$-7j zk~k8zQdDn`)XC)VR7aX8#S<7d1n1o3h+XA*&`Sd@uyb%~$Pv5BF98-DDzp(eHROn0 znXN?^GT7g!zY)Q}@~ zmG4F_>`ItD$3nXMrx)PH49Wjj@VWHBjx!U z^}o=B|51Z(irQg@b{IM0s2$?eG!}1gvuel@yUO3LJli}8m!_hAh4SQx-6rFQl{7^< zc!!F}5l550q&&Zy-HQ3I-K)3@aeoPBEqs-T{P%{xOWf^*^5jl9xWCJ8h7D6RuZX`< z5jkR4`EwnXd}{c&;`864B9g=|3ovTyk<<9`5XTWa z6ekhWaG8M%j2lP|Ibv7&rOIzW^x%=6P2R)-B$-45RsoaefOR3Z-!@2}#DWX+))Wrj dyH$dN^QQ!NewUdYp0<$Ec#w(WuuZsF*k6JltN#E1 delta 4020 zcmcImZEO@(6uob|yWMuCbZN`hDwcK8N(Jmfi=tLoNe%oE(nzDVl60wv5ECp=11625 zjZuG~qGK6UG)nZ3i3Y6(B*rWTjR}G^Aq0^Keh@K0tnmYbg?i5Joj9!iKof6r=bn4+ znK$pfdGF19@J9IPPkyw}iefvsSKJ+1I^d zUH7_WeeN`SN(`}^oV(bbU%IsKt`*DfyT?0HVG^OHCigA7(aqTr_mDj^T3CMW(XQH| z#){MCuRJl-TKRG^nE&2%vLcYbJ?CU~ARUU`x-%5azv>u`Xg+kb>%c34TFJG|v)!*d z8bh1Q-#)v@ICAdCxe}Eu*0@yd8Ywf0foT7CcJ*6l#x6TEmP<+~mCHz+peKjx)~OGt zUr!R;`>_2U;xj$F?1P8{Js-9{hS-zJ^)9ENrzh7xh&V5mYj0x%^YRU#y|l27_RKdG zV>ywSsoE8<7!es-bZ*onZaO;_6T7M*8EHs|mS>C|O0`ME{cJ2TIL}NB85vw+R=vB= zJRh26qt~Apks8GHA(6`wTT4X3h#iP=#K$#%2Qh~Hxc5YfS?lmtGeu+pZeI;N0Dlj- z0&y$+V_;eg8vha09|k`kJoS_D$k~Y0-w8ZX@j74{@AbRId$)jZ0Y4z($gnR0K|BF* zEBqL+rFbNuA#PN@4r8Ik;KUap^4=K%o|tv=*ZDj;QJ5d6F!~G%oV)=zCyd5k`;*6B zF9XksrG}G9qsE_DYBqpJ$ZI&!G-~`wr{;a|7lUUz2iUtx0QT-!;D+PCF>t(LBydA{ z*jp4aiS3;cv&w|Z!|p?yQqj>W^fc;?L`^D^!8WS48ZoutqLR*zKR3fanI~OR>D#>%0x6rXjQ~?7hR7j(CR=qmM>Jb{IG3r6O}mMcUmNs`JVH0M-HA($hSrLsiJ(eC@;~cQ2nzNF1*jiF?(YWHe<-StAm>itR%ZPia(|&SABWER#u>UakbCvENd-SR+vnP5 zf~oUAInvwPz4pH4ef$>Xzd_#O3iC|mnzhK5%euhFsM(Pn=!DV6xlK(|;jx{>cybqN zJO+rfzz@NRXCw9#Hx%?d;C##jkQy3atB*+;Zg<$-@EYT-A7{Fp4h)`4pcQ_*;tb*u z#XNYwQT!?53B|*Rrxouj1qRBS1~ zMfq8%@fbGMxWHb8Q%{cAQXU7V7*0NH8=M+)#Fp~YfPGE|gM1h!3%*ixP!L{p0kY(JbDa>SPMt-$6YTwsUb)Q}^#l+OSg9JDkqI^K+T zG-(52F3$6E0)aP^Bes-Z0BkP71@<$X8gj&z^0xpRu2@(V>eP@Uwv=y2ZZ4$)o!G=q zXwm_~)aQAr*PF=^TgrD*GpV4tQZ?j=E#;R`lf(r!T{Yy0tt45Ih062y#A(CD@SVd* zVRW@@xiTeko?VllO1ap+WI5^o=EWK1a-iMIZC0#!M|VbhGm0 zh%M!pP&2)tS*03s#Fp~efaU?!kR#4(IQ~6a*pIj`fInA!0Pzdr$%TjUpT^8A;9tpO z0OW`*213igjp7Bw;i2sJp7G`;Oxiuwo^`*NX4haKv=+QM Zqd4O}ovOXOlMIIeTNc2*#P|iH{Rw)|O>qDK diff --git a/components/esp8266/lib/libespnow.a b/components/esp8266/lib/libespnow.a index 44f9d76dcb51d6866e06d8827294eb421aa3e209..9a99a2d289d91ed62e61d96907472288b574b3f6 100644 GIT binary patch delta 1246 zcmX|=e`p(J7{{OIF4wHfr90QeRn594nY#{~k-NsWY6ENL6h=cc*wQvlgN)8U$~qi4 zHl$^746V}Yx~Kj?;z$R=z^-hb;19Z4)D0Dj6{@y#107TU*rX0r6vEEuJ#TyAdA?sh z@AJG*F8AK`N$KpQbUfr~i?j_wS`sv6=u)NL`pS3#X;*VB zwqnl#M4A-iH{0B^DWX>64M947v5jl?lP9E04Ukf+&GP7@iH@IXra9De+5RWrm>xT2 zEZb%j%&0ymL(CtNaY;08PM40R%H?Fu)~+IcCrD!&7lo?Q=JetG(Q?`Jo=thr?eV_H z(;mTh^J;VPP!YeTcp`2U5;t(?ANZqasIqPDo-Reg3%2pCohskL@9*;PyuCbYMn;#% zO10rHY~xGb{|mplvmc4PR9YMU)HXh2{5pYLY{x@7~c0fmhTip<4GR! zifz1Vr>5SZ`s6x%lUkBdJZa^U12T7fvQ?I7%QiLqG5|;%A9L*Bh;Voi;2zfpt(DZ% zeyO#UIx+#tc-R`seBi-j^x*C;JWU5VXXqm5pD38^!U5WweF%dzk&PzD& zbTzAE6Di#y$2e=WoAV-#bnD6$8DIl<)Y5FXhVRonvx*0xj&7~3CACMxIIZu|m4E`^ zcUYd;Q#8bEBeVbOrkNe4^UT`s)>W9DCV#K4bTaceGdg=UoTGkbnJR#b&UqzfpVJv; zbzXoKhu!Ser0X4YyLXeaY8AkQ1KV>NmMNXnl@hZ96b=SxJhz62yvYVtHK| zX7;P|0Q;B?&w124IOKX3 z7io{ApigX delta 1302 zcmX|=ZEO@(6o${8?XZ^pU~IRg>O#A_O{Z#WcBUI>wT-g2KuDXG7`9)#O+%0v+P@m0-1f-grrHQuXsA zP4_e|IcJFC4XSa;F}K&ngQen%BpVhS<9BD%5oKd7rGurWb?E-ohKu}OQ*`H?b0b^d zl|N?u?3f8M6Z#n+HHJ(}6Bp#lySoZU(w5a0-qI~*C8+NbKe|mUijS0_Ra}`8-$}AB z`@ChD{$kpHYP)|5y<5clS<~{3JuS}h+Emi+NnI9OuZdrzd4=O(ugO9@_Pt~L;H0g; z#81mSHsj2FYQ_)EiChZ3r zH2dHKd&M0`g|)n0{X1y$nq$1~q$l3waNBC}7T2{U#Jl#EwjDk!{qP~5!r!(BV`D_5 zAU;F%A>xQiL3F#Pb^EvU&XCe#ve6S!nv!;|=aUjK&K29b#c6&Nd6+*&{*%>Ax7fqm zGWQCdM>7evxSpuUCo&0P@k~aC?{DN*Uel|KcJ4r4;E`Tkz3L;X#)@*D?A62~PlE+j zqAI>tR?auUc5tXqS8KsSF6->maDp6IYS~u+o8*&Voy)$fVDo$nEDKiR_Gs)fEX$(xdc%bc1DcrSwgFw81l!HAiU{u? zScN99g4L7~b-2E7;QNSw9ni&NtPbj;nHvXnbumEH>drqgsNsd}2dfPdHG@TXdT+C^ z;6;_7?(;Mrou2VD3gtbGBhm>^Yp7G6j-YPxw4AR(h%^$$FhcGxnbZM~N1=s}4xkV{ zg^(r*r4Hc6$Og}O`~}oePs_Vo^t8OwH3;!A62@7C+^5FV0gr#}@kP{HglI>?m?eBM zxj@2M9^JJ%GY=(6J*w1!4kU~Qgm}=Ew1gr(l1Ux#coJG{M8XK;n9?IzSlH)xJ-HJ9 P%9g#=ew6-aFNFRBoQqU^ diff --git a/components/esp8266/lib/libnet80211.a b/components/esp8266/lib/libnet80211.a index 6cc12eb899b42e9c706ea21dbc39d8a2088c36fb..1646ebd4ad6d6597498726d6e4d5e84b5e11c2f6 100644 GIT binary patch delta 669 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 E1zCia^8f$< delta 45680 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 diff --git a/components/esp8266/lib/libsmartconfig.a b/components/esp8266/lib/libsmartconfig.a index 1c830c5931e1fd39ca6059dedff8c83e98700b6e..badcf14d479ea85907d2b47d5afef554cc304890 100644 GIT binary patch delta 67 zcmeBr%-Z#sb%HdznT3J5g^B4#C23X|d-8!+vCUDe@eMG6%?Dc7&Vg}2vdg=a82tgk CRTU@z delta 67 zcmeBr%-Z#sb%Hdzsj;c0shQbEC23X|d-8!+vCUDe@eMG6%?Dc7&Vg}2vdg=a82tgk Ct`#f* diff --git a/components/esp8266/lib/libwpa.a b/components/esp8266/lib/libwpa.a index bb7a3595f0b734568e125d11b7648bc3fd49fe2a..1d6f85c3bb4a4d462a40335f90b05254629531bb 100644 GIT binary patch delta 909 zcma))OGsN$5J2xFDp>>)P!SSE5Cj)3 zw8k=BO2M6$>a%^p&%%N(Tq!76L2=WKze1^@AX4X=kMVBw!f@`HJIuTXvwf!9Jk!0m zY8q_~4%=Lr7DnnAMD7_g3k-P7Q++zt`x)F7$8iR?BM|EA?+(9t^*R*0cxaU4@I{mS zq?nX2%cHt>OO_s$T1`nsDFPO`ymnBV_59s2sn610_o6CGo4o%fGHQ{f-HYO+%2L8t zl6f&}YU&;KI%Ty0)Ro}JwPx_aV=R0|Xv7|lulS8)3N=nb9(HheaGGNX&pD>h+d_!r zM~=Vvi(?b(T?8ABaRhOPBaRhr0>c50Ag;M#5G>f-3cq0zpLi(g$6*gd;VrsWz=UBv zl;FW0jp)h+gRKKTB(n93^U+^MeERS;46h>CXs>sua*Ef;t zi7pBwRlOj8PWPp2w=us^9|V?}e?2fN6pRc0nLI$vP{jw>*{tyXL-3!19}1oTCu3Gh zmgn$>4yL8X>BIjhU+_nQ*Tzmim6ml1*^uDF_^u6>RpGGWdkL4-$>mXKC!;l~`_>FZ aQ=6a<6o=>Kziow}5pzgQwF(LvQZ>$$|9q!3rxP=jE>oGn=B#f#WW1$#1xQt(X{&1Nn-@Z+2Bz2WUF%;CB9=-j&MGIw}= zFZ`K$3&`CJ<{y~NECZe`I)9t|9E1CEmSa$!>DfebJT8q+%%-j@tCTE!Giz5$#R|2` zl6AzX)4y(4wN4v4<}8}x&ogi;Y9M9PwWmVg4La?KT&~@zQ;Ge)eyXVwD@5zGZE=pt z7w~th`wlR+fP@FV5QRppc}eKONsevY;Yg#ok6_2w9D}&Q@ewaL(irI{II8^4|_#ENc-KQdzn;z zUS{#~0+R(_7W^yuGz~)ozkr`*gnnM|W5G|$TxRTw3NFg?3O+Ev9?{_2#s9ck@H)Y} z1RoK6Oz?!>P4t09Tp5C#CGkFyoSadIhvC2H?yc3T(mY7*IzQb6N%zcEX$u-1x_&wj M%}tuC^s?p0H{fo;vH$=8 diff --git a/components/esp8266/lib/libwps.a b/components/esp8266/lib/libwps.a index 3ca31eec2c700042d18c0558f8d286dedc0a093b..55bfc4cbc7d65ea9dac343d75fb7c71908f0e629 100644 GIT binary patch delta 213 zcmeCXEYNpZV1f**g@J{E(MH9s0ua_@eMRxjp9CzR+|Bxmhq)m#)9qg}N^IuW&38cN z&(1B@MbfD?J3$P>-Q2&?G*a4}L9Zx3C9xz?FFxKa)XzD@)88*XUd6)1*kb#AF2>@y xNM>!%U%_}9YWQ}bW$TUL21{(`mSGA`hw}S3N^Y-dX0rMQmlxlDsgilmdH|PSK~Vqz delta 213 zcmeCXEYNpZV1f**v7wo%*+#{!0ua_@eMRxjp9CzR+|Bxmhq)m#)9qg}N^IuW&38cN z&(1B@MbfD?J3$P>-Q2&?G*a4vL9Zx3C9xz?FFxKa)XzD@)88*XUd6)1*mC=QF2>@y xNM>!%U%_}9YWQ}bW$TUL21{(`mSGA`hw}S3N^Y-dX0rMQmlxlDsgilmdH|;bL3aQE diff --git a/components/esp8266/source/esp_wifi_os_adapter.c b/components/esp8266/source/esp_wifi_os_adapter.c index 51541748..bf6ddfaf 100644 --- a/components/esp8266/source/esp_wifi_os_adapter.c +++ b/components/esp8266/source/esp_wifi_os_adapter.c @@ -341,6 +341,13 @@ static int32_t rand_wrapper(void) return (int32_t)esp_random(); } +void *osi_task_top_sp(void) +{ + extern uint32_t **pxCurrentTCB; + + return pxCurrentTCB[0]; +} + const wifi_osi_funcs_t s_wifi_osi_funcs = { .version = ESP_WIFI_OS_ADAPTER_VERSION, diff --git a/components/esp8266/source/startup.c b/components/esp8266/source/startup.c index 1adc724f..36ceddb6 100644 --- a/components/esp8266/source/startup.c +++ b/components/esp8266/source/startup.c @@ -27,6 +27,7 @@ #include "esp_phy_init.h" #include "esp_wifi_osi.h" #include "esp_heap_caps_init.h" +#include "esp_task_wdt.h" #include "internal/esp_wifi_internal.h" #define FLASH_MAP_ADDR 0x40200000 @@ -58,11 +59,14 @@ static void user_init_entry(void *param) assert(mac_init() == 0); assert(base_gpio_init() == 0); esp_phy_load_cal_and_init(0); - assert(watchdog_init() == 0); assert(wifi_timer_init() == 0); esp_wifi_set_rx_pbuf_mem_type(WIFI_RX_PBUF_DRAM); +#ifdef CONFIG_TASK_WDT + esp_task_wdt_init(); +#endif + app_main(); wifi_task_delete(NULL); diff --git a/components/esp8266/source/task_wdt.c b/components/esp8266/source/task_wdt.c new file mode 100644 index 00000000..1700bf50 --- /dev/null +++ b/components/esp8266/source/task_wdt.c @@ -0,0 +1,102 @@ +// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "esp_log.h" +#include "esp_libc.h" +#include "esp_wifi_osi.h" +#include "esp_task_wdt.h" +#include "portmacro.h" +#include "esp8266/eagle_soc.h" + +#define WDT_REG_READ(_reg) REG_READ(PERIPHS_WDT_BASEADDR + _reg) +#define WDT_REG_WRITE(_reg, _val) REG_WRITE(PERIPHS_WDT_BASEADDR + _reg, _val) +#define CLEAR_WDT_REG_MASK(_reg, _mask) WDT_REG_WRITE(_reg, WDT_REG_READ(_reg) & (~_mask)) +#define WDT_FEED() WDT_REG_WRITE(WDT_RST_ADDRESS, WDT_FEED_VALUE) + +static const char *TAG = "wdt"; + +#ifdef CONFIG_TASK_WDT_PANIC +/** + * @brief Task watch dog interrupt function and it should do panic + */ +static void esp_task_wdt_isr(void *param) +{ + extern void panicHandler(void *frame, int wdt); + + panicHandler(osi_task_top_sp(), 1); +} +#endif + +/** + * @brief Just for pass compiling and mark wdt calling line + */ +esp_err_t esp_task_wdt_init(void) +{ + CLEAR_WDT_REG_MASK(WDT_CTL_ADDRESS, BIT0); + +#ifdef CONFIG_TASK_WDT_PANIC + const uint32_t panic_time_param = 11; + + _xt_isr_attach(ETS_WDT_INUM, esp_task_wdt_isr, NULL); + _xt_isr_unmask(1 << ETS_WDT_INUM); + + WDT_EDGE_INT_ENABLE(); + + ESP_LOGD(TAG, "Enable task watch dog panic, panic time parameter is %u", panic_time_param); +#else + const uint32_t panic_time_param = 1; +#endif + + ESP_LOGD(TAG, "task watch dog trigger time parameter is %u", CONFIG_TASK_WDT_TIMEOUT_S); + + WDT_REG_WRITE(WDT_OP_ADDRESS, CONFIG_TASK_WDT_TIMEOUT_S); // 2^n * 0.8ms, mask 0xf, n = 13 -> (2^13 = 8192) * 0.8 * 0.001 = 6.5536 + WDT_REG_WRITE(WDT_OP_ND_ADDRESS, panic_time_param); // 2^n * 0.8ms, mask 0xf, n = 11 -> (2^11 = 2048) * 0.8 * 0.001 = 1.6384 + + SET_PERI_REG_BITS(PERIPHS_WDT_BASEADDR + WDT_CTL_ADDRESS, WDT_CTL_RSTLEN_MASK, 7 << WDT_CTL_RSTLEN_LSB, 0); + // interrupt then reset + SET_PERI_REG_BITS(PERIPHS_WDT_BASEADDR + WDT_CTL_ADDRESS, WDT_CTL_RSPMOD_MASK, 0 << WDT_CTL_RSPMOD_LSB, 0); + // start task watch dog1 + SET_PERI_REG_BITS(PERIPHS_WDT_BASEADDR + WDT_CTL_ADDRESS, WDT_CTL_EN_MASK, 1 << WDT_CTL_EN_LSB, 0); + + WDT_FEED(); + + return 0; +} + +/** + * @brief Reset(Feed) the Task Watchdog Timer (TWDT) on behalf of the currently + * running task + */ +void esp_task_wdt_reset(void) +{ + WDT_FEED(); +} + +/** + * @brief Just for pass compiling and mark wdt calling line + */ +void pp_soft_wdt_stop(void) +{ + +} + +/** + * @brief Just for pass compiling and mark wdt calling line + */ +void pp_soft_wdt_restart(void) +{ + +} diff --git a/components/freertos/port/esp8266/panic.c b/components/freertos/port/esp8266/panic.c index 8917aad6..6dc86421 100644 --- a/components/freertos/port/esp8266/panic.c +++ b/components/freertos/port/esp8266/panic.c @@ -131,7 +131,7 @@ static void panic_stack(StackType_t *start_stk, StackType_t *end_stk) * * @return none */ -void panic_info(void *frame) +static void panic_info(void *frame, int wdt) { task_info_t *task; int *regs = (int *)frame; @@ -144,14 +144,14 @@ void panic_info(void *frame) " A14", " A15", " SAR", "EXCCAUSE" }; - extern int _Pri_3_NMICount; - panic_str("\r\n\r\n"); - if (_Pri_3_NMICount == -1) { - panic_str("Soft watch dog triggle:\r\n\r\n"); + if (wdt) { + panic_str("Task watchdog got triggered.\r\n\r\n"); show_critical_info(); - } else if (xPortInIsrContext()) + } + + if (xPortInIsrContext()) panic_str("Core 0 was running in ISR context:\r\n\r\n"); if ((task = (task_info_t *)xTaskGetCurrentTaskHandle())) { @@ -195,7 +195,7 @@ void panic_info(void *frame) while (1); } -void IRAM_ATTR panicHandler(void *frame) +void IRAM_ATTR panicHandler(void *frame, int wdt) { int cnt = 10; @@ -208,7 +208,7 @@ void IRAM_ATTR panicHandler(void *frame) // for panic the function that disable cache Cache_Read_Enable_New(); - panic_info(frame); + panic_info(frame, wdt); } void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) diff --git a/components/freertos/port/esp8266/port.c b/components/freertos/port/esp8266/port.c index 49e9dfde..f13b79fe 100644 --- a/components/freertos/port/esp8266/port.c +++ b/components/freertos/port/esp8266/port.c @@ -386,3 +386,12 @@ BaseType_t xQueueGenericReceive(QueueHandle_t xQueue, void * const pvBuffer, configASSERT(xJustPeeking == 0); return xQueueReceive(xQueue, pvBuffer, xTicksToWait); } + +void vApplicationIdleHook(void) +{ + extern void pmIdleHook(void); + extern void esp_task_wdt_reset(void); + + pmIdleHook(); + esp_task_wdt_reset(); +} diff --git a/components/freertos/port/esp8266/xtensa_vectors.S b/components/freertos/port/esp8266/xtensa_vectors.S index 2d74d6fe..b7c8ffb8 100644 --- a/components/freertos/port/esp8266/xtensa_vectors.S +++ b/components/freertos/port/esp8266/xtensa_vectors.S @@ -1418,96 +1418,6 @@ nmi_rfi: #endif #endif /* NMI */ - .section .text, "ax" - .global ShowCritical - .type ShowCritical, @function - .align 4 -ShowCritical: - movi a2, LABEL(_Pri_,_NMICount) - l32i a2, a2, 0 - bnei a2, 1, nmi_reentry_panic - - /* - * a2 == 1, the function is not NMI exception function and its stack - * is stored at LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE - * - * a2 >= 1, the function is NMI exception function and its stack - * is stored at LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE + HESF_TOTALSIZE + PRI_N_STACK_SIZE2 - */ - movi a2, LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE - j nmi_common_panic -nmi_reentry_panic: - movi a2, LABEL(_Pri_,_Stack) + PRI_N_STACK_SIZE + HESF_TOTALSIZE + PRI_N_STACK_SIZE2 -nmi_common_panic: - movi a1, 0XFFFFFFFF - movi a3, LABEL(_Pri_,_NMICount) - s32i a1, a3, 0 - - movi a1, _chip_interrupt_tmp - addi a1, a1, -XT_STK_FRMSZ - - l32i a3, a2, HESF_AR(0) - s32i a3, a1, XT_STK_A0 - - l32i a3, a2, HESF_AR(1) - s32i a3, a1, XT_STK_A1 - - l32i a3, a2, HESF_AR(2) - s32i a3, a1, XT_STK_A2 - - l32i a3, a2, HESF_AR(3) - s32i a3, a1, XT_STK_A3 - - l32i a3, a2, HESF_AR(4) - s32i a3, a1, XT_STK_A4 - - l32i a3, a2, HESF_AR(5) - s32i a3, a1, XT_STK_A5 - - l32i a3, a2, HESF_AR(6) - s32i a3, a1, XT_STK_A6 - - l32i a3, a2, HESF_AR(7) - s32i a3, a1, XT_STK_A7 - - l32i a3, a2, HESF_AR(8) - s32i a3, a1, XT_STK_A8 - - l32i a3, a2, HESF_AR(9) - s32i a3, a1, XT_STK_A9 - - l32i a3, a2, HESF_AR(10) - s32i a3, a1, XT_STK_A10 - - l32i a3, a2, HESF_AR(11) - s32i a3, a1, XT_STK_A11 - - l32i a3, a2, HESF_AR(12) - s32i a3, a1, XT_STK_A12 - - l32i a3, a2, HESF_AR(13) - s32i a3, a1, XT_STK_A13 - - l32i a3, a2, HESF_AR(14) - s32i a3, a1, XT_STK_A14 - - l32i a3, a2, HESF_AR(15) - s32i a3, a1, XT_STK_A15 - - l32i a3, a2, HESF_EXCCAUSE - s32i a3, a1, XT_STK_EXCCAUSE - - l32i a3, a2, HESF_EPC3 - s32i a3, a1, XT_STK_PC - - l32i a3, a2, HESF_EPS3 - s32i a3, a1, XT_STK_PS - - mov a2, a1 - - call0 panicHandler - - .global _xt_ext_panic .type _xt_ext_panic, @function .align 4 @@ -1555,4 +1465,5 @@ _xt_ext_panic: //Call panic handler mov a2, sp + movi a3, 0 call0 panicHandler diff --git a/components/spi_flash/src/spi_flash.c b/components/spi_flash/src/spi_flash.c index 703b9dfb..3866bee5 100644 --- a/components/spi_flash/src/spi_flash.c +++ b/components/spi_flash/src/spi_flash.c @@ -20,6 +20,7 @@ #include "esp_wifi_osi.h" #include "esp_system.h" #include "esp_log.h" +#include "esp_task_wdt.h" #include "esp8266/eagle_soc.h" #include "esp8266/rom_functions.h" #include "esp8266/pin_mux_register.h" @@ -136,7 +137,6 @@ bool special_flash_write_status(uint8_t command, uint32_t status, int len, bool esp_err_t spi_flash_read(size_t src_addr, void *dest, size_t size); uint8_t en25q16x_read_sfdp(); -extern void pp_soft_wdt_feed(void); extern void pp_soft_wdt_stop(void); extern void pp_soft_wdt_restart(void); @@ -494,7 +494,7 @@ esp_err_t IRAM_ATTR spi_flash_write(size_t dest_addr, const void *src, size_t si #define FLASH_WRITE(dest, src, size) \ { \ ret = spi_flash_write_raw(dest, src, size); \ - pp_soft_wdt_feed(); \ + esp_task_wdt_reset(); \ if (ret) { \ return ret; \ } \ @@ -607,7 +607,7 @@ esp_err_t IRAM_ATTR spi_flash_read(size_t src_addr, void *dest, size_t size) #define FLASH_READ(addr, dest, size) \ { \ ret = spi_flash_read_raw(addr, dest, size); \ - pp_soft_wdt_feed(); \ + esp_task_wdt_reset(); \ if (ret) \ return ret; \ } @@ -1028,7 +1028,7 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(size_t start_address, size_t size) do { ret = spi_flash_erase_sector(sec++); - pp_soft_wdt_feed(); + esp_task_wdt_reset(); } while (ret == ESP_OK && --num); return ret;