forked from espressif/esp-idf
Compare commits
1125 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8e057b02c | ||
|
|
86f1a260f5 | ||
|
|
18f2a0d3bc | ||
|
|
0e043ae99f | ||
|
|
c70eecc8c4 | ||
|
|
9bdf545599 | ||
|
|
b08aee46de | ||
|
|
1ef2b2d32a | ||
|
|
1e72a8c850 | ||
|
|
b30e8d1019 | ||
|
|
447032c8ff | ||
|
|
c78fa51d1f | ||
|
|
8f958c8013 | ||
|
|
853bffe1e6 | ||
|
|
346ec3938d | ||
|
|
6802f9eec1 | ||
|
|
fd555836b3 | ||
|
|
b66cd055bc | ||
|
|
96f16cef80 | ||
|
|
61dac00099 | ||
|
|
549269970b | ||
|
|
bd21cd02b6 | ||
|
|
8e55efaa2f | ||
|
|
94e2981d17 | ||
|
|
808bd4faee | ||
|
|
6b230cdbb2 | ||
|
|
80180f4709 | ||
|
|
c5751f7fd7 | ||
|
|
9bae06ef10 | ||
|
|
797eff6534 | ||
|
|
7db5c3ffd1 | ||
|
|
be5e315282 | ||
|
|
f1ac73f496 | ||
|
|
295f0cc546 | ||
|
|
1aee0a0357 | ||
|
|
ca1685f7a2 | ||
|
|
75a205e381 | ||
|
|
28f3619a90 | ||
|
|
3ab91d4395 | ||
|
|
8782bd076e | ||
|
|
c5ff0aff02 | ||
|
|
737dd8b2f1 | ||
|
|
02789d3114 | ||
|
|
dac77846e5 | ||
|
|
2ba75c5b07 | ||
|
|
ea6c4cb5d0 | ||
|
|
5d5bccf948 | ||
|
|
0fc01c2b28 | ||
|
|
4cfa562b9d | ||
|
|
006be5d599 | ||
|
|
eb6177d7f3 | ||
|
|
32386575c9 | ||
|
|
518ae6733a | ||
|
|
a08f588d43 | ||
|
|
91c09d638f | ||
|
|
61a66bf489 | ||
|
|
a12417d9cc | ||
|
|
fe94d07dfe | ||
|
|
cf68e23974 | ||
|
|
d42e2ac3a5 | ||
|
|
f0afa64416 | ||
|
|
df54f783f7 | ||
|
|
fe9ffbf0ac | ||
|
|
ebf9bc3051 | ||
|
|
3f42d7a61d | ||
|
|
1a97251e27 | ||
|
|
79b7ed2d7d | ||
|
|
9f72091043 | ||
|
|
33f3a347cc | ||
|
|
be2a7a9f15 | ||
|
|
8cd13848bd | ||
|
|
cfacb41674 | ||
|
|
85b2cb15b5 | ||
|
|
f1daea79f7 | ||
|
|
63825ee9ee | ||
|
|
e93fe8d03e | ||
|
|
f643978a5e | ||
|
|
486ed20d32 | ||
|
|
af65d0828a | ||
|
|
b20b3c0f0a | ||
|
|
be1eb3b291 | ||
|
|
ba61a56561 | ||
|
|
dee71eecd7 | ||
|
|
f18451fc4d | ||
|
|
2fbfdf7973 | ||
|
|
af809ad0e8 | ||
|
|
04a1901d2b | ||
|
|
9ebf0bb363 | ||
|
|
9a680f27a4 | ||
|
|
37fc756875 | ||
|
|
1d7fdf42d5 | ||
|
|
331cf8816e | ||
|
|
3ffe77f006 | ||
|
|
6f28e06a35 | ||
|
|
3c573510a5 | ||
|
|
0a84fe593d | ||
|
|
7143d13f7a | ||
|
|
20871acb55 | ||
|
|
934cfdc3af | ||
|
|
30fc65fcff | ||
|
|
b76ac03598 | ||
|
|
66bd7a276e | ||
|
|
80e4350eb7 | ||
|
|
46c6dc3930 | ||
|
|
49258593c2 | ||
|
|
9048b59333 | ||
|
|
61b15d7442 | ||
|
|
4a9fc1026a | ||
|
|
0a58e59150 | ||
|
|
39b497cac3 | ||
|
|
6784b2bcd5 | ||
|
|
1c8a5db010 | ||
|
|
e594d27cc1 | ||
|
|
6beea28f56 | ||
|
|
9d8fef2220 | ||
|
|
4744aa3198 | ||
|
|
be24aaa0a1 | ||
|
|
0169728ddd | ||
|
|
7c673ae5bd | ||
|
|
8de1c4b21b | ||
|
|
f5b7501417 | ||
|
|
02ba857c69 | ||
|
|
612a25f50c | ||
|
|
6bfec37fa8 | ||
|
|
b532e28ec4 | ||
|
|
a340a4e46e | ||
|
|
0c4ca580d2 | ||
|
|
84fccb592d | ||
|
|
015021d57e | ||
|
|
a760a14e2a | ||
|
|
10fd8a09c7 | ||
|
|
d8339602d9 | ||
|
|
6cb0dbe54a | ||
|
|
efa1d4d133 | ||
|
|
07fa97b94c | ||
|
|
462c49d646 | ||
|
|
caea2e34a4 | ||
|
|
cffeb16104 | ||
|
|
4de860ec89 | ||
|
|
be24e32da9 | ||
|
|
26550d1cf2 | ||
|
|
a87e533ba8 | ||
|
|
4943500058 | ||
|
|
83a9fd42e0 | ||
|
|
8cbe713ab8 | ||
|
|
dbdde2ec8c | ||
|
|
1aed045de7 | ||
|
|
11f15798f9 | ||
|
|
171489153d | ||
|
|
f786a25b36 | ||
|
|
23f45235de | ||
|
|
a302c3fc68 | ||
|
|
9abba6b1fe | ||
|
|
6e25e6a991 | ||
|
|
0c7e7817cb | ||
|
|
2981e2e95f | ||
|
|
0fc8a5214f | ||
|
|
15e2bfd250 | ||
|
|
e46b00991d | ||
|
|
84d16f970e | ||
|
|
c934e026b5 | ||
|
|
0d85e9abbe | ||
|
|
d91272f280 | ||
|
|
07bcc8c055 | ||
|
|
89d71691d6 | ||
|
|
1c89a6c4db | ||
|
|
907878d606 | ||
|
|
1145b0414f | ||
|
|
2d08f86958 | ||
|
|
aeda8e0c8f | ||
|
|
89d549c8a4 | ||
|
|
61be3bd1a5 | ||
|
|
fd9f46a645 | ||
|
|
f09dc866f8 | ||
|
|
42739580e4 | ||
|
|
6a3e623b52 | ||
|
|
35f3554109 | ||
|
|
882dfb5f97 | ||
|
|
54b813ad69 | ||
|
|
f5b9366999 | ||
|
|
704e2f4a8c | ||
|
|
7a7f2c9110 | ||
|
|
1387ecef6c | ||
|
|
b64bda7e4e | ||
|
|
83458426ac | ||
|
|
f48dbc09ae | ||
|
|
abf766af80 | ||
|
|
e07f7c4456 | ||
|
|
c0a5cb07cd | ||
|
|
d6e333f014 | ||
|
|
06a453e18a | ||
|
|
f8798d686d | ||
|
|
01d17d8694 | ||
|
|
4b05708daf | ||
|
|
2c780ab1cc | ||
|
|
b7529b8a85 | ||
|
|
a815e3ede2 | ||
|
|
9eb8a740a3 | ||
|
|
7904cae9c1 | ||
|
|
8af11f1f89 | ||
|
|
7648859a27 | ||
|
|
a4ce828d40 | ||
|
|
a80ec4787e | ||
|
|
0449ba7f91 | ||
|
|
7840d64d2e | ||
|
|
b45ed8719c | ||
|
|
87304cbcf4 | ||
|
|
7942604c22 | ||
|
|
c86be32b6d | ||
|
|
a3d232f053 | ||
|
|
7e538b88fb | ||
|
|
e8f65b958d | ||
|
|
87b9f2f660 | ||
|
|
56bb35d9fe | ||
|
|
2edb9c4761 | ||
|
|
61b585ab41 | ||
|
|
725eba3378 | ||
|
|
4bf4384846 | ||
|
|
4db0d07177 | ||
|
|
58dc5049a5 | ||
|
|
4db6f0721c | ||
|
|
fd0ecca4c9 | ||
|
|
f21f5fd45b | ||
|
|
9196bc7a53 | ||
|
|
da3239c336 | ||
|
|
b94341c4e0 | ||
|
|
30547ae02c | ||
|
|
941ec097bb | ||
|
|
a5db2f0f2d | ||
|
|
adf6ed9c8c | ||
|
|
6020bd5261 | ||
|
|
c69a410012 | ||
|
|
d8d868db6c | ||
|
|
687a62fb1e | ||
|
|
86300427dc | ||
|
|
cbf12758c2 | ||
|
|
3c60c55476 | ||
|
|
963fe19abf | ||
|
|
cad3e23b08 | ||
|
|
6a6313c429 | ||
|
|
7ba0310a58 | ||
|
|
ba7a0fa4ec | ||
|
|
6af07b800a | ||
|
|
16a96dccf0 | ||
|
|
a33c5f1713 | ||
|
|
da23381ff6 | ||
|
|
6692c3ffb8 | ||
|
|
931b3c07af | ||
|
|
b994682736 | ||
|
|
896d597adf | ||
|
|
e0dee8cfae | ||
|
|
71f1b7f424 | ||
|
|
8a1a8309e3 | ||
|
|
8949ed717b | ||
|
|
813c6a25a1 | ||
|
|
4bce69b69a | ||
|
|
0138827492 | ||
|
|
2fa98e031c | ||
|
|
2e81c7c0cd | ||
|
|
737c8d4944 | ||
|
|
cc125f1d13 | ||
|
|
e03df25be9 | ||
|
|
572c858935 | ||
|
|
c7dc2570b4 | ||
|
|
ae4e0330cc | ||
|
|
ed211b44d7 | ||
|
|
5175d55adc | ||
|
|
881e1c37fd | ||
|
|
4e25f20c82 | ||
|
|
559a9def5b | ||
|
|
d9b5d7744c | ||
|
|
79a0fc780e | ||
|
|
e8980a7bda | ||
|
|
b575737c0c | ||
|
|
1d04e5f7f8 | ||
|
|
9adf8a7aa9 | ||
|
|
91262682c1 | ||
|
|
c4e72db390 | ||
|
|
8a2ff86c87 | ||
|
|
df4df2f493 | ||
|
|
4764977c3c | ||
|
|
7f081efbc6 | ||
|
|
3b2d5e5a4f | ||
|
|
df12d488fb | ||
|
|
63013e1060 | ||
|
|
42426a986c | ||
|
|
b526cb5372 | ||
|
|
6a29794a65 | ||
|
|
b6c07f0fe9 | ||
|
|
5421f5e9ae | ||
|
|
85d00d8daa | ||
|
|
8dd3bb07f8 | ||
|
|
ceafbca0a2 | ||
|
|
f53f40396b | ||
|
|
e263c1add8 | ||
|
|
4ec321d1b9 | ||
|
|
c5dcb7e662 | ||
|
|
6600250f30 | ||
|
|
cb5c0d3a12 | ||
|
|
14abc49237 | ||
|
|
dfe06c6dfb | ||
|
|
a74775d5f0 | ||
|
|
378a13ba18 | ||
|
|
f30c415cdd | ||
|
|
95c0b90cc1 | ||
|
|
e7322c8472 | ||
|
|
357364ab25 | ||
|
|
d09ccd4b31 | ||
|
|
1d58ccdf42 | ||
|
|
3a8fbb7be4 | ||
|
|
c9694d4004 | ||
|
|
a19c901e99 | ||
|
|
4a6d2da209 | ||
|
|
613558774b | ||
|
|
34f18da855 | ||
|
|
d95911ec38 | ||
|
|
ea48d2802c | ||
|
|
3e666077f0 | ||
|
|
23cd758ddb | ||
|
|
5e0d95c4ec | ||
|
|
2cd1cdcb7d | ||
|
|
5760e37dcc | ||
|
|
f45612fb2f | ||
|
|
3706b3863a | ||
|
|
1ffa3be4a7 | ||
|
|
2ec62e3a98 | ||
|
|
86c913dbe9 | ||
|
|
4a82ad3937 | ||
|
|
7307bf1b87 | ||
|
|
eae386d0db | ||
|
|
36620e1c5b | ||
|
|
e86d1ac95d | ||
|
|
9a7b82d61f | ||
|
|
4c3bd860f4 | ||
|
|
e83bdf62ca | ||
|
|
ce52121050 | ||
|
|
4f17f383ec | ||
|
|
84c96bf5bf | ||
|
|
56766719df | ||
|
|
3004d86dc1 | ||
|
|
98c7d289ee | ||
|
|
37b47b8e47 | ||
|
|
10a7eacc98 | ||
|
|
15adb64dd7 | ||
|
|
3f7cc13ed7 | ||
|
|
6aacb06c73 | ||
|
|
c41f10f4b8 | ||
|
|
692f86bbd0 | ||
|
|
02138399ce | ||
|
|
42986bf1e5 | ||
|
|
9d80953a63 | ||
|
|
f11250cd36 | ||
|
|
857bdf65e5 | ||
|
|
8ca1efd91a | ||
|
|
b8d1ff5e95 | ||
|
|
db3dcc9a79 | ||
|
|
774a3c1446 | ||
|
|
1bca6d0ffe | ||
|
|
9c60abcaca | ||
|
|
4b11e8cb54 | ||
|
|
401c940434 | ||
|
|
1cbdfcc493 | ||
|
|
a48e682e38 | ||
|
|
6250918dfa | ||
|
|
072d5233ca | ||
|
|
29f5ad6638 | ||
|
|
5abf384c96 | ||
|
|
d39c0cc281 | ||
|
|
8af15bf448 | ||
|
|
c2986c0a1f | ||
|
|
e8fc27da7d | ||
|
|
361d28e19e | ||
|
|
bfc3931d3f | ||
|
|
18ff22aa09 | ||
|
|
ff94a5202c | ||
|
|
c7d8cc928f | ||
|
|
c607d8ff68 | ||
|
|
e1ff84516f | ||
|
|
654d6ee594 | ||
|
|
a46c30eda4 | ||
|
|
73298a6c3d | ||
|
|
b10767a122 | ||
|
|
42773d22fd | ||
|
|
9f2ed0f58d | ||
|
|
c90831775f | ||
|
|
f664eb04d1 | ||
|
|
8fe62b75ca | ||
|
|
64169e7d12 | ||
|
|
12a29f1a43 | ||
|
|
02ee80201b | ||
|
|
1ee0f9455f | ||
|
|
df86f46efe | ||
|
|
30ed610950 | ||
|
|
18b5d7e5ab | ||
|
|
89afc96bf0 | ||
|
|
6dde1b7b80 | ||
|
|
c3bf2a0685 | ||
|
|
f6015c29d5 | ||
|
|
c278dcb707 | ||
|
|
abb114475f | ||
|
|
533d90b4c2 | ||
|
|
83bf77e2f4 | ||
|
|
c27d9d9d4e | ||
|
|
a64139690b | ||
|
|
9122ec43e1 | ||
|
|
4d80587594 | ||
|
|
cf1b95cc00 | ||
|
|
a05b99e0dc | ||
|
|
8b6b623b64 | ||
|
|
4f4b4fa9d5 | ||
|
|
6349f6835d | ||
|
|
05c1463691 | ||
|
|
00c3f795a2 | ||
|
|
8db70b4aa8 | ||
|
|
439bdc0b77 | ||
|
|
82bdc66e34 | ||
|
|
7313da42b5 | ||
|
|
570cb25d26 | ||
|
|
db91841915 | ||
|
|
50664c43b2 | ||
|
|
c1e5f01d2e | ||
|
|
f28e3cbc07 | ||
|
|
4f6b6d3391 | ||
|
|
d6fb966ea4 | ||
|
|
df5c9c8804 | ||
|
|
3c443ae9d7 | ||
|
|
96b77c11ec | ||
|
|
f0462244ec | ||
|
|
2f73a62737 | ||
|
|
042c0109a9 | ||
|
|
4bb656c36d | ||
|
|
471013f7e0 | ||
|
|
51e29d6d95 | ||
|
|
3f0c737969 | ||
|
|
8599f73019 | ||
|
|
6fbf2675e6 | ||
|
|
f97748d46f | ||
|
|
8890627f6d | ||
|
|
867a237c27 | ||
|
|
044cadbad3 | ||
|
|
dda1af6e55 | ||
|
|
cea8c51527 | ||
|
|
5fb9aaa377 | ||
|
|
75724791fa | ||
|
|
d5938abf79 | ||
|
|
58ed22461f | ||
|
|
ed84e5aef3 | ||
|
|
f8310c4a67 | ||
|
|
03006a109b | ||
|
|
3d542b2530 | ||
|
|
9f3bde6096 | ||
|
|
7d4bb5de1f | ||
|
|
a26408bf24 | ||
|
|
e4d61154f2 | ||
|
|
cea310d5c5 | ||
|
|
f2f9d92131 | ||
|
|
4c248f40aa | ||
|
|
b92def7b01 | ||
|
|
0ddcbfa751 | ||
|
|
94defe35cc | ||
|
|
0b48653ed0 | ||
|
|
1ce0434373 | ||
|
|
bc58f4b9ba | ||
|
|
2c3af8a18e | ||
|
|
39c6b2f904 | ||
|
|
e5b4d2e01a | ||
|
|
3fc09372f1 | ||
|
|
6685ca4771 | ||
|
|
1b5a77eba9 | ||
|
|
398a428e08 | ||
|
|
8fffb9d172 | ||
|
|
d323962e14 | ||
|
|
d6c52407fc | ||
|
|
62444346c1 | ||
|
|
4c4acd8d2f | ||
|
|
7e5ac34be7 | ||
|
|
887ff7d685 | ||
|
|
43dc03659e | ||
|
|
863da69c5b | ||
|
|
fb4b035105 | ||
|
|
04ed861eb8 | ||
|
|
4e55490602 | ||
|
|
7ee102a9f6 | ||
|
|
70a9e72e06 | ||
|
|
9cfd94a9d6 | ||
|
|
48416c38c8 | ||
|
|
beb8347faa | ||
|
|
450118fdf8 | ||
|
|
1e1450bf5d | ||
|
|
3567b1d0ce | ||
|
|
2f14aeee00 | ||
|
|
42383518b8 | ||
|
|
fb15403515 | ||
|
|
8a20519222 | ||
|
|
4e33313a9b | ||
|
|
98ed70cd91 | ||
|
|
c6ee38eb69 | ||
|
|
ed1771c7cc | ||
|
|
1bd674dc64 | ||
|
|
285a0aa13c | ||
|
|
a019517d07 | ||
|
|
f57d5db86d | ||
|
|
57118e2f10 | ||
|
|
03527e840c | ||
|
|
ba0974b101 | ||
|
|
191cad0398 | ||
|
|
454268da00 | ||
|
|
5e048a9ebb | ||
|
|
ce83031571 | ||
|
|
298aafd112 | ||
|
|
f8f96c368b | ||
|
|
83bd616b6f | ||
|
|
6743820bce | ||
|
|
3e06ad6af9 | ||
|
|
1c6b0bf925 | ||
|
|
ef2bf23862 | ||
|
|
cf5dbadf4f | ||
|
|
72c88db3a8 | ||
|
|
cfe10825cf | ||
|
|
be115ec3ab | ||
|
|
dbfe5b5886 | ||
|
|
e94b130ede | ||
|
|
5412ccbcb1 | ||
|
|
fa9e6713ae | ||
|
|
2ccfa6bd44 | ||
|
|
188f86e946 | ||
|
|
6220de03da | ||
|
|
31716a4960 | ||
|
|
10cac76d79 | ||
|
|
778566042b | ||
|
|
0e2eccfad0 | ||
|
|
b26ded717f | ||
|
|
85825377c8 | ||
|
|
10419b48bf | ||
|
|
fa8c79e0fe | ||
|
|
38edc33bb8 | ||
|
|
c6750d271e | ||
|
|
63a9054e5b | ||
|
|
9699ec9277 | ||
|
|
15ac1d40fa | ||
|
|
8f4ec72a0f | ||
|
|
02668b62e8 | ||
|
|
36b65c8498 | ||
|
|
91bc4ebb6c | ||
|
|
205c484c49 | ||
|
|
60f4ccf303 | ||
|
|
1d0df04579 | ||
|
|
50d4ffd22e | ||
|
|
9845219a5f | ||
|
|
b4939b1121 | ||
|
|
8c1d9e70b5 | ||
|
|
e444a31e79 | ||
|
|
c3bd2a7539 | ||
|
|
3a9c713748 | ||
|
|
6a63d0eeaf | ||
|
|
570e32915a | ||
|
|
8ad6ba2436 | ||
|
|
7fe18ef334 | ||
|
|
126ade78d4 | ||
|
|
608986cd4f | ||
|
|
fe05db83f1 | ||
|
|
d1936acf43 | ||
|
|
7ce22b11bf | ||
|
|
b917fbe914 | ||
|
|
beb80ffeeb | ||
|
|
fc6235c190 | ||
|
|
92a27d642b | ||
|
|
9bc10d9eda | ||
|
|
357239a20c | ||
|
|
014b3c639f | ||
|
|
505663cd6b | ||
|
|
2dc384198d | ||
|
|
e1dcd81c18 | ||
|
|
9f653a9d9f | ||
|
|
b0c389c450 | ||
|
|
faeb15e1ec | ||
|
|
cbd1e9fa35 | ||
|
|
e105d23b51 | ||
|
|
6cc626ab99 | ||
|
|
e70fc19384 | ||
|
|
935501896d | ||
|
|
e690cfcbd7 | ||
|
|
6f582fe71d | ||
|
|
7116547ebf | ||
|
|
df53422cad | ||
|
|
014b6ba44a | ||
|
|
a663c61427 | ||
|
|
ed1304146b | ||
|
|
1937bc2bd7 | ||
|
|
1255be4e3e | ||
|
|
3e7a5b144a | ||
|
|
763c2cc188 | ||
|
|
7ca260554f | ||
|
|
4e9b4cb9cc | ||
|
|
efe9100306 | ||
|
|
ac62b8437d | ||
|
|
9969b4218d | ||
|
|
02c3097191 | ||
|
|
db256ed1e1 | ||
|
|
270f105823 | ||
|
|
44811c6896 | ||
|
|
d8c9530d3c | ||
|
|
152a4f46d6 | ||
|
|
b4552c02d4 | ||
|
|
3c87f47ba2 | ||
|
|
a0eedf112f | ||
|
|
a9dae85d03 | ||
|
|
a18f92b09b | ||
|
|
6a418013a3 | ||
|
|
bd9eb5255d | ||
|
|
29da5b2e17 | ||
|
|
1c4bbaa567 | ||
|
|
ad9bce3203 | ||
|
|
129f1df461 | ||
|
|
2b58be5a6c | ||
|
|
ee99795f3d | ||
|
|
f4b64a491b | ||
|
|
b5371b38c9 | ||
|
|
07e8b35ead | ||
|
|
76f98a4b36 | ||
|
|
0b3fdf420f | ||
|
|
a7d37b303d | ||
|
|
a7b5496770 | ||
|
|
ce5b2709ab | ||
|
|
a617116479 | ||
|
|
4070d095d0 | ||
|
|
3387d751d9 | ||
|
|
155e48bbde | ||
|
|
13155223f3 | ||
|
|
61ecee012e | ||
|
|
ab8e4069b5 | ||
|
|
34064b4302 | ||
|
|
93fcc418fe | ||
|
|
6393ef0f52 | ||
|
|
f00c6d1e84 | ||
|
|
2aea6e5e9c | ||
|
|
47a9e032d8 | ||
|
|
a27e0357b8 | ||
|
|
c229de0564 | ||
|
|
f298897fb5 | ||
|
|
ab2062aa45 | ||
|
|
3892fd2c09 | ||
|
|
87f810dca1 | ||
|
|
868da0741c | ||
|
|
09b2cd7d26 | ||
|
|
f3cf5711bf | ||
|
|
ddbb535080 | ||
|
|
195f7274c4 | ||
|
|
cdd3131f8a | ||
|
|
37c9b4056a | ||
|
|
dfd46965ae | ||
|
|
e885ff235f | ||
|
|
845bbc293a | ||
|
|
50f8b7b783 | ||
|
|
c4193d5ec1 | ||
|
|
8e0bb3ec81 | ||
|
|
41caedd0da | ||
|
|
13d4e43888 | ||
|
|
b837e64640 | ||
|
|
26e7d01d42 | ||
|
|
bbd0696992 | ||
|
|
d4eab2602f | ||
|
|
dbd225c673 | ||
|
|
da8835aa0b | ||
|
|
8e703b14ee | ||
|
|
79da87def9 | ||
|
|
0ffe9f0c4e | ||
|
|
46fd333167 | ||
|
|
8b50419f55 | ||
|
|
65691de9bc | ||
|
|
3514effcd0 | ||
|
|
f7b9ea8cb5 | ||
|
|
ac124ee89c | ||
|
|
01cfb0d6bd | ||
|
|
69b6eabef0 | ||
|
|
8c16be1edc | ||
|
|
a015072a7e | ||
|
|
7cc2445b9a | ||
|
|
cfef8291bb | ||
|
|
725978b817 | ||
|
|
1e598fc6db | ||
|
|
08c14389f6 | ||
|
|
35769b6c50 | ||
|
|
2aa9a21180 | ||
|
|
acdc7b0511 | ||
|
|
3b92e85b30 | ||
|
|
7d6b82673f | ||
|
|
12e5f25a1c | ||
|
|
539064b93c | ||
|
|
82e69475ca | ||
|
|
d09342957d | ||
|
|
7a05ef2002 | ||
|
|
6a6fccc191 | ||
|
|
9c41962e68 | ||
|
|
a7372d5828 | ||
|
|
3850f82259 | ||
|
|
3f64b39ad5 | ||
|
|
536549253d | ||
|
|
d1d2ce8c28 | ||
|
|
7ad26f30f0 | ||
|
|
97610cfccf | ||
|
|
143c0bdaf9 | ||
|
|
9ec43e1721 | ||
|
|
e5f2f1ba78 | ||
|
|
89ee65e1c6 | ||
|
|
4eb20f4d99 | ||
|
|
55d7900079 | ||
|
|
4b5cf90a95 | ||
|
|
9edde5e8af | ||
|
|
67ad5852f6 | ||
|
|
5641ff1b42 | ||
|
|
7778b9d83a | ||
|
|
afeaf64624 | ||
|
|
6159788b97 | ||
|
|
695b25775e | ||
|
|
ccddd3bc01 | ||
|
|
e982c25b40 | ||
|
|
7707b9fc91 | ||
|
|
f97e2d3bde | ||
|
|
93f04b87b2 | ||
|
|
d444469cae | ||
|
|
64b41b5602 | ||
|
|
b26b1389de | ||
|
|
3cf2f09469 | ||
|
|
fb30315d01 | ||
|
|
027e081622 | ||
|
|
84b4916fb8 | ||
|
|
27023a77e7 | ||
|
|
1a3db605c2 | ||
|
|
712b9374af | ||
|
|
06321a5241 | ||
|
|
b9f10a71ea | ||
|
|
97219eeb31 | ||
|
|
a2f2cd3b41 | ||
|
|
bbad487deb | ||
|
|
7930cfdba9 | ||
|
|
68a9d1168f | ||
|
|
1755fba8dc | ||
|
|
d7615df616 | ||
|
|
541e02a7e3 | ||
|
|
d899bf029d | ||
|
|
f11ac037c4 | ||
|
|
0846615e98 | ||
|
|
f16b3754fb | ||
|
|
862b7b22b5 | ||
|
|
e353d09630 | ||
|
|
5205b31186 | ||
|
|
de0a323bef | ||
|
|
39f97ee0d0 | ||
|
|
ebdc82d3d2 | ||
|
|
773d282d71 | ||
|
|
fc7ff2a59c | ||
|
|
c4ce84bba5 | ||
|
|
315f18766c | ||
|
|
9ad19e8122 | ||
|
|
75fcd062e8 | ||
|
|
b7fde00aed | ||
|
|
d6547595d7 | ||
|
|
5bb12070d9 | ||
|
|
83b8f38484 | ||
|
|
bdb65ed066 | ||
|
|
cbb5b6f50b | ||
|
|
cc0a73c156 | ||
|
|
1d4ae1e9ad | ||
|
|
e14b836fcc | ||
|
|
fbcfc869e2 | ||
|
|
4107361a3a | ||
|
|
e8aa442305 | ||
|
|
82ee078d9a | ||
|
|
f90512ba39 | ||
|
|
bb48077a81 | ||
|
|
72f9d15a57 | ||
|
|
78dca32a28 | ||
|
|
52a70b3418 | ||
|
|
889c80ec1c | ||
|
|
922bae0be3 | ||
|
|
982a7fa499 | ||
|
|
52413e9925 | ||
|
|
cfb96e67f9 | ||
|
|
a7c67c1681 | ||
|
|
53d75901a9 | ||
|
|
8f665c3393 | ||
|
|
b5365c19f7 | ||
|
|
738afe2de3 | ||
|
|
ea3b2716fd | ||
|
|
bfcb673c8e | ||
|
|
e5d8a68d96 | ||
|
|
760772ec4b | ||
|
|
1a9d40ca3d | ||
|
|
9773c019d8 | ||
|
|
67ef1865a6 | ||
|
|
3db38f8281 | ||
|
|
c6d2fc6807 | ||
|
|
9237110c5c | ||
|
|
4c240064ab | ||
|
|
da4108dd1e | ||
|
|
01994059e2 | ||
|
|
763fa9b0fa | ||
|
|
a55c7a62ad | ||
|
|
0e1f561a32 | ||
|
|
cea4d31325 | ||
|
|
af86b9cbce | ||
|
|
f16e78f72c | ||
|
|
bc8540fec1 | ||
|
|
533c5e98e8 | ||
|
|
d04718bbe3 | ||
|
|
7edf2bf66c | ||
|
|
a05868f0a8 | ||
|
|
5b1d8d64f2 | ||
|
|
031ec7af93 | ||
|
|
2a5802241f | ||
|
|
f6f4d7b410 | ||
|
|
8e20c13348 | ||
|
|
f617a33b8d | ||
|
|
782ab8d872 | ||
|
|
b3697e7741 | ||
|
|
da3c1be049 | ||
|
|
35785d08fd | ||
|
|
05fbfe21b9 | ||
|
|
4fc1587f6c | ||
|
|
297945c32e | ||
|
|
d193895ec6 | ||
|
|
f1bf446410 | ||
|
|
e6a0eb74c8 | ||
|
|
b3189bae38 | ||
|
|
c27c381ba2 | ||
|
|
95c5805088 | ||
|
|
196793dccb | ||
|
|
7c6d447938 | ||
|
|
7d847e60ec | ||
|
|
b069b31a2c | ||
|
|
969161183a | ||
|
|
45e29a817c | ||
|
|
dabebbf639 | ||
|
|
cd78dc632a | ||
|
|
33b3418b4e | ||
|
|
6a2f492832 | ||
|
|
24a03a8d3f | ||
|
|
27ffeacf07 | ||
|
|
b1da63d645 | ||
|
|
ec3a1318dc | ||
|
|
22da5f6de9 | ||
|
|
0ec9d3ec7d | ||
|
|
70764a4cf9 | ||
|
|
2ad5686937 | ||
|
|
84d10d8dad | ||
|
|
7f8de47631 | ||
|
|
16add00668 | ||
|
|
a83c918946 | ||
|
|
9f791e06f6 | ||
|
|
c3ba237846 | ||
|
|
17c4a76395 | ||
|
|
114b16f0d5 | ||
|
|
e1fc259600 | ||
|
|
1d537d29d5 | ||
|
|
09f5854c9a | ||
|
|
200d8d235b | ||
|
|
84a32f3288 | ||
|
|
bfc8142c99 | ||
|
|
bcebf3e6f1 | ||
|
|
4577270fc3 | ||
|
|
2d22fbd4ff | ||
|
|
9f6af0ad4b | ||
|
|
c060853f70 | ||
|
|
501d81ce32 | ||
|
|
f9a770134b | ||
|
|
b4fc5b0e8f | ||
|
|
a821805ddc | ||
|
|
cb9fa1f295 | ||
|
|
7ffd68cac2 | ||
|
|
dd77a4c65d | ||
|
|
a47cc3dd46 | ||
|
|
7cd75f30f2 | ||
|
|
3d2cd911f0 | ||
|
|
da94560ec5 | ||
|
|
21ef7ed82c | ||
|
|
125da7a1c2 | ||
|
|
ceca7b741c | ||
|
|
ab95d5cdd7 | ||
|
|
bc6a193130 | ||
|
|
7cc5888583 | ||
|
|
0743361da3 | ||
|
|
c16fbbf614 | ||
|
|
b64815be4c | ||
|
|
885df4c90f | ||
|
|
d376105e8e | ||
|
|
7f50bb7e7f | ||
|
|
53509c7bfd | ||
|
|
1bbe9538ef | ||
|
|
39dd71d958 | ||
|
|
2dfe58e1b3 | ||
|
|
2e60a4b751 | ||
|
|
fc18d2cea5 | ||
|
|
8b6060e24e | ||
|
|
640f690def | ||
|
|
cce9fa970e | ||
|
|
f63ab0792b | ||
|
|
f4c8df2635 | ||
|
|
db5c542e96 | ||
|
|
bb8ecf8a7b | ||
|
|
c2e424e7af | ||
|
|
a0191b28b2 | ||
|
|
fa8dc32800 | ||
|
|
cf3e89c1b2 | ||
|
|
08b9551494 | ||
|
|
92b29923cb | ||
|
|
695d95c983 | ||
|
|
d91c425178 | ||
|
|
0da8e99580 | ||
|
|
c6b4fa5a9a | ||
|
|
281877ada5 | ||
|
|
9a273863ba | ||
|
|
abbc13af62 | ||
|
|
9fb746824a | ||
|
|
8a1adb0d50 | ||
|
|
ddb2570849 | ||
|
|
7f4b77ca5b | ||
|
|
d421663d3f | ||
|
|
c455d6f2a0 | ||
|
|
b3eee7d58f | ||
|
|
271e2f9419 | ||
|
|
70f15bd28e | ||
|
|
607a1abefd | ||
|
|
8122f7162c | ||
|
|
cd31a5e3c6 | ||
|
|
8a6c1df041 | ||
|
|
7e02cd3498 | ||
|
|
ef30229e52 | ||
|
|
6ee884c861 | ||
|
|
002189cd1a | ||
|
|
fbe792f33f | ||
|
|
b88ae6c39f | ||
|
|
45d7039623 | ||
|
|
d9a1b5faae | ||
|
|
b2901d7e2f | ||
|
|
a3b5a23b87 | ||
|
|
eaa48f380a | ||
|
|
78c083325f | ||
|
|
a8d34b8e20 | ||
|
|
66e7027e7a | ||
|
|
6210272bfd | ||
|
|
57ed12a019 | ||
|
|
a4270573e7 | ||
|
|
ae5cb25f11 | ||
|
|
bf76c1bc1a | ||
|
|
cb05e152b9 | ||
|
|
f999688f2c | ||
|
|
762c5fe996 | ||
|
|
ac19aef689 | ||
|
|
d88b705562 | ||
|
|
7d9d4d16e5 | ||
|
|
1e92ad77c4 | ||
|
|
e136fb7e18 | ||
|
|
4225b9794f | ||
|
|
76b9e36f2b | ||
|
|
b490f05b95 | ||
|
|
c7ca7872cb | ||
|
|
97655e05b5 | ||
|
|
512e4d5836 | ||
|
|
9d8a85e2ab | ||
|
|
8a940ccd65 | ||
|
|
c983bc4d12 | ||
|
|
b8582d977d | ||
|
|
c4ffb39ccc | ||
|
|
485ed4cc22 | ||
|
|
d4e38152ef | ||
|
|
e5abec310d | ||
|
|
2c483a6b52 | ||
|
|
bf281b31ec | ||
|
|
3c359763da | ||
|
|
f81e71f622 | ||
|
|
a1dadda7d6 | ||
|
|
cfde037f9a | ||
|
|
3fcc3689ce | ||
|
|
497b123958 | ||
|
|
7995ba6433 | ||
|
|
5019ff3345 | ||
|
|
b270638868 | ||
|
|
3576a634c7 | ||
|
|
d8a1080bdf | ||
|
|
c209efa4e2 | ||
|
|
d78452ed29 | ||
|
|
acb3b6fee2 | ||
|
|
c237beff1d | ||
|
|
34a4a96ded | ||
|
|
2ef6bcaedd | ||
|
|
1928a4a638 | ||
|
|
d85b1fb091 | ||
|
|
970502f904 | ||
|
|
d3cb687936 | ||
|
|
b28db50786 | ||
|
|
7999c06f68 | ||
|
|
490d7cbba9 | ||
|
|
a8b92d560b | ||
|
|
1884151ca8 | ||
|
|
b86c8b3260 | ||
|
|
2d31597fa9 | ||
|
|
715dfac07e | ||
|
|
bf72ed92a9 | ||
|
|
146a959706 | ||
|
|
fa9c836f02 | ||
|
|
609e39a620 | ||
|
|
3956fe30c0 | ||
|
|
831e8d653f | ||
|
|
35a3ef6892 | ||
|
|
5637424aff | ||
|
|
0fc888cf78 | ||
|
|
b37f08f961 | ||
|
|
62682a681a | ||
|
|
3e2d5f6292 | ||
|
|
e9112a9489 | ||
|
|
e00d9425da | ||
|
|
3eaf8f1a84 | ||
|
|
ef38eb0323 | ||
|
|
c6be772242 | ||
|
|
c892c96f9a | ||
|
|
7f2edf8528 | ||
|
|
9b6769411a | ||
|
|
e55f55531c | ||
|
|
0f665dfb0d | ||
|
|
b2f1dd6a16 | ||
|
|
989396ef27 | ||
|
|
b3a2f85c70 | ||
|
|
bd768edca2 | ||
|
|
fdf61f7c45 | ||
|
|
ccd431c7ed | ||
|
|
e1e4e08fa8 | ||
|
|
f8b191cfae | ||
|
|
487ae78235 | ||
|
|
4314b00289 | ||
|
|
650e1f79d1 | ||
|
|
b87c822d59 | ||
|
|
90c6ea59a6 | ||
|
|
7fbfb0fc9b | ||
|
|
447890247a | ||
|
|
d360f6d95d | ||
|
|
7edc392d7c | ||
|
|
071f7cdb49 | ||
|
|
89b423658a | ||
|
|
6d0a9fe95e | ||
|
|
afdc73c8ab | ||
|
|
1dc9be01c4 | ||
|
|
cffd28ad83 | ||
|
|
f4c57eb764 | ||
|
|
346d6b0eaa | ||
|
|
0a357a4838 | ||
|
|
76a46a0f68 | ||
|
|
8dbf96a471 | ||
|
|
60080d4893 | ||
|
|
3716e3e8c4 | ||
|
|
0b1c461e63 | ||
|
|
ec73cebb59 | ||
|
|
ce634ef221 | ||
|
|
af2a6ee826 | ||
|
|
2a581e3fab | ||
|
|
7b0a926574 | ||
|
|
f2c543785b | ||
|
|
ed27e75f50 | ||
|
|
ea30c54cda | ||
|
|
c71c8aea55 | ||
|
|
46001bf6d4 | ||
|
|
3e5053b778 | ||
|
|
0db9b87d66 | ||
|
|
a9aaabae21 | ||
|
|
f43dd79e11 | ||
|
|
dff911da69 | ||
|
|
31ca811240 | ||
|
|
febb0cb3da | ||
|
|
d128ff3ecd | ||
|
|
debe83c3b5 | ||
|
|
5752e4d588 | ||
|
|
66dad0c506 | ||
|
|
fffbcbb78b | ||
|
|
b8937e5522 | ||
|
|
0a2e4967ef | ||
|
|
cbc5ef4bc6 | ||
|
|
aec8dfdc8e | ||
|
|
3ad712ba86 | ||
|
|
b31e16039e | ||
|
|
16bb663c74 | ||
|
|
4bd6486b41 | ||
|
|
1340de576e | ||
|
|
92ea676c38 | ||
|
|
8335933cdf | ||
|
|
f198339ec0 | ||
|
|
f4f563bc7b | ||
|
|
a95678bfcd | ||
|
|
dadfcc35b3 | ||
|
|
7535226679 | ||
|
|
35364c365f | ||
|
|
2d7798e091 | ||
|
|
d945191e08 | ||
|
|
a0014d91b9 | ||
|
|
ebc3df0038 | ||
|
|
85127bcbbd | ||
|
|
364e587b46 | ||
|
|
6752163800 | ||
|
|
ddb05d0719 | ||
|
|
125828edaf | ||
|
|
d7f5c3e55f | ||
|
|
eebbe2d008 | ||
|
|
9ca4dc0626 | ||
|
|
dd73e2a453 | ||
|
|
07b1e2053c | ||
|
|
999f86320e | ||
|
|
3c188abdd7 | ||
|
|
698d3bafa5 | ||
|
|
fcf0324a66 | ||
|
|
3c4c838c2b | ||
|
|
36adefc8a8 | ||
|
|
e8ff79d6b4 | ||
|
|
baa6c19700 | ||
|
|
e3dedb74c5 | ||
|
|
f406174be5 | ||
|
|
5ebb70ecc5 | ||
|
|
8437b63845 | ||
|
|
b17defd6cb | ||
|
|
26e1136fc5 | ||
|
|
6b5a15e3da | ||
|
|
f9affb9fb8 | ||
|
|
21fd581265 | ||
|
|
6c87d104c0 | ||
|
|
7634d9a991 | ||
|
|
c59f7687ca | ||
|
|
0f0833e350 |
@@ -37,7 +37,3 @@ max_line_length = 119
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
max_line_length = 120
|
||||
|
||||
[{*.sh,*.yml,*.yaml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
170
.flake8
170
.flake8
@@ -1,170 +0,0 @@
|
||||
[flake8]
|
||||
|
||||
select =
|
||||
# Full lists are given in order to suppress all errors from other plugins
|
||||
# Full list of pyflakes error codes:
|
||||
F401, # module imported but unused
|
||||
F402, # import module from line N shadowed by loop variable
|
||||
F403, # 'from module import *' used; unable to detect undefined names
|
||||
F404, # future import(s) name after other statements
|
||||
F405, # name may be undefined, or defined from star imports: module
|
||||
F406, # 'from module import *' only allowed at module level
|
||||
F407, # an undefined __future__ feature name was imported
|
||||
F601, # dictionary key name repeated with different values
|
||||
F602, # dictionary key variable name repeated with different values
|
||||
F621, # too many expressions in an assignment with star-unpacking
|
||||
F622, # two or more starred expressions in an assignment (a, *b, *c = d)
|
||||
F631, # assertion test is a tuple, which are always True
|
||||
F701, # a break statement outside of a while or for loop
|
||||
F702, # a continue statement outside of a while or for loop
|
||||
F703, # a continue statement in a finally block in a loop
|
||||
F704, # a yield or yield from statement outside of a function
|
||||
F705, # a return statement with arguments inside a generator
|
||||
F706, # a return statement outside of a function/method
|
||||
F707, # an except: block as not the last exception handler
|
||||
F721, F722, # doctest syntax error syntax error in forward type annotation
|
||||
F811, # redefinition of unused name from line N
|
||||
F812, # list comprehension redefines name from line N
|
||||
F821, # undefined name name
|
||||
F822, # undefined name name in __all__
|
||||
F823, # local variable name referenced before assignment
|
||||
F831, # duplicate argument name in function definition
|
||||
F841, # local variable name is assigned to but never used
|
||||
F901, # raise NotImplemented should be raise NotImplementedError
|
||||
|
||||
# Full list of pycodestyle violations:
|
||||
E101, # indentation contains mixed spaces and tabs
|
||||
E111, # indentation is not a multiple of four
|
||||
E112, # expected an indented block
|
||||
E113, # unexpected indentation
|
||||
E114, # indentation is not a multiple of four (comment)
|
||||
E115, # expected an indented block (comment)
|
||||
E116, # unexpected indentation (comment)
|
||||
E121, # continuation line under-indented for hanging indent
|
||||
E122, # continuation line missing indentation or outdented
|
||||
E123, # closing bracket does not match indentation of opening bracket's line
|
||||
E124, # closing bracket does not match visual indentation
|
||||
E125, # continuation line with same indent as next logical line
|
||||
E126, # continuation line over-indented for hanging indent
|
||||
E127, # continuation line over-indented for visual indent
|
||||
E128, # continuation line under-indented for visual indent
|
||||
E129, # visually indented line with same indent as next logical line
|
||||
E131, # continuation line unaligned for hanging indent
|
||||
E133, # closing bracket is missing indentation
|
||||
E201, # whitespace after '('
|
||||
E202, # whitespace before ')'
|
||||
E203, # whitespace before ':'
|
||||
E211, # whitespace before '('
|
||||
E221, # multiple spaces before operator
|
||||
E222, # multiple spaces after operator
|
||||
E223, # tab before operator
|
||||
E224, # tab after operator
|
||||
E225, # missing whitespace around operator
|
||||
E226, # missing whitespace around arithmetic operator
|
||||
E227, # missing whitespace around bitwise or shift operator
|
||||
E228, # missing whitespace around modulo operator
|
||||
E231, # missing whitespace after ',', ';', or ':'
|
||||
E241, # multiple spaces after ','
|
||||
E242, # tab after ','
|
||||
E251, # unexpected spaces around keyword / parameter equals
|
||||
E261, # at least two spaces before inline comment
|
||||
E262, # inline comment should start with '# '
|
||||
E265, # block comment should start with '# '
|
||||
E266, # too many leading '#' for block comment
|
||||
E271, # multiple spaces after keyword
|
||||
E272, # multiple spaces before keyword
|
||||
E273, # tab after keyword
|
||||
E274, # tab before keyword
|
||||
E275, # missing whitespace after keyword
|
||||
E301, # expected 1 blank line, found 0
|
||||
E302, # expected 2 blank lines, found 0
|
||||
E303, # too many blank lines
|
||||
E304, # blank lines found after function decorator
|
||||
E305, # expected 2 blank lines after end of function or class
|
||||
E306, # expected 1 blank line before a nested definition
|
||||
E401, # multiple imports on one line
|
||||
E402, # module level import not at top of file
|
||||
E501, # line too long (82 > 79 characters)
|
||||
E502, # the backslash is redundant between brackets
|
||||
E701, # multiple statements on one line (colon)
|
||||
E702, # multiple statements on one line (semicolon)
|
||||
E703, # statement ends with a semicolon
|
||||
E704, # multiple statements on one line (def)
|
||||
E711, # comparison to None should be 'if cond is None:'
|
||||
E712, # comparison to True should be 'if cond is True:' or 'if cond:'
|
||||
E713, # test for membership should be 'not in'
|
||||
E714, # test for object identity should be 'is not'
|
||||
E721, # do not compare types, use 'isinstance()'
|
||||
E722, # do not use bare except, specify exception instead
|
||||
E731, # do not assign a lambda expression, use a def
|
||||
E741, # do not use variables named 'l', 'O', or 'I'
|
||||
E742, # do not define classes named 'l', 'O', or 'I'
|
||||
E743, # do not define functions named 'l', 'O', or 'I'
|
||||
E901, # SyntaxError or IndentationError
|
||||
E902, # IOError
|
||||
W191, # indentation contains tabs
|
||||
W291, # trailing whitespace
|
||||
W292, # no newline at end of file
|
||||
W293, # blank line contains whitespace
|
||||
W391, # blank line at end of file
|
||||
W503, # line break before binary operator
|
||||
W504, # line break after binary operator
|
||||
W505, # doc line too long (82 > 79 characters)
|
||||
W601, # .has_key() is deprecated, use 'in'
|
||||
W602, # deprecated form of raising exception
|
||||
W603, # '<>' is deprecated, use '!='
|
||||
W604, # backticks are deprecated, use 'repr()'
|
||||
W605, # invalid escape sequence 'x'
|
||||
W606, # 'async' and 'await' are reserved keywords starting with Python 3.7
|
||||
|
||||
# Full list of flake8 violations
|
||||
E999, # failed to compile a file into an Abstract Syntax Tree for the plugins that require it
|
||||
|
||||
# Full list of mccabe violations
|
||||
C901 # complexity value provided by the user
|
||||
|
||||
ignore =
|
||||
E221, # multiple spaces before operator
|
||||
E231, # missing whitespace after ',', ';', or ':'
|
||||
E241, # multiple spaces after ','
|
||||
W503, # line break before binary operator
|
||||
W504 # line break after binary operator
|
||||
|
||||
max-line-length = 160
|
||||
|
||||
show_source = True
|
||||
|
||||
statistics = True
|
||||
|
||||
exclude =
|
||||
.git,
|
||||
__pycache__,
|
||||
# submodules
|
||||
components/bootloader/subproject/components/micro-ecc/micro-ecc,
|
||||
components/bt/host/nimble/nimble,
|
||||
components/cmock/CMock,
|
||||
components/esptool_py/esptool,
|
||||
components/expat/expat,
|
||||
components/json/cJSON,
|
||||
components/libsodium/libsodium,
|
||||
components/mbedtls/mbedtls,
|
||||
components/nghttp/nghttp2,
|
||||
components/openthread/openthread,
|
||||
components/tinyusb,
|
||||
components/unity/unity,
|
||||
examples/build_system/cmake/import_lib/main/lib/tinyxml2,
|
||||
examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib,
|
||||
# autogenerated scripts
|
||||
components/protocomm/python/constants_pb2.py,
|
||||
components/protocomm/python/sec0_pb2.py,
|
||||
components/protocomm/python/sec1_pb2.py,
|
||||
components/protocomm/python/session_pb2.py,
|
||||
components/wifi_provisioning/python/wifi_scan_pb2.py,
|
||||
components/wifi_provisioning/python/wifi_config_pb2.py,
|
||||
components/wifi_provisioning/python/wifi_constants_pb2.py,
|
||||
components/esp_local_ctrl/python/esp_local_ctrl_pb2.py,
|
||||
examples/provisioning/legacy/custom_config/components/custom_provisioning/python/custom_config_pb2.py,
|
||||
|
||||
per-file-ignores =
|
||||
# Sphinx conf.py files use star imports to setup config variables
|
||||
docs/conf_common.py: F405
|
||||
92
.github/ISSUE_TEMPLATE/bug_report.md
vendored
92
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,92 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: ESP-IDF crashes, produces incorrect output, or has incorrect behavior
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
----------------------------- Delete below -----------------------------
|
||||
|
||||
**Reminder: If your issue is a general question, starts similar to "How do I..", or is related to 3rd party development kits/libs, please discuss this on our community forum at https://esp32.com instead.**
|
||||
|
||||
INSTRUCTIONS
|
||||
============
|
||||
|
||||
Before submitting a new issue, please follow the checklist and try to find the answer.
|
||||
|
||||
- [ ] I have read the documentation [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/latest/) and the issue is not addressed there.
|
||||
- [ ] I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
|
||||
- [ ] I have searched the issue tracker for a similar issue and not found a similar issue.
|
||||
|
||||
If the issue cannot be solved after the steps before, please follow these instructions so we can get the needed information to help you in a quick and effective fashion.
|
||||
|
||||
1. Fill in all the fields under **Environment** marked with [ ] by picking the correct option for you in each case and deleting the others.
|
||||
2. Describe your problem.
|
||||
3. Include [debug logs from the "monitor" tool](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/tools/idf-monitor.html), or [coredumps](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/core_dump.html).
|
||||
4. Providing as much information as possible under **Other items if possible** will help us locate and fix the problem.
|
||||
5. Use [Markdown](https://guides.github.com/features/mastering-markdown/) (see formatting buttons above) and the Preview tab to check what the issue will look like.
|
||||
6. Delete these instructions from the above to the below marker lines before submitting this issue.
|
||||
|
||||
**IMPORTANT: If you do not follow these instructions and provide the necessary details, your issue may not be resolved.**
|
||||
|
||||
----------------------------- Delete above -----------------------------
|
||||
|
||||
## Environment
|
||||
|
||||
- Development Kit: [ESP32-Wrover-Kit|ESP32-DevKitC|ESP32-PICO-Kit|ESP32-LyraT|ESP32-LyraTD-MSC|none]
|
||||
- Kit version (for WroverKit/PicoKit/DevKitC): [v1|v2|v3|v4]
|
||||
- Module or chip used: [ESP32-WROOM-32|ESP32-WROOM-32D|ESP32-WROOM-32U|ESP32-WROVER|ESP32-WROVER-I|ESP32-WROVER-B|ESP32-WROVER-IB|ESP32-SOLO-1|ESP32-PICO-D4|ESP32]
|
||||
- IDF version (run ``git describe --tags`` to find it):
|
||||
// v3.2-dev-1148-g96cd3b75c
|
||||
- Build System: [Make|CMake|idf.py]
|
||||
- Compiler version (run ``xtensa-esp32-elf-gcc --version`` to find it):
|
||||
// 1.22.0-80-g6c4433a
|
||||
- Operating System: [Windows|Linux|macOS]
|
||||
- (Windows only) environment type: [MSYS2 mingw32|ESP Command Prompt|Plain Command Prompt|PowerShell].
|
||||
- Using an IDE?: [No|Yes (please give details)]
|
||||
- Power Supply: [USB|external 5V|external 3.3V|Battery]
|
||||
|
||||
## Problem Description
|
||||
|
||||
//Detailed problem description goes here.
|
||||
|
||||
### Expected Behavior
|
||||
|
||||
### Actual Behavior
|
||||
|
||||
### Steps to reproduce
|
||||
|
||||
1. step1
|
||||
2. ...
|
||||
|
||||
// If possible, attach a picture of your setup/wiring here.
|
||||
|
||||
|
||||
### Code to reproduce this issue
|
||||
|
||||
```cpp
|
||||
// the code should be wrapped in the ```cpp tag so that it will be displayed better.
|
||||
#include "esp_log.h"
|
||||
|
||||
void app_main()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
// If your code is longer than 30 lines, [GIST](https://gist.github.com) is preferred.
|
||||
|
||||
## Debug Logs
|
||||
|
||||
```
|
||||
Debug log goes here, should contain the backtrace, as well as the reset source if it is a crash.
|
||||
Please copy the plain text here for us to search the error log. Or attach the complete logs but leave the main part here if the log is *too* long.
|
||||
```
|
||||
|
||||
## Other items if possible
|
||||
|
||||
- [ ] sdkconfig file (attach the sdkconfig file from your project folder)
|
||||
- [ ] elf file in the ``build`` folder (**note this may contain all the code details and symbols of your project.**)
|
||||
- [ ] coredump (This provides stacks of tasks.)
|
||||
14
.github/ISSUE_TEMPLATE/config.yml
vendored
14
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,14 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: ESP-IDF Programming Guide
|
||||
url: https://docs.espressif.com/projects/esp-idf/en/latest/
|
||||
about: Documentation for configuring and using ESP-IDF
|
||||
- name: Espressif documentation page
|
||||
url: https://www.espressif.com/en/support/download/documents
|
||||
about: Hardware documentation (datasheets, Technical Reference Manual, etc)
|
||||
- name: Forum
|
||||
url: https://esp32.com
|
||||
about: For questions about using ESP-IDF and/or ESP32 series chips. Please submit all questions starting "How do I..." here.
|
||||
- name: Hardware-related services
|
||||
url: https://www.espressif.com/en/products/hardware-services
|
||||
about: Espressif service providing hardware design and certification support
|
||||
26
.github/ISSUE_TEMPLATE/feature_request.md
vendored
26
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,26 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for ESP-IDF
|
||||
title: ''
|
||||
labels: 'Type: Feature Request'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
Please give as many details as you can. Include suggestions for useful APIs or interfaces if relevant.
|
||||
|
||||
**Additional context**
|
||||
|
||||
Add any other context or screenshots about the feature request here.
|
||||
19
.github/workflows/issue_comment.yml
vendored
19
.github/workflows/issue_comment.yml
vendored
@@ -1,19 +0,0 @@
|
||||
name: Sync issue comments to JIRA
|
||||
|
||||
# This workflow will be triggered when new issue comment is created (including PR comments)
|
||||
on: issue_comment
|
||||
|
||||
jobs:
|
||||
sync_issue_comments_to_jira:
|
||||
name: Sync Issue Comments to Jira
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Sync issue comments to JIRA
|
||||
uses: espressif/github-actions/sync_issues_to_jira@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
JIRA_PASS: ${{ secrets.JIRA_PASS }}
|
||||
JIRA_PROJECT: IDFGH
|
||||
JIRA_URL: ${{ secrets.JIRA_URL }}
|
||||
JIRA_USER: ${{ secrets.JIRA_USER }}
|
||||
19
.github/workflows/new_issues.yml
vendored
19
.github/workflows/new_issues.yml
vendored
@@ -1,19 +0,0 @@
|
||||
name: Sync issues to Jira
|
||||
|
||||
# This workflow will be triggered when a new issue is opened
|
||||
on: issues
|
||||
|
||||
jobs:
|
||||
sync_issues_to_jira:
|
||||
name: Sync issues to Jira
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Sync GitHub issues to Jira project
|
||||
uses: espressif/github-actions/sync_issues_to_jira@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
JIRA_PASS: ${{ secrets.JIRA_PASS }}
|
||||
JIRA_PROJECT: IDFGH
|
||||
JIRA_URL: ${{ secrets.JIRA_URL }}
|
||||
JIRA_USER: ${{ secrets.JIRA_USER }}
|
||||
24
.github/workflows/new_prs.yml
vendored
24
.github/workflows/new_prs.yml
vendored
@@ -1,24 +0,0 @@
|
||||
name: Sync remain PRs to Jira
|
||||
|
||||
# This workflow will be triggered every hour, to sync remaining PRs (i.e. PRs with zero comment) to Jira project
|
||||
# Note that, PRs can also get synced when new PR comment is created
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 * * * *"
|
||||
|
||||
jobs:
|
||||
sync_prs_to_jira:
|
||||
name: Sync PRs to Jira
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Sync PRs to Jira project
|
||||
uses: espressif/github-actions/sync_issues_to_jira@master
|
||||
with:
|
||||
cron_job: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
JIRA_PASS: ${{ secrets.JIRA_PASS }}
|
||||
JIRA_PROJECT: IDFGH
|
||||
JIRA_URL: ${{ secrets.JIRA_URL }}
|
||||
JIRA_USER: ${{ secrets.JIRA_USER }}
|
||||
33
.github/workflows/python_lint.yml
vendored
33
.github/workflows/python_lint.yml
vendored
@@ -1,33 +0,0 @@
|
||||
name: Python CI
|
||||
|
||||
# This workflow will be triggered when a PR modifies some python relevant files
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "**.py"
|
||||
- "requirements.txt"
|
||||
|
||||
jobs:
|
||||
python_lint:
|
||||
name: python lint
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.6, 3.7, 3.8]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
- name: Set up Python environment
|
||||
uses: actions/setup-python@master
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
export IDF_PATH=${GITHUB_WORKSPACE}
|
||||
pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
- name: Lint with flake8
|
||||
run: |
|
||||
pip install flake8
|
||||
flake8 . --config=.flake8 --benchmark
|
||||
17
.github/workflows/release_zips.yml
vendored
17
.github/workflows/release_zips.yml
vendored
@@ -1,17 +0,0 @@
|
||||
name: Create zip file with recursive source clone for release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
|
||||
jobs:
|
||||
release_zips:
|
||||
name: Create release zip file
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Create a recursive clone source zip
|
||||
uses: espressif/github-actions/release_zips@master
|
||||
env:
|
||||
RELEASE_PROJECT_NAME: ESP-IDF
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
61
.gitignore
vendored
61
.gitignore
vendored
@@ -21,44 +21,30 @@ GPATH
|
||||
# MacOS directory files
|
||||
.DS_Store
|
||||
|
||||
# Components Unit Test Apps files
|
||||
components/**/build
|
||||
components/**/sdkconfig
|
||||
components/**/sdkconfig.old
|
||||
|
||||
# Example project files
|
||||
examples/**/sdkconfig
|
||||
examples/**/sdkconfig.old
|
||||
examples/**/build
|
||||
|
||||
# Doc build artifacts
|
||||
docs/_build/
|
||||
docs/*/_build/
|
||||
docs/*/doxygen-warning-log.txt
|
||||
docs/*/sphinx-warning-log.txt
|
||||
docs/*/sphinx-warning-log-sanitized.txt
|
||||
docs/*/xml/
|
||||
docs/*/xml_in/
|
||||
docs/*/man/
|
||||
docs/doxygen_sqlite3.db
|
||||
|
||||
# Downloaded font files
|
||||
docs/_static/DejaVuSans.ttf
|
||||
docs/_static/NotoSansSC-Regular.otf
|
||||
|
||||
# Unit test app files
|
||||
tools/unit-test-app/sdkconfig
|
||||
tools/unit-test-app/sdkconfig.old
|
||||
tools/unit-test-app/build
|
||||
tools/unit-test-app/builds
|
||||
tools/unit-test-app/output
|
||||
tools/unit-test-app/test_configs
|
||||
|
||||
# Unit Test CMake compile log folder
|
||||
log_ut_cmake
|
||||
|
||||
# test application build files
|
||||
tools/test_apps/**/build
|
||||
tools/test_apps/**/sdkconfig
|
||||
tools/test_apps/**/sdkconfig.old
|
||||
|
||||
# IDF monitor test
|
||||
tools/test_idf_monitor/outputs
|
||||
|
||||
TEST_LOGS
|
||||
# AWS IoT Examples require device-specific certs/keys
|
||||
examples/protocols/aws_iot/*/main/certs/*.pem.*
|
||||
|
||||
# gcov coverage reports
|
||||
*.gcda
|
||||
@@ -66,28 +52,11 @@ TEST_LOGS
|
||||
coverage.info
|
||||
coverage_report/
|
||||
|
||||
# Windows tools installer build
|
||||
tools/windows/tool_setup/.*
|
||||
tools/windows/tool_setup/input
|
||||
tools/windows/tool_setup/dl
|
||||
tools/windows/tool_setup/Output
|
||||
|
||||
test_multi_heap_host
|
||||
|
||||
# VS Code Settings
|
||||
.vscode/
|
||||
|
||||
# VIM files
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Clion IDE CMake build & config
|
||||
.idea/
|
||||
cmake-build-*/
|
||||
|
||||
# Results for the checking of the Python coding style and static analysis
|
||||
.mypy_cache
|
||||
flake8_output.txt
|
||||
|
||||
# ESP-IDF default build directory name
|
||||
build
|
||||
|
||||
# lock files for examples and components
|
||||
dependencies.lock
|
||||
|
||||
# managed_components for examples
|
||||
managed_components
|
||||
|
||||
1655
.gitlab-ci.yml
1655
.gitlab-ci.yml
File diff suppressed because it is too large
Load Diff
@@ -1,211 +0,0 @@
|
||||
# For the syntax of this file, see:
|
||||
#
|
||||
# https://docs.gitlab.com/ee/user/project/code_owners.html#the-syntax-of-code-owners-files
|
||||
#
|
||||
# If more than one rule matches a given file, the latest rule is used.
|
||||
# The file should be generally kept sorted, except when it is necessary
|
||||
# to use a different order due to the fact above. In that case, use
|
||||
# '# sort-order-reset' comment line to reset the sort order.
|
||||
#
|
||||
# Recipes for a few common cases:
|
||||
#
|
||||
# 1. Specific directory with all its contents:
|
||||
#
|
||||
# /components/app_trace/
|
||||
#
|
||||
# Note the trailing slash!
|
||||
#
|
||||
# 2. File with certain extension in any subdirectory of a certain directory:
|
||||
#
|
||||
# /examples/**/*.py
|
||||
#
|
||||
# This includes an *.py files in /examples/ directory as well.
|
||||
#
|
||||
# 3. Contents of a directory with a certain name, anywhere in the tree:
|
||||
#
|
||||
# test_*_host/
|
||||
#
|
||||
# Will match everything under components/efuse/test_efuse_host/,
|
||||
# components/heap/test_multi_heap_host/, components/lwip/test_afl_host/, etc.
|
||||
#
|
||||
# 4. Same as above, except limited to a specific place in the tree:
|
||||
#
|
||||
# /components/esp32*/
|
||||
#
|
||||
# Matches everything under /components/esp32, /components/esp32s2, etc.
|
||||
# Doesn't match /tools/some-test/components/esp32s5.
|
||||
#
|
||||
# 5. Specific file:
|
||||
#
|
||||
# /tools/tools.json
|
||||
#
|
||||
# 6. File with a certain name anywhere in the tree
|
||||
#
|
||||
# .gitignore
|
||||
#
|
||||
|
||||
* @esp-idf-codeowners/other
|
||||
|
||||
/.* @esp-idf-codeowners/tools
|
||||
/.gitlab-ci.yml @esp-idf-codeowners/ci
|
||||
/.gitlab/ci/ @esp-idf-codeowners/ci
|
||||
/.pre-commit-config.yaml @esp-idf-codeowners/ci
|
||||
/.readthedocs.yml @esp-idf-codeowners/docs
|
||||
/CMakeLists.txt @esp-idf-codeowners/build-config
|
||||
/Kconfig @esp-idf-codeowners/build-config
|
||||
/add_path.sh @esp-idf-codeowners/tools
|
||||
/export.* @esp-idf-codeowners/tools
|
||||
/install.* @esp-idf-codeowners/tools
|
||||
/sdkconfig.rename @esp-idf-codeowners/build-config
|
||||
/sonar-project.properties @esp-idf-codeowners/ci
|
||||
|
||||
# sort-order-reset
|
||||
|
||||
/components/app_trace/ @esp-idf-codeowners/tools
|
||||
/components/app_update/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities
|
||||
/components/asio/ @esp-idf-codeowners/network
|
||||
/components/bootloader*/ @esp-idf-codeowners/system @esp-idf-codeowners/security
|
||||
/components/bt/ @esp-idf-codeowners/bluetooth
|
||||
/components/cbor/ @esp-idf-codeowners/app-utilities
|
||||
/components/cmock/ @esp-idf-codeowners/system
|
||||
/components/coap/ @esp-idf-codeowners/app-utilities
|
||||
/components/console/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities
|
||||
/components/cxx/ @esp-idf-codeowners/system
|
||||
/components/driver/ @esp-idf-codeowners/peripherals
|
||||
/components/efuse/ @esp-idf-codeowners/system
|
||||
/components/esp32*/ @esp-idf-codeowners/system
|
||||
/components/esp_adc_cal/ @esp-idf-codeowners/peripherals
|
||||
/components/esp_common/ @esp-idf-codeowners/system
|
||||
/components/esp_eth/ @esp-idf-codeowners/network
|
||||
/components/esp_event/ @esp-idf-codeowners/system
|
||||
/components/esp_gdbstub/ @esp-idf-codeowners/tools
|
||||
/components/esp_hid/ @esp-idf-codeowners/bluetooth
|
||||
/components/esp_http_client/ @esp-idf-codeowners/app-utilities
|
||||
/components/esp_http_server/ @esp-idf-codeowners/app-utilities
|
||||
/components/esp_https_ota/ @esp-idf-codeowners/app-utilities
|
||||
/components/esp_https_server/ @esp-idf-codeowners/app-utilities
|
||||
/components/esp_hw_support/ @esp-idf-codeowners/system
|
||||
/components/esp_ipc/ @esp-idf-codeowners/system
|
||||
/components/esp_lcd/ @esp-idf-codeowners/peripherals
|
||||
/components/esp_local_ctrl/ @esp-idf-codeowners/app-utilities
|
||||
/components/esp_netif/ @esp-idf-codeowners/network
|
||||
/components/esp_phy/ @esp-idf-codeowners/bluetooth @esp-idf-codeowners/wifi @esp-idf-codeowners/ieee802154
|
||||
/components/esp_pm/ @esp-idf-codeowners/power-management @esp-idf-codeowners/bluetooth @esp-idf-codeowners/wifi
|
||||
/components/esp_ringbuf/ @esp-idf-codeowners/system
|
||||
/components/esp_rom/ @esp-idf-codeowners/system @esp-idf-codeowners/bluetooth @esp-idf-codeowners/wifi
|
||||
/components/esp_serial_slave_link/ @esp-idf-codeowners/peripherals
|
||||
/components/esp_system/ @esp-idf-codeowners/system
|
||||
/components/esp_timer/ @esp-idf-codeowners/system
|
||||
/components/esp-tls/ @esp-idf-codeowners/app-utilities
|
||||
/components/esp_websocket_client/ @esp-idf-codeowners/network
|
||||
/components/esp_wifi/ @esp-idf-codeowners/wifi
|
||||
/components/espcoredump/ @esp-idf-codeowners/tools
|
||||
/components/esptool_py/ @esp-idf-codeowners/tools
|
||||
/components/expat/ @esp-idf-codeowners/app-utilities
|
||||
/components/fatfs/ @esp-idf-codeowners/storage
|
||||
/components/freemodbus/ @esp-idf-codeowners/peripherals
|
||||
/components/freertos/ @esp-idf-codeowners/system
|
||||
/components/hal/ @esp-idf-codeowners/peripherals
|
||||
/components/heap/ @esp-idf-codeowners/system
|
||||
/components/idf_test/ @esp-idf-codeowners/ci
|
||||
/components/ieee802154/ @esp-idf-codeowners/ieee802154
|
||||
/components/jsmn/ @esp-idf-codeowners/app-utilities
|
||||
/components/json/ @esp-idf-codeowners/app-utilities
|
||||
/components/libsodium/ @esp-idf-codeowners/security
|
||||
/components/log/ @esp-idf-codeowners/system
|
||||
/components/lwip/ @esp-idf-codeowners/lwip
|
||||
/components/mbedtls/ @esp-idf-codeowners/app-utilities @esp-idf-codeowners/security
|
||||
/components/mdns/ @esp-idf-codeowners/network
|
||||
/components/mqtt/ @esp-idf-codeowners/network
|
||||
/components/newlib/ @esp-idf-codeowners/system @esp-idf-codeowners/tools
|
||||
/components/nghttp/ @esp-idf-codeowners/app-utilities
|
||||
/components/nvs_flash/ @esp-idf-codeowners/storage
|
||||
/components/openssl/ @esp-idf-codeowners/network
|
||||
/components/openthread/ @esp-idf-codeowners/ieee802154
|
||||
/components/partition_table/ @esp-idf-codeowners/system
|
||||
/components/perfmon/ @esp-idf-codeowners/tools
|
||||
/components/protobuf-c/ @esp-idf-codeowners/app-utilities
|
||||
/components/protocomm/ @esp-idf-codeowners/app-utilities
|
||||
/components/pthread/ @esp-idf-codeowners/system
|
||||
/components/sdmmc/ @esp-idf-codeowners/storage
|
||||
/components/soc/ @esp-idf-codeowners/peripherals @esp-idf-codeowners/system
|
||||
/components/spi_flash/ @esp-idf-codeowners/peripherals
|
||||
/components/spiffs/ @esp-idf-codeowners/storage
|
||||
/components/tcp_transport/ @esp-idf-codeowners/network
|
||||
/components/tcpip_adapter/ @esp-idf-codeowners/network
|
||||
/components/tinyusb/ @esp-idf-codeowners/peripherals/usb
|
||||
/components/touch_element/ @esp-idf-codeowners/peripherals
|
||||
/components/ulp/ @esp-idf-codeowners/system
|
||||
/components/unity/ @esp-idf-codeowners/ci
|
||||
/components/usb/ @esp-idf-codeowners/peripherals/usb
|
||||
/components/vfs/ @esp-idf-codeowners/storage
|
||||
/components/wear_levelling/ @esp-idf-codeowners/storage
|
||||
/components/wifi_provisioning/ @esp-idf-codeowners/app-utilities
|
||||
/components/wpa_supplicant/ @esp-idf-codeowners/wifi
|
||||
/components/xtensa/ @esp-idf-codeowners/system
|
||||
|
||||
/docs/ @esp-idf-codeowners/docs
|
||||
/docs/**/api-reference/bluetooth/ @esp-idf-codeowners/bluetooth
|
||||
/docs/**/api-reference/network/ @esp-idf-codeowners/network
|
||||
/docs/**/api-reference/peripherals/ @esp-idf-codeowners/peripherals
|
||||
/docs/**/api-reference/protocols/ @esp-idf-codeowners/network @esp-idf-codeowners/app-utilities
|
||||
/docs/**/api-reference/provisioning/ @esp-idf-codeowners/app-utilities
|
||||
/docs/**/api-reference/storage/ @esp-idf-codeowners/storage
|
||||
/docs/**/api-reference/system/ @esp-idf-codeowners/system
|
||||
/docs/**/security/ @esp-idf-codeowners/security
|
||||
|
||||
/examples/bluetooth/ @esp-idf-codeowners/bluetooth
|
||||
/examples/build_system/ @esp-idf-codeowners/build-config
|
||||
/examples/common_components/ @esp-idf-codeowners/system
|
||||
/examples/cxx/ @esp-idf-codeowners/system
|
||||
/examples/ethernet/ @esp-idf-codeowners/network
|
||||
/examples/get-started/ @esp-idf-codeowners/system
|
||||
/examples/mesh/ @esp-idf-codeowners/wifi
|
||||
/examples/network/ @esp-idf-codeowners/network @esp-idf-codeowners/wifi
|
||||
/examples/openthread/ @esp-idf-codeowners/ieee802154
|
||||
/examples/peripherals/ @esp-idf-codeowners/peripherals
|
||||
/examples/protocols/ @esp-idf-codeowners/network @esp-idf-codeowners/app-utilities
|
||||
/examples/provisioning/ @esp-idf-codeowners/app-utilities
|
||||
/examples/security/ @esp-idf-codeowners/security
|
||||
/examples/storage/ @esp-idf-codeowners/storage
|
||||
/examples/system/ @esp-idf-codeowners/system
|
||||
/examples/wifi/ @esp-idf-codeowners/wifi
|
||||
|
||||
/examples/**/*.py @esp-idf-codeowners/ci @esp-idf-codeowners/tools
|
||||
|
||||
/make/ @esp-idf-codeowners/build-config
|
||||
|
||||
/tools/ @esp-idf-codeowners/tools
|
||||
/tools/*_apps.py @esp-idf-codeowners/ci
|
||||
/tools/ble/ @esp-idf-codeowners/app-utilities
|
||||
/tools/catch/ @esp-idf-codeowners/ci
|
||||
/tools/ci/ @esp-idf-codeowners/ci
|
||||
/tools/cmake/ @esp-idf-codeowners/build-config
|
||||
/tools/esp_prov/ @esp-idf-codeowners/app-utilities
|
||||
/tools/find_build_apps/ @esp-idf-codeowners/ci
|
||||
/tools/idf_size_yaml/ @esp-idf-codeowners/peripherals
|
||||
/tools/kconfig*/ @esp-idf-codeowners/build-config
|
||||
/tools/ldgen/ @esp-idf-codeowners/build-config
|
||||
/tools/mass_mfg/ @esp-idf-codeowners/app-utilities
|
||||
/tools/mocks/ @esp-idf-codeowners/system
|
||||
|
||||
## Note: owners here should be the same as the owners for the same example subdir, above
|
||||
/tools/test_apps/build_system/ @esp-idf-codeowners/build-config
|
||||
/tools/test_apps/protocols/ @esp-idf-codeowners/network @esp-idf-codeowners/app-utilities
|
||||
/tools/test_apps/security/ @esp-idf-codeowners/security
|
||||
/tools/test_apps/system/ @esp-idf-codeowners/system
|
||||
|
||||
/tools/test_apps/**/*.py @esp-idf-codeowners/ci @esp-idf-codeowners/tools
|
||||
|
||||
/tools/unit-test-app/ @esp-idf-codeowners/system @esp-idf-codeowners/tools
|
||||
|
||||
requirements.txt @esp-idf-codeowners/tools
|
||||
|
||||
# sort-order-reset
|
||||
|
||||
# ignore lists
|
||||
/tools/ci/check_copyright_ignore.txt @esp-idf-codeowners/tools
|
||||
/tools/ci/check_copyright_permanent_ignore.txt @esp-idf-codeowners/all-maintainers
|
||||
/tools/ci/check_examples_cmake_make-cmake_ignore.txt @esp-idf-codeowners/tools
|
||||
/tools/ci/check_examples_cmake_make-make_ignore.txt @esp-idf-codeowners/tools
|
||||
/tools/ci/mypy_ignore_list.txt @esp-idf-codeowners/tools
|
||||
@@ -1,225 +0,0 @@
|
||||
# IDF CI
|
||||
|
||||
- [IDF CI](#idf-ci)
|
||||
- [General Workflow](#general-workflow)
|
||||
- [What if Expected Jobs ARE NOT Created?](#what-if-expected-jobs-are-not-created)
|
||||
- [MR labels for additional jobs](#mr-labels-for-additional-jobs)
|
||||
- [Supported MR Labels](#supported-mr-labels)
|
||||
- [How to trigger a `detached` pipeline without pushing new commits?](#how-to-trigger-a-detached-pipeline-without-pushing-new-commits)
|
||||
- [How to Develop With `rules.yml`?](#how-to-develop-with-rulesyml)
|
||||
- [General Concepts](#general-concepts)
|
||||
- [How to Add a New `Job`?](#how-to-add-a-new-job)
|
||||
- [How to Add a New `Rules` Template?](#how-to-add-a-new-rules-template)
|
||||
- [How to Add a New `if` Anchor?](#how-to-add-a-new-if-anchor)
|
||||
- [Naming Rules](#naming-rules)
|
||||
- [Common Naming Rules](#common-naming-rules)
|
||||
- [`if` Anchors Naming Rules](#if-anchors-naming-rules)
|
||||
- [`rules` Template Naming Rules](#rules-template-naming-rules)
|
||||
- [Reusable Shell Script `tools/ci/utils.sh`](#reusable-shell-script-toolsciutilssh)
|
||||
- [Functions](#functions)
|
||||
- [CI Job Related](#ci-job-related)
|
||||
- [Shell Script Related](#shell-script-related)
|
||||
|
||||
## General Workflow
|
||||
|
||||
1. Push to a remote branch
|
||||
2. Create an MR, choose related labels (not required)
|
||||
3. A `detached` pipeline will be created.
|
||||
4. if you push a new commit, a new pipeline will be created automatically.
|
||||
|
||||
## What if Expected Jobs ARE NOT Created?
|
||||
|
||||
1. check the file patterns
|
||||
|
||||
If you found a job that is not running as expected with some file changes, a git commit to improve the `pattern` will be appreciated.
|
||||
|
||||
2. please add MR labels to run additional tests, currently we have to do this only for `target-test` jobs, please use it as few as possible. Our final goal is to remove all the labels and let the file changes decide everything!
|
||||
|
||||
## MR labels for additional jobs
|
||||
|
||||
### Supported MR Labels
|
||||
|
||||
- `build`
|
||||
- `build_docs`
|
||||
- `component_ut[_esp32/esp32s2/...]`
|
||||
- `custom_test[_esp32/esp32s2/...]`
|
||||
- `docker`
|
||||
- `docs`
|
||||
- `example_test[_esp32/esp32s2/...]`
|
||||
- `fuzzer_test`
|
||||
- `host_test`
|
||||
- `integration_test`
|
||||
- `iperf_stress_test`
|
||||
- `macos`
|
||||
- `macos_test`
|
||||
- `nvs_coverage`
|
||||
- `submodule`
|
||||
- `unit_test[_esp32/esp32s2/...]`
|
||||
- `weekend_test`
|
||||
- `windows`
|
||||
|
||||
There are two general labels (not recommended since these two labels will trigger a lot of jobs)
|
||||
|
||||
- `target_test`: includes all target for `example_test`, `custom_test`, `component_ut`, `unit_test`, `integration_test`
|
||||
- `all_test`: includes all test labels
|
||||
|
||||
### How to trigger a `detached` pipeline without pushing new commits?
|
||||
|
||||
Go to MR web page -> `Pipelines` tab -> click `Run pipeline` button.
|
||||
|
||||
In very rare case, this tab will not show up because no merge_request pipeline is created before. Please use web API then.
|
||||
|
||||
```shell
|
||||
curl -X POST --header "PRIVATE-TOKEN: [YOUR PERSONAL ACCESS TOKEN]" [GITLAB_SERVER]/api/v4/projects/103/merge_requests/[MERGE_REQUEST_IID]/pipelines
|
||||
```
|
||||
|
||||
## How to Develop With `rules.yml`?
|
||||
|
||||
### General Concepts
|
||||
|
||||
- `pattern`: Defined in an array. A GitLab job will be created if the changed files in this MR matched one of the patterns. For example:
|
||||
|
||||
```yaml
|
||||
.patterns-python-files: &patterns-python-files
|
||||
- "**/*.py"
|
||||
```
|
||||
|
||||
- `label`: Defined in an if clause, similar as the previous bot command. A GitLab job will be created if the pipeline variables contains variables in `BOT_LABEL_xxx` format (DEPRECATED) or included in the MR labels. For example:
|
||||
|
||||
```yaml
|
||||
.if-label-build_docs: &if-label-build_docs
|
||||
if: '$BOT_LABEL_BUILD_DOCS || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*build_docs(?:,[^,\n\r]+)*$/i'
|
||||
```
|
||||
|
||||
- `rule`: A combination of various patterns, and labels. It will be used by GitLab YAML `extends` keyword to tell GitLab in what conditions will this job be created. For example:
|
||||
|
||||
```yaml
|
||||
.rules:build:docs:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build_docs
|
||||
- <<: *if-label-docs
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-docs
|
||||
```
|
||||
|
||||
An example for GitLab job on how to use extends:
|
||||
|
||||
```yaml
|
||||
check_docs_lang_sync:
|
||||
extends:
|
||||
- .pre_check_job_template
|
||||
- .rules:build:docs
|
||||
script:
|
||||
- cd docs
|
||||
- ./check_lang_folder_sync.sh
|
||||
```
|
||||
|
||||
### How to Add a New `Job`?
|
||||
|
||||
check if there's a suitable `.rules:<rules-you-need>` template
|
||||
|
||||
1. if there is, put this in the job `extends`. All done, now you can close this window. (`extends` could be array or string)
|
||||
2. if there isn't
|
||||
1. check [How to Add a New `Rules` Template?](#how-to-add-a-new-rules-template), create a suitable one
|
||||
2. follow step 1
|
||||
|
||||
### How to Add a New `Rules` Template?
|
||||
|
||||
check if this rule is related to `labels`, `patterns`
|
||||
|
||||
1. if it is, please refer to [dependencies/README.md](./dependencies/README.md) and add new rules by auto-generating
|
||||
2. if it isn't, please continue reading
|
||||
|
||||
check if there's a suitable `.if-<if-anchor-you-need>` anchor
|
||||
|
||||
1. if there is, create a rule following [`rules` Template Naming Rules](#rules-template-naming-rules).For detail information, please refer to [GitLab Documentation `rules-if`](https://docs.gitlab.com/ee/ci/yaml/README.html#rulesif). Here's an example.
|
||||
|
||||
```yaml
|
||||
.rules:dev:
|
||||
rules:
|
||||
- <<: *if-trigger
|
||||
- <<: *if-dev-push
|
||||
```
|
||||
|
||||
2. if there isn't
|
||||
|
||||
1. check [How to Add a New `if` Anchor?](#how-to-add-a-new-if-anchor), create a suitable one
|
||||
2. follow step 1
|
||||
|
||||
### How to Add a New `if` Anchor?
|
||||
|
||||
Create an `if` anchor following [`if` Anchors Naming Rules](#if-anchors-naming-rules). For detailed information about how to write the condition clause, please refer to [GitLab Documentation `only/except (advanced)](https://docs.gitlab.com/ee/ci/yaml/README.html#onlyexcept-advanced). Here's an example.
|
||||
|
||||
```yaml
|
||||
.if-schedule: &if-schedule:
|
||||
if: '$CI_PIPELINE_SOURCE == "schedule"'
|
||||
```
|
||||
|
||||
### Naming Rules
|
||||
|
||||
#### Common Naming Rules
|
||||
|
||||
if a phrase has multi words, use `_` to concatenate them.
|
||||
|
||||
> e.g. `regular_test`
|
||||
|
||||
if a name has multi phrases, use `-` to concatenate them.
|
||||
|
||||
> e.g. `regular_test-example_test`
|
||||
|
||||
#### `if` Anchors Naming Rules
|
||||
|
||||
- if it's a label: `.if-label-<label_name>`
|
||||
- if it's a ref: `.if-ref-<ref_name>`
|
||||
- if it's a branch: `.if-branch-<branch_name>`
|
||||
- if it's a tag: `.if-tag-<tag_name>`
|
||||
- if it's multi-type combination: `.if-ref-<release_name>-branch-<branch_name>`
|
||||
|
||||
**Common Phrases/Abbreviations**
|
||||
|
||||
- `no_label`
|
||||
|
||||
`$BOT_TRIGGER_WITH_LABEL == null`
|
||||
|
||||
- `protected`
|
||||
|
||||
`($CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_BRANCH =~ /^release\/v/ || $CI_COMMIT_TAG =~ /^v\d+\.\d+(\.\d+)?($|-)/)`
|
||||
|
||||
- `target_test`
|
||||
|
||||
a combination of `example_test`, `custom_test`, `unit_test`, `component_ut`, `integration_test` and all targets
|
||||
|
||||
#### `rules` Template Naming Rules
|
||||
|
||||
- if it's tag related: `.rules:tag:<tag_1>-<tag_2>`
|
||||
- if it's label related: `.rules:labels:<label_1>-<label_2>`
|
||||
- if it's test related: `.rules:test:<test_type>`
|
||||
- if it's build related: `.rules:build:<build_type>`
|
||||
- if it's pattern related: `.rules:patterns:<patterns>`
|
||||
|
||||
## Reusable Shell Script `tools/ci/utils.sh`
|
||||
|
||||
It is used to put all the reusable shell scripts as small functions. If you want to set `before_script: []` for you job, now you can set `extends: .before_script_slim` instead. it will only run `source tools/ci/utils.sh`
|
||||
|
||||
If you're developing CI shell scripts, you can use these functions without `source` them. They're already included in all `before_script`
|
||||
|
||||
To run these commands in shell script locally, place `source tools/ci/utils.sh` at the very beginning.
|
||||
|
||||
### Functions
|
||||
|
||||
#### CI Job Related
|
||||
|
||||
- `add_gitlab_ssh_keys`
|
||||
- `add_github_ssh_keys`
|
||||
- `add_doc_server_ssh_keys`
|
||||
- `fetch_submodules`
|
||||
- `get_all_submodules`
|
||||
|
||||
#### Shell Script Related
|
||||
|
||||
- `error`: log in red color
|
||||
- `warning`: log in orange color
|
||||
- `info`: log in green color
|
||||
- `run_cmd`: run the command with duration seconds info
|
||||
- `retry_failed`: run the command with duration seconds info, retry when failed
|
||||
@@ -1,88 +0,0 @@
|
||||
assign_test:
|
||||
extends: .rules:test:any_test
|
||||
tags:
|
||||
- assign_test
|
||||
image: $CI_DOCKER_REGISTRY/ubuntu-test-env$BOT_DOCKER_IMAGE_TAG
|
||||
stage: assign_test
|
||||
# gitlab ci do not support match job with RegEx or wildcard now in dependencies.
|
||||
# we have a lot build example jobs. now we don't use dependencies, just download all artifacts of build stage.
|
||||
dependencies: # Here is not a hard dependency relationship, could be skipped. so we do not use "needs" here.
|
||||
- build_ssc_esp32
|
||||
- build_esp_idf_tests_cmake_esp32
|
||||
- build_esp_idf_tests_cmake_esp32s2
|
||||
- build_esp_idf_tests_cmake_esp32s3
|
||||
- build_esp_idf_tests_cmake_esp32c3
|
||||
variables:
|
||||
SUBMODULES_TO_FETCH: "components/esptool_py/esptool"
|
||||
EXAMPLE_TEST_DIR: "${CI_PROJECT_DIR}/examples"
|
||||
CUSTOM_TEST_DIR: "${CI_PROJECT_DIR}/tools/test_apps"
|
||||
UNIT_TEST_DIR: "${CI_PROJECT_DIR}/components/idf_test/unit_test"
|
||||
# COMPONENT_UT_DIRS is set by `set_component_ut_vars` in `utils.sh`
|
||||
COMPONENT_UT_OUTPUT_DIR: "${CI_PROJECT_DIR}/component_ut"
|
||||
INTEGRATION_CONFIG_OUTPUT_PATH: "${CI_PROJECT_DIR}/components/idf_test/integration_test/CIConfigs"
|
||||
INTEGRATION_TEST_CASE_PATH: "${CI_PROJECT_DIR}/auto_test_script/TestCaseFiles"
|
||||
ASSIGN_TEST_CASE_SCRIPT: "${CI_PROJECT_DIR}/auto_test_script/bin/CIAssignTestCases.py"
|
||||
PYTHONPATH: ${CI_PROJECT_DIR}/auto_test_script/packages
|
||||
# auto_test_script only supports python 3.7.x
|
||||
PYTHON_VER: 3.7.7
|
||||
artifacts:
|
||||
paths:
|
||||
- components/idf_test/*/CIConfigs
|
||||
- $EXAMPLE_TEST_DIR/test_configs
|
||||
- $CUSTOM_TEST_DIR/test_configs
|
||||
- $COMPONENT_UT_OUTPUT_DIR/test_configs
|
||||
- build_examples/artifact_index.json
|
||||
- build_test_apps/artifact_index.json
|
||||
- build_component_ut/artifact_index.json
|
||||
- tools/unit-test-app/builds/artifact_index.json
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- set_component_ut_vars
|
||||
- python tools/ci/python_packages/ttfw_idf/IDFAssignTest.py example_test $EXAMPLE_TEST_DIR -c $CI_TARGET_TEST_CONFIG_FILE -o $EXAMPLE_TEST_DIR/test_configs
|
||||
- python tools/ci/python_packages/ttfw_idf/IDFAssignTest.py custom_test $CUSTOM_TEST_DIR -c $CI_TARGET_TEST_CONFIG_FILE -o $CUSTOM_TEST_DIR/test_configs
|
||||
- python tools/ci/python_packages/ttfw_idf/IDFAssignTest.py component_ut $COMPONENT_UT_DIRS -c $CI_TARGET_TEST_CONFIG_FILE -o $COMPONENT_UT_OUTPUT_DIR/test_configs
|
||||
- python tools/ci/python_packages/ttfw_idf/IDFAssignTest.py unit_test $UNIT_TEST_DIR -c $CI_TARGET_TEST_CONFIG_FILE -o $UNIT_TEST_DIR/CIConfigs
|
||||
# clone test script to assign tests
|
||||
# can not retry if downing git lfs files failed, so using empty_branch first.
|
||||
- retry_failed git clone ${CI_AUTO_TEST_SCRIPT_REPO_URL} -b empty_branch
|
||||
- retry_failed git -C auto_test_script checkout -f ${CI_AUTO_TEST_SCRIPT_REPO_BRANCH}
|
||||
- python $CHECKOUT_REF_SCRIPT auto_test_script auto_test_script --customized_only
|
||||
# assign integration test cases
|
||||
- python ${ASSIGN_TEST_CASE_SCRIPT} -t ${INTEGRATION_TEST_CASE_PATH} -c $CI_TARGET_TEST_CONFIG_FILE -b $IDF_PATH/SSC/ssc_bin -o $INTEGRATION_CONFIG_OUTPUT_PATH
|
||||
|
||||
update_test_cases:
|
||||
extends: .rules:ref:master-schedule
|
||||
stage: assign_test
|
||||
image: $CI_DOCKER_REGISTRY/ubuntu-test-env
|
||||
tags:
|
||||
- deploy_test
|
||||
needs:
|
||||
- build_esp_idf_tests_cmake_esp32
|
||||
- build_esp_idf_tests_cmake_esp32s2
|
||||
- build_esp_idf_tests_cmake_esp32s3
|
||||
- build_esp_idf_tests_cmake_esp32c3
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- ${CI_PROJECT_DIR}/test-management/*.log
|
||||
expire_in: 1 week
|
||||
variables:
|
||||
SUBMODULES_TO_FETCH: "components/esptool_py/esptool"
|
||||
UNIT_TEST_DIR: "${CI_PROJECT_DIR}/components/idf_test/unit_test"
|
||||
BOT_ACCOUNT_CONFIG_FILE: "${CI_PROJECT_DIR}/test-management/Config/Account.local.yml"
|
||||
AUTO_TEST_SCRIPT_PATH: "${CI_PROJECT_DIR}/auto_test_script"
|
||||
PYTHON_VER: 3.7.7
|
||||
script:
|
||||
- export GIT_SHA=$(echo ${CI_COMMIT_SHA} | cut -c 1-8)
|
||||
- retry_failed git clone $TEST_MANAGEMENT_REPO
|
||||
- python $CHECKOUT_REF_SCRIPT test-management test-management
|
||||
- cd test-management
|
||||
- echo $BOT_JIRA_ACCOUNT > ${BOT_ACCOUNT_CONFIG_FILE}
|
||||
# update unit test cases
|
||||
- export UNIT_TEST_CASE_FILES=$(find $UNIT_TEST_DIR -maxdepth 1 -name "*.yml" | xargs)
|
||||
- python ImportTestCase.py $JIRA_TEST_MANAGEMENT_PROJECT unity -d $UNIT_TEST_CASE_FILES -r $GIT_SHA
|
||||
# update example test cases
|
||||
- python ImportTestCase.py $JIRA_TEST_MANAGEMENT_PROJECT tiny_test_fw -d ${CI_PROJECT_DIR}/examples -r $GIT_SHA
|
||||
- python ImportTestCase.py $JIRA_TEST_MANAGEMENT_PROJECT tiny_test_fw -d ${CI_PROJECT_DIR}/tools/test_apps -r $GIT_SHA
|
||||
# organize test cases
|
||||
- python OrganizeTestCases.py $JIRA_TEST_MANAGEMENT_PROJECT
|
||||
@@ -1,406 +0,0 @@
|
||||
.build_template:
|
||||
stage: build
|
||||
image: $ESP_ENV_IMAGE
|
||||
tags:
|
||||
- build
|
||||
variables:
|
||||
SIZE_INFO_LOCATION: "$CI_PROJECT_DIR/size_info.txt"
|
||||
dependencies: []
|
||||
|
||||
.build_template_app_template:
|
||||
extends: .build_template
|
||||
variables:
|
||||
LOG_PATH: "${CI_PROJECT_DIR}/log_template_app"
|
||||
BUILD_PATH: "${CI_PROJECT_DIR}/build_template_app"
|
||||
BUILD_DIR: "@t/@w"
|
||||
BUILD_LOG_MAKE: "${LOG_PATH}/make_@t_@w.txt"
|
||||
BUILD_LOG_CMAKE: "${LOG_PATH}/cmake_@t_@w.txt"
|
||||
BUILD_COMMAND_ARGS: ""
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- log_template_app/*
|
||||
- size_info.txt
|
||||
- build_template_app/**/size.json
|
||||
script:
|
||||
# Set the variable for 'esp-idf-template' testing
|
||||
- ESP_IDF_TEMPLATE_GIT=${ESP_IDF_TEMPLATE_GIT:-"https://github.com/espressif/esp-idf-template.git"}
|
||||
- retry_failed git clone ${ESP_IDF_TEMPLATE_GIT}
|
||||
# Try to use the same branch name for esp-idf-template that we're
|
||||
# using on esp-idf. If it doesn't exist then just stick to the default branch
|
||||
- python $CHECKOUT_REF_SCRIPT esp-idf-template esp-idf-template
|
||||
- export PATH="$IDF_PATH/tools:$PATH"
|
||||
- export EXTRA_CFLAGS=${PEDANTIC_CFLAGS}
|
||||
- export EXTRA_CXXFLAGS=${PEDANTIC_CXXFLAGS}
|
||||
# Only do the default cmake build for each target, remaining part are done in the build_template_app job
|
||||
- tools/ci/build_template_app.sh ${BUILD_COMMAND_ARGS}
|
||||
# Check if there are any stray printf/ets_printf references in WiFi libs
|
||||
- cd components/esp_wifi/lib
|
||||
- for dir in esp32 esp32s2; do test $(xtensa-esp32-elf-nm $dir/*.a | grep -w printf | wc -l) -eq 0; done;
|
||||
- for dir in esp32 esp32s2; do test $(xtensa-esp32-elf-nm $dir/*.a | grep -w ets_printf | wc -l) -eq 0; done;
|
||||
|
||||
# build-related-pre-check-jobs ------------------------------------------------
|
||||
# Build at least one project for each target at earliest stage to reduce build cost for obvious failing commits
|
||||
fast_template_app:
|
||||
extends:
|
||||
- .build_template_app_template
|
||||
- .rules:build:target_test
|
||||
stage: pre_check
|
||||
variables:
|
||||
BUILD_COMMAND_ARGS: "-p"
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
.build_ssc_template:
|
||||
extends:
|
||||
- .build_template
|
||||
- .rules:build:integration_test
|
||||
artifacts:
|
||||
paths:
|
||||
- SSC/ssc_bin
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- retry_failed git clone $SSC_REPOSITORY
|
||||
- python $CHECKOUT_REF_SCRIPT SSC SSC
|
||||
- cd SSC
|
||||
- MAKEFLAGS= ./ci_build_ssc.sh $TARGET_NAME
|
||||
|
||||
build_ssc_esp32:
|
||||
extends: .build_ssc_template
|
||||
parallel: 3
|
||||
variables:
|
||||
TARGET_NAME: "ESP32"
|
||||
|
||||
build_ssc_esp32s2:
|
||||
extends: .build_ssc_template
|
||||
parallel: 2
|
||||
variables:
|
||||
TARGET_NAME: "ESP32S2"
|
||||
|
||||
build_ssc_esp32c3:
|
||||
extends: .build_ssc_template
|
||||
parallel: 3
|
||||
variables:
|
||||
TARGET_NAME: "ESP32C3"
|
||||
|
||||
.build_esp_idf_tests_cmake_template:
|
||||
extends: .build_template
|
||||
dependencies: # set dependencies to null to avoid missing artifacts issue
|
||||
needs:
|
||||
- job: fast_template_app
|
||||
artifacts: false
|
||||
- scan_tests
|
||||
artifacts:
|
||||
paths:
|
||||
- tools/unit-test-app/output/${IDF_TARGET}
|
||||
- tools/unit-test-app/builds/*.json
|
||||
- tools/unit-test-app/builds/${IDF_TARGET}/*/size.json
|
||||
- components/idf_test/unit_test/*.yml
|
||||
- $LOG_PATH
|
||||
- $SIZE_INFO_LOCATION
|
||||
when: always
|
||||
expire_in: 4 days
|
||||
variables:
|
||||
LOG_PATH: "$CI_PROJECT_DIR/log_ut_cmake"
|
||||
BUILD_PATH: ${CI_PROJECT_DIR}/tools/unit-test-app/builds
|
||||
OUTPUT_PATH: ${CI_PROJECT_DIR}/tools/unit-test-app/output
|
||||
BUILD_SYSTEM: "cmake"
|
||||
TEST_TYPE: "unit_test"
|
||||
PYTHON_VER: 3.6.13
|
||||
LDGEN_CHECK_MAPPING: 1
|
||||
script:
|
||||
- ${IDF_PATH}/tools/ci/find_apps_build_apps.sh
|
||||
- cd $CI_PROJECT_DIR/tools/unit-test-app
|
||||
- python tools/UnitTestParser.py ${BUILD_PATH} ${CI_NODE_INDEX:-1}
|
||||
|
||||
build_esp_idf_tests_cmake_esp32:
|
||||
extends:
|
||||
- .build_esp_idf_tests_cmake_template
|
||||
- .rules:build:unit_test-esp32
|
||||
parallel: 2
|
||||
variables:
|
||||
IDF_TARGET: esp32
|
||||
|
||||
build_esp_idf_tests_cmake_esp32s2:
|
||||
extends:
|
||||
- .build_esp_idf_tests_cmake_template
|
||||
- .rules:build:unit_test-esp32s2
|
||||
parallel: 2
|
||||
variables:
|
||||
IDF_TARGET: esp32s2
|
||||
|
||||
build_esp_idf_tests_cmake_esp32s3:
|
||||
extends:
|
||||
- .build_esp_idf_tests_cmake_template
|
||||
- .rules:build:unit_test-esp32s3
|
||||
variables:
|
||||
IDF_TARGET: esp32s3
|
||||
|
||||
build_esp_idf_tests_cmake_esp32c3:
|
||||
extends:
|
||||
- .build_esp_idf_tests_cmake_template
|
||||
- .rules:build:unit_test-esp32c3
|
||||
variables:
|
||||
IDF_TARGET: esp32c3
|
||||
|
||||
.build_examples_template:
|
||||
extends: .build_template
|
||||
dependencies: # set dependencies to null to avoid missing artifacts issue
|
||||
needs:
|
||||
- job: fast_template_app
|
||||
artifacts: false
|
||||
- scan_tests
|
||||
variables:
|
||||
TEST_PREFIX: examples
|
||||
TEST_RELATIVE_DIR: examples
|
||||
SCAN_TEST_JSON: ${CI_PROJECT_DIR}/${TEST_RELATIVE_DIR}/test_configs/scan_${IDF_TARGET}_${BUILD_SYSTEM}.json
|
||||
TEST_TYPE: example_test
|
||||
LOG_PATH: ${CI_PROJECT_DIR}/log_${TEST_PREFIX}
|
||||
BUILD_PATH: ${CI_PROJECT_DIR}/build_${TEST_PREFIX}
|
||||
PYTHON_VER: 3.6.13
|
||||
LDGEN_CHECK_MAPPING: 1
|
||||
script:
|
||||
# it's not possible to build 100% out-of-tree and have the "artifacts"
|
||||
# mechanism work, but this is the next best thing
|
||||
- ${IDF_PATH}/tools/ci/find_apps_build_apps.sh
|
||||
|
||||
build_examples_make:
|
||||
extends:
|
||||
- .build_examples_template
|
||||
- .rules:build:example_test-esp32
|
||||
stage: host_test
|
||||
# This is a workaround for a rarely encountered issue with building examples in CI.
|
||||
# Probably related to building of Kconfig in 'make clean' stage
|
||||
retry: 1
|
||||
parallel: 8
|
||||
artifacts:
|
||||
paths:
|
||||
- $LOG_PATH
|
||||
- build_${TEST_PREFIX}/*/*/*/build/size.json
|
||||
- $SIZE_INFO_LOCATION
|
||||
when: always
|
||||
expire_in: 4 days
|
||||
variables:
|
||||
BUILD_SYSTEM: make
|
||||
IDF_TARGET: esp32 # currently we only support esp32
|
||||
|
||||
# same as above, but for CMake
|
||||
.build_examples_cmake_template:
|
||||
extends: .build_examples_template
|
||||
artifacts:
|
||||
paths:
|
||||
- build_${TEST_PREFIX}/list.json
|
||||
- build_${TEST_PREFIX}/list_job_*.json
|
||||
- build_${TEST_PREFIX}/*/*/*/sdkconfig
|
||||
- build_${TEST_PREFIX}/*/*/*/build/size.json
|
||||
- build_${TEST_PREFIX}/*/*/*/build/*.bin
|
||||
- build_${TEST_PREFIX}/*/*/*/build/*.elf
|
||||
- build_${TEST_PREFIX}/*/*/*/build/*.map
|
||||
- build_${TEST_PREFIX}/*/*/*/build/flasher_args.json
|
||||
- build_${TEST_PREFIX}/*/*/*/build/bootloader/*.bin
|
||||
- build_${TEST_PREFIX}/*/*/*/build/partition_table/*.bin
|
||||
- $LOG_PATH
|
||||
- $SIZE_INFO_LOCATION
|
||||
when: always
|
||||
expire_in: 4 days
|
||||
variables:
|
||||
BUILD_SYSTEM: cmake
|
||||
|
||||
build_examples_cmake_esp32:
|
||||
extends:
|
||||
- .build_examples_cmake_template
|
||||
- .rules:build:example_test-esp32
|
||||
parallel: 10
|
||||
variables:
|
||||
IDF_TARGET: esp32
|
||||
|
||||
build_examples_cmake_esp32s2:
|
||||
extends:
|
||||
- .build_examples_cmake_template
|
||||
- .rules:build:example_test-esp32s2
|
||||
parallel: 8
|
||||
variables:
|
||||
IDF_TARGET: esp32s2
|
||||
|
||||
build_examples_cmake_esp32s3:
|
||||
extends:
|
||||
- .build_examples_cmake_template
|
||||
- .rules:build:example_test-esp32s3
|
||||
parallel: 8
|
||||
variables:
|
||||
IDF_TARGET: esp32s3
|
||||
|
||||
build_examples_cmake_esp32c3:
|
||||
extends:
|
||||
- .build_examples_cmake_template
|
||||
- .rules:build:example_test-esp32c3
|
||||
parallel: 8
|
||||
variables:
|
||||
IDF_TARGET: esp32c3
|
||||
|
||||
.build_test_apps_template:
|
||||
extends: .build_examples_cmake_template
|
||||
variables:
|
||||
TEST_PREFIX: test_apps
|
||||
TEST_RELATIVE_DIR: tools/test_apps
|
||||
TEST_TYPE: custom_test
|
||||
script:
|
||||
- ${IDF_PATH}/tools/ci/find_apps_build_apps.sh
|
||||
|
||||
build_test_apps_esp32:
|
||||
extends:
|
||||
- .build_test_apps_template
|
||||
- .rules:build:custom_test-esp32
|
||||
parallel: 8
|
||||
variables:
|
||||
IDF_TARGET: esp32
|
||||
|
||||
build_test_apps_esp32s2:
|
||||
extends:
|
||||
- .build_test_apps_template
|
||||
- .rules:build:custom_test-esp32s2
|
||||
parallel: 8
|
||||
variables:
|
||||
IDF_TARGET: esp32s2
|
||||
|
||||
build_test_apps_esp32s3:
|
||||
extends:
|
||||
- .build_test_apps_template
|
||||
- .rules:build:custom_test-esp32s3
|
||||
parallel: 8
|
||||
variables:
|
||||
IDF_TARGET: esp32s3
|
||||
|
||||
build_test_apps_esp32c3:
|
||||
extends:
|
||||
- .build_test_apps_template
|
||||
- .rules:build:custom_test-esp32c3
|
||||
parallel: 8
|
||||
variables:
|
||||
IDF_TARGET: esp32c3
|
||||
|
||||
.build_component_ut_template:
|
||||
extends: .build_test_apps_template
|
||||
variables:
|
||||
TEST_PREFIX: component_ut
|
||||
TEST_RELATIVE_DIR: component_ut
|
||||
|
||||
build_component_ut_esp32:
|
||||
extends:
|
||||
- .build_component_ut_template
|
||||
- .rules:build:component_ut-esp32
|
||||
variables:
|
||||
IDF_TARGET: esp32
|
||||
|
||||
build_component_ut_esp32s2:
|
||||
extends:
|
||||
- .build_component_ut_template
|
||||
- .rules:build:component_ut-esp32s2
|
||||
variables:
|
||||
IDF_TARGET: esp32s2
|
||||
|
||||
build_component_ut_esp32s3:
|
||||
extends:
|
||||
- .build_component_ut_template
|
||||
- .rules:build:component_ut-esp32s3
|
||||
variables:
|
||||
IDF_TARGET: esp32s3
|
||||
|
||||
build_component_ut_esp32c3:
|
||||
extends:
|
||||
- .build_component_ut_template
|
||||
- .rules:build:component_ut-esp32c3
|
||||
variables:
|
||||
IDF_TARGET: esp32c3
|
||||
|
||||
.test_build_system_template:
|
||||
stage: host_test
|
||||
extends:
|
||||
- .build_template
|
||||
- .rules:build
|
||||
needs:
|
||||
- job: fast_template_app
|
||||
artifacts: false
|
||||
script:
|
||||
- ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh
|
||||
- rm -rf test_build_system
|
||||
- mkdir test_build_system
|
||||
- cd test_build_system
|
||||
- ${IDF_PATH}/tools/ci/${SHELL_TEST_SCRIPT}
|
||||
|
||||
test_build_system:
|
||||
extends: .test_build_system_template
|
||||
variables:
|
||||
SHELL_TEST_SCRIPT: test_build_system.sh
|
||||
|
||||
test_build_system_cmake:
|
||||
extends: .test_build_system_template
|
||||
variables:
|
||||
SHELL_TEST_SCRIPT: test_build_system_cmake.sh
|
||||
|
||||
test_build_system_cmake_macos:
|
||||
extends:
|
||||
- .test_build_system_template
|
||||
- .before_script_macos
|
||||
- .rules:build:macos
|
||||
tags:
|
||||
- macos_shell
|
||||
variables:
|
||||
SHELL_TEST_SCRIPT: test_build_system_cmake.sh
|
||||
|
||||
build_docker:
|
||||
extends:
|
||||
- .before_script_minimal
|
||||
- .rules:build:docker
|
||||
stage: host_test
|
||||
needs: []
|
||||
image: espressif/docker-builder:1
|
||||
tags:
|
||||
- build_docker_amd64_brno
|
||||
variables:
|
||||
DOCKER_TMP_IMAGE_NAME: "idf_tmp_image"
|
||||
script:
|
||||
- export LOCAL_CI_REPOSITORY_URL=$CI_REPOSITORY_URL
|
||||
- if [ -n "$LOCAL_GITLAB_HTTPS_HOST" ]; then export LOCAL_CI_REPOSITORY_URL="https://gitlab-ci-token:${CI_JOB_TOKEN}@${LOCAL_GITLAB_HTTPS_HOST}/${CI_PROJECT_PATH}"; fi
|
||||
- echo "Using repository at $LOCAL_CI_REPOSITORY_URL"
|
||||
- export DOCKER_BUILD_ARGS="--build-arg IDF_CLONE_URL=${LOCAL_CI_REPOSITORY_URL} --build-arg IDF_CLONE_BRANCH_OR_TAG=${CI_COMMIT_REF_NAME} --build-arg IDF_CHECKOUT_REF=${CI_COMMIT_TAG:-$CI_COMMIT_SHA}"
|
||||
# Build
|
||||
- docker build --tag ${DOCKER_TMP_IMAGE_NAME} ${DOCKER_BUILD_ARGS} tools/docker/
|
||||
# We can't mount $PWD/examples/get-started/blink into the container, see https://gitlab.com/gitlab-org/gitlab-ce/issues/41227.
|
||||
# The workaround mentioned there works, but leaves around directories which need to be cleaned up manually.
|
||||
# Therefore, build a copy of the example located inside the container.
|
||||
- docker run --rm --workdir /opt/esp/idf/examples/get-started/blink ${DOCKER_TMP_IMAGE_NAME} idf.py build
|
||||
|
||||
.test-on-windows:
|
||||
extends:
|
||||
- .before_script_minimal
|
||||
- .rules:build:windows
|
||||
stage: host_test
|
||||
needs: []
|
||||
image: $CI_DOCKER_REGISTRY/esp32-toolchain-win-cross
|
||||
tags:
|
||||
- build
|
||||
script:
|
||||
- cd $TEST_DIR
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain-i686-w64-mingw32.cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
- cmake --build .
|
||||
|
||||
build_idf_exe:
|
||||
extends: .test-on-windows
|
||||
artifacts:
|
||||
paths:
|
||||
- tools/windows/idf_exe/build/idf-exe-v*.zip
|
||||
expire_in: 4 days
|
||||
variables:
|
||||
TEST_DIR: tools/windows/idf_exe
|
||||
|
||||
# This job builds template app with permutations of targets and optimization levels
|
||||
build_template_app:
|
||||
extends:
|
||||
- .build_template_app_template
|
||||
- .rules:build
|
||||
stage: host_test
|
||||
needs:
|
||||
- job: fast_template_app
|
||||
artifacts: false
|
||||
@@ -1,100 +0,0 @@
|
||||
# How the `generate_rules.py` works
|
||||
|
||||
## Functionalities
|
||||
|
||||
This script can do only two things:
|
||||
|
||||
1. Auto-generate some labels/rules we need and update them in `rules.yml`
|
||||
2. Generate a dependency tree graph
|
||||
|
||||
## Schema
|
||||
|
||||
This file only used basic YAML grammar and has nothing to do with the GitLab version YAML file.
|
||||
|
||||
It has five custom keywords:
|
||||
|
||||
- `matrix`: An array of sub-arrays, used to replicate rules by formatting strings. You can use the format string everywhere, it will be formatted recursively
|
||||
- `labels`: An array of `labels`.
|
||||
- `patterns`: An array of `patterns`. Patterns that not included
|
||||
- `included_in`: An array of other `rule` names. It indicates the `labels` and `patterns` will be included in all specified `rules` as well
|
||||
- `deploy`: An array of strings, used to replicate rules by adding postfix `-<item in deploy array>`. It indicates the extra `label` used in `rules`, which will explain later.
|
||||
|
||||
## How to use this file to generate `rules.yml`
|
||||
|
||||
Let's take a complicated example to help understand the process
|
||||
|
||||
```yaml
|
||||
"test-{0}-{1}":
|
||||
matrix:
|
||||
- [a, b]
|
||||
- [c, d]
|
||||
labels:
|
||||
- "{0}-{1}"
|
||||
patterns:
|
||||
- "{0}"
|
||||
- pattern-not-exist
|
||||
included_in:
|
||||
- build-{0}
|
||||
```
|
||||
|
||||
1. expand the mapping dicts defined by `matrix`
|
||||
|
||||
After this step, it will turn into 4 dicts:
|
||||
|
||||
| key | labels | patterns | included_in |
|
||||
| -------- | ------ | -------- | ----------- |
|
||||
| test-a-c | a-c | a | build-a |
|
||||
| test-a-d | a-d | a | build-a |
|
||||
| test-b-c | b-c | b | build-b |
|
||||
| test-b-d | b-d | b | build-b |
|
||||
|
||||
**Advanced Usage: You can overwrite a mapping by declaring it again later**, For example:
|
||||
|
||||
If we concatenate this part to the previous example,
|
||||
|
||||
```yaml
|
||||
# ... The same as the previous example
|
||||
|
||||
test-a-c:
|
||||
labels:
|
||||
- overwrite
|
||||
```
|
||||
|
||||
`rule` `test-a-c` will be turned into:
|
||||
|
||||
| key | labels |
|
||||
| -------- | --------- |
|
||||
| test-a-c | overwrite |
|
||||
|
||||
**Mappings with the keyword `deploy` will also replicate by adding a postfix `-<item in deploy array>` to the mapping key**
|
||||
|
||||
2. create rules by `included_in`
|
||||
|
||||
After this step, it will turn into 6 mapping dicts:
|
||||
|
||||
| key | labels | patterns |
|
||||
| -------- | -------- | -------- |
|
||||
| test-a-c | a-c | a |
|
||||
| test-a-d | a-d | a |
|
||||
| test-b-c | b-c | b |
|
||||
| test-b-d | b-d | b |
|
||||
| build-a | a-c, a-d | a |
|
||||
| build-b | b-c, b-d | b |
|
||||
|
||||
3. replace the auto-generated region in `rules.yml` with `labels`, and `rules`. Each mapping will generate a `rule` and all the required labels. `patterns` are pre-defined in `rules.yml` and could not be generated automatically. If a mapping is using a `pattern` undefined, the `pattern` will be ignored.
|
||||
|
||||
- If a mapping key has postfix `-preview`, no `if-protected-xxx` clause will be added
|
||||
- else if a mapping key has postfix `-production`, an `if-protected-no_label` clause will be added
|
||||
- else, an `if-protected` clause will be added
|
||||
|
||||
## Graph
|
||||
|
||||
All `label` nodes are in green, `pattern` nodes are in cyan, `rule` nodes are in blue
|
||||
|
||||
### Requirements
|
||||
|
||||
There are a few extra dependencies while generating the dependency tree graph, please refer to [pygraphviz](https://github.com/pygraphviz/pygraphviz/blob/master/INSTALL.txt) documentation to install both `graphviz` and `pygraphviz`
|
||||
|
||||
### CLI usage
|
||||
|
||||
`python generate_rules.py --graph OUTPUT_PATH`
|
||||
@@ -1,184 +0,0 @@
|
||||
.all_targets: &all_targets
|
||||
- esp32
|
||||
- esp32s2
|
||||
- esp32s3
|
||||
- esp32c3
|
||||
|
||||
.target_test: &target_test
|
||||
- example_test
|
||||
- custom_test
|
||||
- unit_test
|
||||
- component_ut
|
||||
|
||||
##############
|
||||
# Build Jobs #
|
||||
##############
|
||||
"build":
|
||||
labels:
|
||||
- build
|
||||
patterns:
|
||||
- build_components
|
||||
- build_system
|
||||
included_in:
|
||||
- build:target_test
|
||||
|
||||
# -------------------
|
||||
# Specific Build Jobs
|
||||
# -------------------
|
||||
"build:docker":
|
||||
labels:
|
||||
- build
|
||||
- docker
|
||||
patterns:
|
||||
- docker
|
||||
|
||||
"build:windows":
|
||||
labels:
|
||||
- build
|
||||
- windows
|
||||
patterns:
|
||||
- build_system
|
||||
- windows
|
||||
|
||||
"build:macos":
|
||||
labels:
|
||||
- build
|
||||
- macos
|
||||
- macos_test # for backward compatibility
|
||||
patterns:
|
||||
- build_system
|
||||
- macos
|
||||
|
||||
# ---------------
|
||||
# Build Test Jobs
|
||||
# ---------------
|
||||
"build:{0}-{1}":
|
||||
matrix:
|
||||
- *target_test
|
||||
- *all_targets
|
||||
labels:
|
||||
- build
|
||||
patterns:
|
||||
- build_components
|
||||
- build_system
|
||||
|
||||
build:integration_test:
|
||||
labels:
|
||||
- build
|
||||
patterns:
|
||||
- build_components
|
||||
- build_system
|
||||
|
||||
# -------------
|
||||
# Special Cases
|
||||
# -------------
|
||||
"build:example_test-esp32c3": # esp32c3 test is only run by label, but build jobs should always be triggered
|
||||
labels:
|
||||
- build
|
||||
- example_test
|
||||
patterns:
|
||||
- build_components
|
||||
- build_system
|
||||
- build-example_test
|
||||
- example_test
|
||||
|
||||
####################
|
||||
# Target Test Jobs #
|
||||
####################
|
||||
"test:{0}-{1}":
|
||||
matrix:
|
||||
- *target_test
|
||||
- *all_targets
|
||||
labels: # For each rule, use labels <test_type> and <test_type>-<target>
|
||||
- "{0}"
|
||||
- "{0}_{1}"
|
||||
patterns: # For each rule, use patterns <test_type> and build-<test_type>
|
||||
- "{0}"
|
||||
- "build-{0}"
|
||||
included_in: # Parent rules
|
||||
- "build:{0}-{1}"
|
||||
- build:target_test
|
||||
- test:target_test
|
||||
- test:any_test
|
||||
|
||||
# -------------
|
||||
# Special Cases
|
||||
# -------------
|
||||
"test:component_ut-{0}": # component_ut will trigger by unit_test as well, since now we have 2 kinds of UT
|
||||
matrix:
|
||||
- *all_targets
|
||||
labels:
|
||||
- component_ut
|
||||
- "component_ut_{0}"
|
||||
- unit_test
|
||||
- "unit_test_{0}"
|
||||
patterns:
|
||||
- component_ut
|
||||
- "build-component_ut-{0}"
|
||||
included_in:
|
||||
- "build:component_ut-{0}"
|
||||
- build:target_test
|
||||
- test:target_test
|
||||
- test:any_test
|
||||
|
||||
"test:example_test-esp32c3": # For esp32c3 we trigger only with label
|
||||
|
||||
"labels:example_test-esp32c3":
|
||||
labels:
|
||||
- example_test_esp32c3
|
||||
included_in:
|
||||
- build:example_test-esp32c3
|
||||
- build:target_test
|
||||
|
||||
"test:integration_test":
|
||||
labels:
|
||||
- "integration_test"
|
||||
patterns:
|
||||
- "integration_test"
|
||||
included_in:
|
||||
- "build:integration_test"
|
||||
- build:target_test
|
||||
- test:target_test
|
||||
- test:any_test
|
||||
|
||||
"test:host_test":
|
||||
labels:
|
||||
- host_test
|
||||
patterns:
|
||||
- host_test
|
||||
included_in:
|
||||
- test:any_test
|
||||
|
||||
"test:submodule":
|
||||
labels:
|
||||
- submodule
|
||||
patterns:
|
||||
- submodule
|
||||
|
||||
#################################
|
||||
# Triggered Only By Labels Jobs #
|
||||
#################################
|
||||
"labels:iperf_stress_test": # example_test
|
||||
labels:
|
||||
- iperf_stress_test
|
||||
included_in:
|
||||
- build:example_test-esp32
|
||||
- build:target_test
|
||||
- test:any_test
|
||||
|
||||
"labels:weekend_test": # custom test
|
||||
labels:
|
||||
- weekend_test
|
||||
included_in:
|
||||
- build:custom_test-esp32
|
||||
- build:target_test
|
||||
- test:any_test
|
||||
|
||||
"labels:nvs_coverage": # host_test
|
||||
labels:
|
||||
- nvs_coverage
|
||||
|
||||
"labels:fuzzer_test-weekend_test": # host test
|
||||
labels:
|
||||
- fuzzer_test
|
||||
- weekend_test
|
||||
@@ -1,305 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2021 Espressif Systems (Shanghai) CO 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.
|
||||
|
||||
import argparse
|
||||
import inspect
|
||||
import os
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from itertools import product
|
||||
|
||||
import yaml
|
||||
|
||||
try:
|
||||
import pygraphviz as pgv
|
||||
except ImportError: # used when pre-commit, skip generating image
|
||||
pass
|
||||
|
||||
try:
|
||||
from typing import Union
|
||||
except ImportError: # used for type hint
|
||||
pass
|
||||
|
||||
IDF_PATH = os.path.abspath(os.getenv('IDF_PATH', os.path.join(os.path.dirname(__file__), '..', '..', '..')))
|
||||
|
||||
|
||||
def _list(str_or_list): # type: (Union[str, list]) -> list
|
||||
if isinstance(str_or_list, str):
|
||||
return [str_or_list]
|
||||
elif isinstance(str_or_list, list):
|
||||
return str_or_list
|
||||
else:
|
||||
raise ValueError('Wrong type: {}. Only supports str or list.'.format(type(str_or_list)))
|
||||
|
||||
|
||||
def _format_nested_dict(_dict, f_tuple): # type: (dict[str, dict], tuple[str, ...]) -> dict[str, dict]
|
||||
res = {}
|
||||
for k, v in _dict.items():
|
||||
k = k.split('__')[0]
|
||||
if isinstance(v, dict):
|
||||
v = _format_nested_dict(v, f_tuple)
|
||||
elif isinstance(v, list):
|
||||
v = _format_nested_list(v, f_tuple)
|
||||
elif isinstance(v, str):
|
||||
v = v.format(*f_tuple)
|
||||
res[k.format(*f_tuple)] = v
|
||||
return res
|
||||
|
||||
|
||||
def _format_nested_list(_list, f_tuple): # type: (list[str], tuple[str, ...]) -> list[str]
|
||||
res = []
|
||||
for item in _list:
|
||||
if isinstance(item, list):
|
||||
item = _format_nested_list(item, f_tuple)
|
||||
elif isinstance(item, dict):
|
||||
item = _format_nested_dict(item, f_tuple)
|
||||
elif isinstance(item, str):
|
||||
item = item.format(*f_tuple)
|
||||
res.append(item)
|
||||
return res
|
||||
|
||||
|
||||
class RulesWriter:
|
||||
AUTO_GENERATE_MARKER = inspect.cleandoc(r'''
|
||||
##################
|
||||
# Auto Generated #
|
||||
##################
|
||||
''')
|
||||
|
||||
LABEL_TEMPLATE = inspect.cleandoc(r'''
|
||||
.if-label-{0}: &if-label-{0}
|
||||
if: '$BOT_LABEL_{1} || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*{0}(?:,[^,\n\r]+)*$/i'
|
||||
''')
|
||||
|
||||
RULE_PROTECTED = ' - <<: *if-protected'
|
||||
RULE_PROTECTED_NO_LABEL = ' - <<: *if-protected-no_label'
|
||||
RULE_BUILD_ONLY = ' - <<: *if-label-build-only\n' \
|
||||
' when: never'
|
||||
RULE_LABEL_TEMPLATE = ' - <<: *if-label-{0}'
|
||||
RULE_PATTERN_TEMPLATE = ' - <<: *if-dev-push\n' \
|
||||
' changes: *patterns-{0}'
|
||||
RULES_TEMPLATE = inspect.cleandoc(r"""
|
||||
.rules:{0}:
|
||||
rules:
|
||||
{1}
|
||||
""")
|
||||
|
||||
KEYWORDS = ['labels', 'patterns']
|
||||
|
||||
def __init__(self, rules_yml, depend_yml): # type: (str, str) -> None
|
||||
self.rules_yml = rules_yml
|
||||
self.rules_cfg = yaml.load(open(rules_yml), Loader=yaml.FullLoader)
|
||||
|
||||
self.full_cfg = yaml.load(open(depend_yml), Loader=yaml.FullLoader)
|
||||
self.cfg = {k: v for k, v in self.full_cfg.items() if not k.startswith('.')}
|
||||
self.cfg = self.expand_matrices()
|
||||
self.rules = self.expand_rules()
|
||||
|
||||
self.graph = None
|
||||
|
||||
def expand_matrices(self): # type: () -> dict
|
||||
"""
|
||||
Expand the matrix into different rules
|
||||
"""
|
||||
res = {}
|
||||
for k, v in self.cfg.items():
|
||||
res.update(self._expand_matrix(k, v))
|
||||
|
||||
for k, v in self.cfg.items():
|
||||
if not v:
|
||||
continue
|
||||
deploy = v.get('deploy')
|
||||
if deploy:
|
||||
for item in _list(deploy):
|
||||
res['{}-{}'.format(k, item)] = v
|
||||
return res
|
||||
|
||||
@staticmethod
|
||||
def _expand_matrix(name, cfg): # type: (str, dict) -> dict
|
||||
"""
|
||||
Expand matrix into multi keys
|
||||
:param cfg: single rule dict
|
||||
:return:
|
||||
"""
|
||||
default = {name: cfg}
|
||||
if not cfg:
|
||||
return default
|
||||
matrices = cfg.pop('matrix', None)
|
||||
if not matrices:
|
||||
return default
|
||||
|
||||
res = {}
|
||||
for comb in product(*_list(matrices)):
|
||||
res.update(_format_nested_dict(default, comb))
|
||||
return res
|
||||
|
||||
def expand_rules(self): # type: () -> dict[str, dict[str, list]]
|
||||
res = defaultdict(lambda: defaultdict(set)) # type: dict[str, dict[str, set]]
|
||||
for k, v in self.cfg.items():
|
||||
if not v:
|
||||
continue
|
||||
for vk, vv in v.items():
|
||||
if vk in self.KEYWORDS:
|
||||
res[k][vk] = set(_list(vv))
|
||||
else:
|
||||
res[k][vk] = vv
|
||||
for key in self.KEYWORDS: # provide empty set for missing field
|
||||
if key not in res[k]:
|
||||
res[k][key] = set()
|
||||
|
||||
for k, v in self.cfg.items():
|
||||
if not v:
|
||||
continue
|
||||
if 'included_in' in v:
|
||||
for item in _list(v['included_in']):
|
||||
if 'labels' in v:
|
||||
res[item]['labels'].update(_list(v['labels']))
|
||||
if 'patterns' in v:
|
||||
for _pat in _list(v['patterns']):
|
||||
# Patterns must be pre-defined
|
||||
if '.patterns-{}'.format(_pat) not in self.rules_cfg:
|
||||
print('WARNING: pattern {} not exists'.format(_pat))
|
||||
continue
|
||||
res[item]['patterns'].add(_pat)
|
||||
|
||||
sorted_res = defaultdict(lambda: defaultdict(list)) # type: dict[str, dict[str, list]]
|
||||
for k, v in res.items():
|
||||
for vk, vv in v.items():
|
||||
sorted_res[k][vk] = sorted(vv)
|
||||
return sorted_res
|
||||
|
||||
def new_labels_str(self): # type: () -> str
|
||||
_labels = set([])
|
||||
for k, v in self.cfg.items():
|
||||
if not v:
|
||||
continue # shouldn't be possible
|
||||
labels = v.get('labels')
|
||||
if not labels:
|
||||
continue
|
||||
_labels.update(_list(labels))
|
||||
labels = sorted(_labels)
|
||||
|
||||
res = ''
|
||||
res += '\n\n'.join([self._format_label(_label) for _label in labels])
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def _format_label(cls, label): # type: (str) -> str
|
||||
return cls.LABEL_TEMPLATE.format(label, cls.bot_label_str(label))
|
||||
|
||||
@staticmethod
|
||||
def bot_label_str(label): # type: (str) -> str
|
||||
return label.upper().replace('-', '_')
|
||||
|
||||
def new_rules_str(self): # type: () -> str
|
||||
res = []
|
||||
for k, v in sorted(self.rules.items()):
|
||||
res.append(self.RULES_TEMPLATE.format(k, self._format_rule(k, v)))
|
||||
return '\n\n'.join(res)
|
||||
|
||||
def _format_rule(self, name, cfg): # type: (str, dict) -> str
|
||||
_rules = []
|
||||
if name.endswith('-production'):
|
||||
_rules.append(self.RULE_PROTECTED_NO_LABEL)
|
||||
else:
|
||||
if not (name.endswith('-preview') or name.startswith('labels:')):
|
||||
_rules.append(self.RULE_PROTECTED)
|
||||
# Special case for esp32c3 example_test, for now it only run with label
|
||||
if name.startswith('test:') or name == 'labels:example_test-esp32c3':
|
||||
_rules.append(self.RULE_BUILD_ONLY)
|
||||
for label in cfg['labels']:
|
||||
_rules.append(self.RULE_LABEL_TEMPLATE.format(label))
|
||||
for pattern in cfg['patterns']:
|
||||
if '.patterns-{}'.format(pattern) in self.rules_cfg:
|
||||
_rules.append(self.RULE_PATTERN_TEMPLATE.format(pattern))
|
||||
else:
|
||||
print('WARNING: pattern {} not exists'.format(pattern))
|
||||
return '\n'.join(_rules)
|
||||
|
||||
def update_rules_yml(self): # type: () -> bool
|
||||
with open(self.rules_yml) as fr:
|
||||
file_str = fr.read()
|
||||
|
||||
auto_generate_str = '\n{}\n\n{}\n'.format(self.new_labels_str(), self.new_rules_str())
|
||||
rest, marker, old = file_str.partition(self.AUTO_GENERATE_MARKER)
|
||||
if old == auto_generate_str:
|
||||
return False
|
||||
else:
|
||||
print(self.rules_yml, 'has been modified. Please check')
|
||||
with open(self.rules_yml, 'w') as fw:
|
||||
fw.write(rest + marker + auto_generate_str)
|
||||
return True
|
||||
|
||||
|
||||
LABEL_COLOR = 'green'
|
||||
PATTERN_COLOR = 'cyan'
|
||||
RULE_COLOR = 'blue'
|
||||
|
||||
|
||||
def build_graph(rules_dict): # type: (dict[str, dict[str, list]]) -> pgv.AGraph
|
||||
graph = pgv.AGraph(directed=True, rankdir='LR', concentrate=True)
|
||||
|
||||
for k, v in rules_dict.items():
|
||||
if not v:
|
||||
continue
|
||||
included_in = v.get('included_in')
|
||||
if included_in:
|
||||
for item in _list(included_in):
|
||||
graph.add_node(k, color=RULE_COLOR)
|
||||
graph.add_node(item, color=RULE_COLOR)
|
||||
graph.add_edge(k, item, color=RULE_COLOR)
|
||||
labels = v.get('labels')
|
||||
if labels:
|
||||
for _label in labels:
|
||||
graph.add_node('label:{}'.format(_label), color=LABEL_COLOR)
|
||||
graph.add_edge('label:{}'.format(_label), k, color=LABEL_COLOR)
|
||||
patterns = v.get('patterns')
|
||||
if patterns:
|
||||
for _pat in patterns:
|
||||
graph.add_node('pattern:{}'.format(_pat), color=PATTERN_COLOR)
|
||||
graph.add_edge('pattern:{}'.format(_pat), k, color=PATTERN_COLOR)
|
||||
|
||||
return graph
|
||||
|
||||
|
||||
def output_graph(graph, output_path='output.png'): # type: (pgv.AGraph, str) -> None
|
||||
graph.layout('dot')
|
||||
if output_path.endswith('.png'):
|
||||
img_path = output_path
|
||||
else:
|
||||
img_path = os.path.join(output_path, 'output.png')
|
||||
graph.draw(img_path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('rules_yml', nargs='?', default=os.path.join(IDF_PATH, '.gitlab', 'ci', 'rules.yml'),
|
||||
help='rules.yml file path')
|
||||
parser.add_argument('dependencies_yml', nargs='?', default=os.path.join(IDF_PATH, '.gitlab', 'ci', 'dependencies',
|
||||
'dependencies.yml'),
|
||||
help='dependencies.yml file path')
|
||||
parser.add_argument('--graph',
|
||||
help='Specify PNG image output path. Use this argument to generate dependency graph')
|
||||
args = parser.parse_args()
|
||||
|
||||
writer = RulesWriter(args.rules_yml, args.dependencies_yml)
|
||||
file_modified = writer.update_rules_yml()
|
||||
|
||||
if args.graph:
|
||||
dep_tree_graph = build_graph(writer.rules)
|
||||
output_graph(dep_tree_graph)
|
||||
|
||||
sys.exit(file_modified)
|
||||
@@ -1,75 +0,0 @@
|
||||
.deploy_job_template:
|
||||
extends: .before_script_no_sync_submodule
|
||||
stage: deploy
|
||||
image: $ESP_ENV_IMAGE
|
||||
tags:
|
||||
- deploy
|
||||
|
||||
push_to_github:
|
||||
extends:
|
||||
- .deploy_job_template
|
||||
- .before_script_minimal
|
||||
- .rules:protected-no_label
|
||||
dependencies: []
|
||||
script:
|
||||
- add_github_ssh_keys
|
||||
- git remote remove github &>/dev/null || true
|
||||
- git remote add github git@github.com:espressif/esp-idf.git
|
||||
- tools/ci/push_to_github.sh
|
||||
|
||||
deploy_test_result:
|
||||
extends:
|
||||
- .deploy_job_template
|
||||
- .before_script_minimal
|
||||
- .rules:ref:master-schedule-always
|
||||
image: $CI_DOCKER_REGISTRY/bot-env
|
||||
tags:
|
||||
- deploy_test
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- ${CI_PROJECT_DIR}/test-management/*.log
|
||||
# save all test logs as artifacts, make it easier to track errors
|
||||
- ${CI_PROJECT_DIR}/TEST_LOGS
|
||||
expire_in: 1 mos
|
||||
variables:
|
||||
UNIT_TEST_CASE_FILE: "${CI_PROJECT_DIR}/components/idf_test/unit_test/TestCaseAll.yml"
|
||||
BOT_ACCOUNT_CONFIG_FILE: "${CI_PROJECT_DIR}/test-management/Config/Account.local.yml"
|
||||
TEST_FW_PATH: "$CI_PROJECT_DIR/tools/tiny-test-fw"
|
||||
AUTO_TEST_SCRIPT_PATH: "${CI_PROJECT_DIR}/auto_test_script"
|
||||
script:
|
||||
- add_gitlab_ssh_keys
|
||||
- export GIT_SHA=$(echo ${CI_COMMIT_SHA} | cut -c 1-8)
|
||||
- export REV_COUNT=$(git rev-list --count HEAD)
|
||||
- export SUMMARY="IDF CI test result for $GIT_SHA (r${REV_COUNT})"
|
||||
# artifacts of job update_test_cases creates test-management folder
|
||||
# we need to remove it so we can clone test-management folder again
|
||||
- rm -rf test-management
|
||||
- retry_failed git clone $TEST_MANAGEMENT_REPO
|
||||
- python3 $CHECKOUT_REF_SCRIPT test-management test-management
|
||||
- cd test-management
|
||||
- echo $BOT_JIRA_ACCOUNT > ${BOT_ACCOUNT_CONFIG_FILE}
|
||||
# update test results
|
||||
- python3 ImportTestResult.py -r "$GIT_SHA (r${REV_COUNT})" -j $JIRA_TEST_MANAGEMENT_PROJECT -s "$SUMMARY" -l CI -p ${CI_PROJECT_DIR}/TEST_LOGS --pipeline_url ${CI_PIPELINE_URL}
|
||||
|
||||
check_submodule_sync:
|
||||
extends:
|
||||
- .deploy_job_template
|
||||
- .rules:test:submodule
|
||||
tags:
|
||||
- github_sync
|
||||
retry: 2
|
||||
variables:
|
||||
GIT_STRATEGY: clone
|
||||
SUBMODULES_TO_FETCH: "none"
|
||||
PUBLIC_IDF_URL: "https://github.com/espressif/esp-idf.git"
|
||||
dependencies: []
|
||||
script:
|
||||
- git submodule deinit --force .
|
||||
# setting the default remote URL to the public one, to resolve relative location URLs
|
||||
- git config remote.origin.url ${PUBLIC_IDF_URL}
|
||||
# check if all submodules are correctly synced to public repository
|
||||
- git submodule init
|
||||
- git config --get-regexp '^submodule\..*\.url$' || true
|
||||
- git submodule update --recursive
|
||||
- echo "IDF was cloned from ${PUBLIC_IDF_URL} completely"
|
||||
@@ -1,230 +0,0 @@
|
||||
.patterns-docs: &patterns-docs
|
||||
- ".gitlab/ci/docs.yml"
|
||||
- "docs/**/*"
|
||||
- "components/**/*.h"
|
||||
- "components/**/Kconfig*"
|
||||
- "components/**/CMakeList.txt"
|
||||
- "components/**/sdkconfig*"
|
||||
- "tools/kconfig_new/**/*"
|
||||
- "CONTRIBUTING.rst"
|
||||
|
||||
.patterns-docs-preview: &patterns-docs-preview
|
||||
- "docs/**/*"
|
||||
|
||||
.if-protected: &if-protected
|
||||
if: '($CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_BRANCH =~ /^release\/v/ || $CI_COMMIT_TAG =~ /^v\d+\.\d+(\.\d+)?($|-)/)'
|
||||
|
||||
.if-protected-no_label: &if-protected-no_label
|
||||
if: '($CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_BRANCH =~ /^release\/v/ || $CI_COMMIT_TAG =~ /^v\d+\.\d+(\.\d+)?($|-)/) && $BOT_TRIGGER_WITH_LABEL == null'
|
||||
|
||||
.if-label-build_docs: &if-label-build_docs
|
||||
if: '$BOT_LABEL_BUILD_DOCS || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*build_docs(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-docs: &if-label-docs
|
||||
if: '$BOT_LABEL_DOCS || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*docs(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-docs_full: &if-label-docs_full
|
||||
if: '$BOT_LABEL_DOCS_FULL || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*docs_full(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-dev-push: &if-dev-push
|
||||
if: '$CI_COMMIT_REF_NAME != "master" && $CI_COMMIT_BRANCH !~ /^release\/v/ && $CI_COMMIT_TAG !~ /^v\d+\.\d+(\.\d+)?($|-)/ && ($CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event")'
|
||||
|
||||
.doc-rules:build:docs:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build_docs
|
||||
- <<: *if-label-docs
|
||||
- <<: *if-label-docs_full
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-docs
|
||||
|
||||
# stage: pre_check
|
||||
check_readme_links:
|
||||
extends:
|
||||
- .pre_check_job_template
|
||||
tags: ["build", "amd64", "internet"]
|
||||
allow_failure: true
|
||||
script:
|
||||
- python ${IDF_PATH}/tools/ci/check_readme_links.py
|
||||
|
||||
check_docs_lang_sync:
|
||||
extends:
|
||||
- .pre_check_job_template
|
||||
- .doc-rules:build:docs
|
||||
script:
|
||||
- cd docs
|
||||
- ./check_lang_folder_sync.sh
|
||||
|
||||
.build_docs_template:
|
||||
image: $ESP_IDF_DOC_ENV_IMAGE
|
||||
variables:
|
||||
PYTHON_VER: 3.6.13
|
||||
tags:
|
||||
- build_docs
|
||||
dependencies: []
|
||||
script:
|
||||
- cd docs
|
||||
- pip install -r requirements.txt
|
||||
- build-docs -t $DOCTGT -bs $DOC_BUILDERS -l $DOCLANG build
|
||||
parallel:
|
||||
matrix:
|
||||
- DOCLANG: ["en", "zh_CN"]
|
||||
DOCTGT: ["esp32", "esp32s2", "esp32s3", "esp32c3"]
|
||||
|
||||
check_docs_gh_links:
|
||||
image: $ESP_IDF_DOC_ENV_IMAGE
|
||||
variables:
|
||||
PYTHON_VER: 3.6.13
|
||||
extends:
|
||||
- .pre_check_job_template
|
||||
- .doc-rules:build:docs
|
||||
script:
|
||||
- cd docs
|
||||
- pip install -r requirements.txt
|
||||
- build-docs gh-linkcheck
|
||||
|
||||
# stage: build_doc
|
||||
# Add this stage to let the build_docs job run in parallel with build
|
||||
.build_docs_build_stage_template:
|
||||
extends:
|
||||
- .build_docs_template
|
||||
stage: build_doc
|
||||
needs:
|
||||
- job: check_docs_lang_sync
|
||||
artifacts: false
|
||||
- job: check_docs_gh_links
|
||||
artifacts: false
|
||||
|
||||
# Doc jobs have a lot of special cases, we specify rules here directly instead
|
||||
# in dependencies.yml to simplify things
|
||||
build_docs_html_full:
|
||||
extends:
|
||||
- .build_docs_build_stage_template
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-docs_full
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- docs/_build/*/*/*.txt
|
||||
- docs/_build/*/*/html/*
|
||||
expire_in: 4 days
|
||||
variables:
|
||||
DOC_BUILDERS: "html"
|
||||
|
||||
build_docs_html_fast:
|
||||
extends:
|
||||
- .build_docs_build_stage_template
|
||||
rules:
|
||||
- <<: *if-label-docs_full
|
||||
when: never
|
||||
- <<: *if-label-build_docs
|
||||
- <<: *if-label-docs
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-docs
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- docs/_build/*/*/*.txt
|
||||
- docs/_build/*/*/html/*
|
||||
expire_in: 4 days
|
||||
variables:
|
||||
DOC_BUILDERS: "html"
|
||||
DOCS_FAST_BUILD: "yes"
|
||||
|
||||
build_docs_pdf:
|
||||
extends:
|
||||
- .build_docs_build_stage_template
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-docs_full
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- docs/_build/*/*/latex/*
|
||||
expire_in: 4 days
|
||||
variables:
|
||||
DOC_BUILDERS: "latex"
|
||||
|
||||
.deploy_docs_template:
|
||||
extends:
|
||||
- .before_script_no_sync_submodule
|
||||
image: $ESP_IDF_DOC_ENV_IMAGE
|
||||
variables:
|
||||
PYTHON_VER: 3.6.13
|
||||
stage: test_deploy
|
||||
tags:
|
||||
- deploy
|
||||
- shiny
|
||||
variables:
|
||||
DOCS_BUILD_DIR: "${IDF_PATH}/docs/_build/"
|
||||
PYTHONUNBUFFERED: 1
|
||||
dependencies: []
|
||||
script:
|
||||
- add_doc_server_ssh_keys $DOCS_DEPLOY_PRIVATEKEY $DOCS_DEPLOY_SERVER $DOCS_DEPLOY_SERVER_USER
|
||||
- export GIT_VER=$(git describe --always)
|
||||
- pip install -r docs/requirements.txt
|
||||
- deploy-docs
|
||||
|
||||
# stage: test_deploy
|
||||
deploy_docs_preview:
|
||||
extends:
|
||||
- .deploy_docs_template
|
||||
rules:
|
||||
- <<: *if-label-build_docs
|
||||
- <<: *if-label-docs
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-docs-preview
|
||||
dependencies:
|
||||
- build_docs_html_fast
|
||||
- build_docs_html_full
|
||||
- build_docs_pdf
|
||||
variables:
|
||||
TYPE: "preview"
|
||||
# older branches use DOCS_DEPLOY_KEY, DOCS_SERVER, DOCS_SERVER_USER, DOCS_PATH for preview server so we keep these names for 'preview'
|
||||
DOCS_DEPLOY_PRIVATEKEY: "$DOCS_DEPLOY_KEY"
|
||||
DOCS_DEPLOY_SERVER: "$DOCS_SERVER"
|
||||
DOCS_DEPLOY_SERVER_USER: "$DOCS_SERVER_USER"
|
||||
DOCS_DEPLOY_PATH: "$DOCS_PATH"
|
||||
DOCS_DEPLOY_URL_BASE: "https://$DOCS_PREVIEW_SERVER_URL/docs/esp-idf"
|
||||
|
||||
# stage: post_deploy
|
||||
deploy_docs_production:
|
||||
# The DOCS_PROD_* variables used by this job are "Protected" so these branches must all be marked "Protected" in Gitlab settings
|
||||
extends:
|
||||
- .deploy_docs_template
|
||||
rules:
|
||||
- <<: *if-protected-no_label
|
||||
stage: post_deploy
|
||||
dependencies: # set dependencies to null to avoid missing artifacts issue
|
||||
needs: # ensure runs after push_to_github succeeded
|
||||
- build_docs_html_full
|
||||
- build_docs_pdf
|
||||
- job: push_to_github
|
||||
artifacts: false
|
||||
variables:
|
||||
TYPE: "preview"
|
||||
DOCS_DEPLOY_PRIVATEKEY: "$DOCS_PROD_DEPLOY_KEY"
|
||||
DOCS_DEPLOY_SERVER: "$DOCS_PROD_SERVER"
|
||||
DOCS_DEPLOY_SERVER_USER: "$DOCS_PROD_SERVER_USER"
|
||||
DOCS_DEPLOY_PATH: "$DOCS_PROD_PATH"
|
||||
DOCS_DEPLOY_URL_BASE: "https://docs.espressif.com/projects/esp-idf"
|
||||
|
||||
check_doc_links:
|
||||
extends:
|
||||
- .build_docs_template
|
||||
- .rules:protected
|
||||
stage: post_deploy
|
||||
tags: ["build", "amd64", "internet"]
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- docs/_build/*/*/*.txt
|
||||
- docs/_build/*/*/linkcheck/*.txt
|
||||
expire_in: 1 week
|
||||
allow_failure: true
|
||||
script:
|
||||
- cd docs
|
||||
- pip install -r requirements.txt
|
||||
# At the moment this check will always fail due to multiple known limitations, ignore result
|
||||
- build-docs -t $DOCTGT -l $DOCLANG linkcheck || { echo "THERE ARE ISSUES DUE TO KNOWN LIMITATIONS, PLEASE FIX THEM. Nowadays we're ignored them to pass pipeline."; true; }
|
||||
@@ -1,373 +0,0 @@
|
||||
.host_test_template:
|
||||
extends: .rules:test:host_test
|
||||
stage: host_test
|
||||
image: $ESP_ENV_IMAGE
|
||||
variables:
|
||||
PYTHON_VER: 3.6.13
|
||||
tags:
|
||||
- host_test
|
||||
dependencies: []
|
||||
needs: [] # run host_test jobs immediately
|
||||
|
||||
test_nvs_on_host:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd components/nvs_flash/test_nvs_host
|
||||
- make test
|
||||
|
||||
test_nvs_coverage:
|
||||
extends:
|
||||
- .host_test_template
|
||||
- .rules:labels:nvs_coverage
|
||||
artifacts:
|
||||
paths:
|
||||
- components/nvs_flash/test_nvs_host/coverage_report
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- cd components/nvs_flash/test_nvs_host
|
||||
- make coverage_report
|
||||
# the 'long' host tests take approx 11 hours on our current runners. Adding some margin here for possible CPU contention
|
||||
timeout: 18 hours
|
||||
|
||||
test_partition_table_on_host:
|
||||
extends: .host_test_template
|
||||
tags:
|
||||
- build
|
||||
script:
|
||||
- cd components/partition_table/test_gen_esp32part_host
|
||||
- ./gen_esp32part_tests.py
|
||||
|
||||
test_wl_on_host:
|
||||
extends: .host_test_template
|
||||
artifacts:
|
||||
paths:
|
||||
- components/wear_levelling/test_wl_host/coverage_report.zip
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- cd components/wear_levelling/test_wl_host
|
||||
- make test
|
||||
|
||||
test_fatfs_on_host:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd components/fatfs/test_fatfs_host/
|
||||
- make test
|
||||
|
||||
test_ldgen_on_host:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd tools/ldgen/test
|
||||
- ./test_fragments.py
|
||||
- ./test_generation.py
|
||||
- ./test_entity.py
|
||||
- ./test_output_commands.py
|
||||
variables:
|
||||
LC_ALL: C.UTF-8
|
||||
|
||||
.host_fuzzer_test_template:
|
||||
extends:
|
||||
- .host_test_template
|
||||
- .rules:labels:fuzzer_test-weekend_test
|
||||
image: $AFL_FUZZER_TEST_IMAGE
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- ${FUZZER_TEST_DIR}/out/crashes
|
||||
- ${FUZZER_TEST_DIR}/fuzz_output.log
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- export AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 && export AFL_SKIP_CPUFREQ=1
|
||||
- cd ${FUZZER_TEST_DIR}
|
||||
# run AFL fuzzer for one hour
|
||||
- ( ( make ${FUZZER_PARAMS} fuzz | tee fuzz_output.log | grep -v '\(Fuzzing test case\|Entering queue cycle\)' ) || pkill sleep ) &
|
||||
- ( sleep 3600 || mkdir -p out/crashes/env_failed ) && pkill afl-fuz
|
||||
# check no crashes found
|
||||
- test -z "$(ls out/crashes/)" || exit 1
|
||||
|
||||
test_mdns_fuzzer_on_host:
|
||||
extends: .host_fuzzer_test_template
|
||||
variables:
|
||||
FUZZER_TEST_DIR: components/mdns/test_afl_fuzz_host
|
||||
|
||||
test_lwip_dns_fuzzer_on_host:
|
||||
extends: .host_fuzzer_test_template
|
||||
variables:
|
||||
FUZZER_TEST_DIR: components/lwip/test_afl_host
|
||||
FUZZER_PARAMS: MODE=dns
|
||||
|
||||
test_lwip_dhcp_fuzzer_on_host:
|
||||
extends: .host_fuzzer_test_template
|
||||
variables:
|
||||
FUZZER_TEST_DIR: components/lwip/test_afl_host
|
||||
FUZZER_PARAMS: MODE=dhcp_client
|
||||
|
||||
test_lwip_dhcps_fuzzer_on_host:
|
||||
extends: .host_fuzzer_test_template
|
||||
variables:
|
||||
FUZZER_TEST_DIR: components/lwip/test_afl_host
|
||||
FUZZER_PARAMS: MODE=dhcp_server
|
||||
|
||||
test_spiffs_on_host:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd components/spiffs/test_spiffs_host/
|
||||
- make test
|
||||
- cd ../test_spiffsgen
|
||||
- ./test_spiffsgen.py
|
||||
|
||||
test_multi_heap_on_host:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd components/heap/test_multi_heap_host
|
||||
- ./test_all_configs.sh
|
||||
|
||||
test_certificate_bundle_on_host:
|
||||
extends: .host_test_template
|
||||
tags:
|
||||
- build
|
||||
script:
|
||||
- cd components/mbedtls/esp_crt_bundle/test_gen_crt_bundle/
|
||||
- ./test_gen_crt_bundle.py
|
||||
|
||||
test_confserver:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd tools/kconfig_new/test/confserver
|
||||
- ./test_confserver.py
|
||||
|
||||
test_gen_kconfig_doc:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd tools/kconfig_new/test/gen_kconfig_doc/
|
||||
- ./test_target_visibility.py
|
||||
- ./test_kconfig_out.py
|
||||
|
||||
test_confgen:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd tools/kconfig_new/test/confgen/
|
||||
- ./test_confgen.py
|
||||
|
||||
test_idf_monitor:
|
||||
extends: .host_test_template
|
||||
artifacts:
|
||||
# save artifacts always in order to access results which were retried without consequent failure
|
||||
when: always
|
||||
paths:
|
||||
- tools/test_idf_monitor/outputs/*
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- cd ${IDF_PATH}/tools/test_idf_monitor
|
||||
- ./run_test_idf_monitor.py
|
||||
|
||||
test_idf_size:
|
||||
extends: .host_test_template
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
- tools/test_idf_size/output
|
||||
- tools/test_idf_size/.coverage
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- cd ${IDF_PATH}/tools/test_idf_size
|
||||
- ./test.sh
|
||||
|
||||
test_idf_py:
|
||||
extends: .host_test_template
|
||||
variables:
|
||||
LC_ALL: C.UTF-8
|
||||
script:
|
||||
- cd ${IDF_PATH}/tools/test_idf_py
|
||||
- ./test_idf_py.py
|
||||
|
||||
test_idf_tools:
|
||||
extends: .host_test_template
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
- tools/tools.new.json
|
||||
expire_in: 1 week
|
||||
script:
|
||||
# Remove Xtensa and ULP toolchains from the PATH, tests will expect a clean environment
|
||||
- export PATH=$(p=$(echo $PATH | tr ":" "\n" | grep -v "/root/.espressif/tools\|/opt/espressif" | tr "\n" ":"); echo ${p%:})
|
||||
- cd ${IDF_PATH}/tools/test_idf_tools
|
||||
- ./test_idf_tools.py
|
||||
# Test for create virtualenv. It must be invoked from Python, not from virtualenv.
|
||||
- cd ${IDF_PATH}/tools
|
||||
- python3 ./idf_tools.py install-python-env
|
||||
|
||||
.test_efuse_table_on_host_template:
|
||||
extends: .host_test_template
|
||||
variables:
|
||||
IDF_TARGET: "esp32"
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
- components/efuse/${IDF_TARGET}/esp_efuse_table.c
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- cd ${IDF_PATH}/components/efuse/
|
||||
- ./efuse_table_gen.py -t "${IDF_TARGET}" ${IDF_PATH}/components/efuse/${IDF_TARGET}/esp_efuse_table.csv
|
||||
- git diff --exit-code -- ${IDF_TARGET}/esp_efuse_table.c || { echo 'Differences found for ${IDF_TARGET} target. Please run make efuse_common_table or idf.py efuse-common-table and commit the changes.'; exit 1; }
|
||||
- cd ${IDF_PATH}/components/efuse/test_efuse_host
|
||||
- ./efuse_tests.py
|
||||
|
||||
test_efuse_table_on_host_esp32:
|
||||
extends: .test_efuse_table_on_host_template
|
||||
|
||||
test_efuse_table_on_host_esp32s2:
|
||||
extends: .test_efuse_table_on_host_template
|
||||
variables:
|
||||
IDF_TARGET: esp32s2
|
||||
|
||||
test_efuse_table_on_host_esp32s3:
|
||||
extends: .test_efuse_table_on_host_template
|
||||
variables:
|
||||
IDF_TARGET: esp32s3
|
||||
|
||||
test_efuse_table_on_host_esp32c3:
|
||||
extends: .test_efuse_table_on_host_template
|
||||
variables:
|
||||
IDF_TARGET: esp32c3
|
||||
|
||||
test_efuse_table_on_host_esp32h2:
|
||||
extends: .test_efuse_table_on_host_template
|
||||
variables:
|
||||
IDF_TARGET: esp32h2
|
||||
|
||||
test_espcoredump:
|
||||
extends: .host_test_template
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- components/espcoredump/test/**/.coverage
|
||||
- components/espcoredump/test/**/output
|
||||
expire_in: 1 week
|
||||
variables:
|
||||
IDF_COREDUMP_ELF_REPO: "https://gitlab-ci-token:${BOT_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/idf/idf-coredump-elf.git"
|
||||
IDF_COREDUMP_ELF_TAG: idf-20210910-00
|
||||
# install CMake version specified in tools.json
|
||||
SETUP_TOOLS_LIST: "all"
|
||||
script:
|
||||
- retry_failed git clone ${IDF_COREDUMP_ELF_REPO} -b $IDF_COREDUMP_ELF_TAG
|
||||
- cd ${IDF_PATH}/components/espcoredump/test/
|
||||
- ./test_espcoredump.sh ${CI_PROJECT_DIR}/idf-coredump-elf
|
||||
|
||||
test_logtrace_proc:
|
||||
extends: .host_test_template
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
- tools/esp_app_trace/test/logtrace/output
|
||||
- tools/esp_app_trace/test/logtrace/.coverage
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- cd ${IDF_PATH}/tools/esp_app_trace/test/logtrace
|
||||
- ./test.sh
|
||||
|
||||
test_sysviewtrace_proc:
|
||||
extends: .host_test_template
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
- tools/esp_app_trace/test/sysview/output
|
||||
- tools/esp_app_trace/test/sysview/.coverage
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- cd ${IDF_PATH}/tools/esp_app_trace/test/sysview
|
||||
- ./test.sh
|
||||
|
||||
test_mkdfu:
|
||||
extends: .host_test_template
|
||||
variables:
|
||||
LC_ALL: C.UTF-8
|
||||
script:
|
||||
- cd ${IDF_PATH}/tools/test_mkdfu
|
||||
- ./test_mkdfu.py
|
||||
|
||||
test_mkuf2:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/tools/test_mkuf2
|
||||
- ./test_mkuf2.py
|
||||
|
||||
test_autocomplete:
|
||||
extends: .host_test_template
|
||||
image: $CI_DOCKER_REGISTRY/linux-shells:1
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
- ${IDF_PATH}/*.out
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- ${IDF_PATH}/tools/ci/test_autocomplete.py
|
||||
|
||||
test_detect_python:
|
||||
extends: .host_test_template
|
||||
image: $CI_DOCKER_REGISTRY/linux-shells:1
|
||||
script:
|
||||
- cd ${IDF_PATH}
|
||||
- shellcheck -s sh tools/detect_python.sh
|
||||
- shellcheck -s bash tools/detect_python.sh
|
||||
- shellcheck -s dash tools/detect_python.sh
|
||||
- "bash -c '. tools/detect_python.sh && echo Our Python: ${ESP_PYTHON?Python is not set}'"
|
||||
- "dash -c '. tools/detect_python.sh && echo Our Python: ${ESP_PYTHON?Python is not set}'"
|
||||
- "zsh -c '. tools/detect_python.sh && echo Our Python: ${ESP_PYTHON?Python is not set}'"
|
||||
- "fish -c 'source tools/detect_python.fish && echo Our Python: $ESP_PYTHON'"
|
||||
|
||||
test_nvs_page:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/components/nvs_flash/host_test/nvs_page_test
|
||||
- idf.py build
|
||||
- build/test_nvs_page_host.elf
|
||||
|
||||
test_log:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/components/log/host_test/log_test
|
||||
- idf.py build
|
||||
- build/test_log_host.elf
|
||||
|
||||
test_esp_event:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/components/esp_event/host_test/esp_event_unit_test
|
||||
- idf.py build
|
||||
- build/test_esp_event_host.elf
|
||||
|
||||
test_esp_timer_cxx:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/host_test/esp_timer
|
||||
- idf.py build
|
||||
- build/test_esp_timer_cxx_host.elf
|
||||
|
||||
test_eh_frame_parser:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/components/esp_system/test_eh_frame_parser
|
||||
- make
|
||||
- ./eh_frame_test
|
||||
|
||||
test_rom_on_linux_works:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/components/esp_rom/host_test/rom_test
|
||||
- idf.py build
|
||||
- build/test_rom_host.elf
|
||||
|
||||
test_cxx_gpio:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/host_test/gpio
|
||||
- idf.py build
|
||||
- build/test_gpio_cxx_host.elf
|
||||
|
||||
test_linux_example:
|
||||
extends: .host_test_template
|
||||
script:
|
||||
- cd ${IDF_PATH}/examples/build_system/cmake/linux_host_app
|
||||
- idf.py build
|
||||
- timeout 5 ./build/linux_host_app.elf >test.log || true
|
||||
- grep "Restarting" test.log
|
||||
@@ -1,195 +0,0 @@
|
||||
.pre_check_base_template:
|
||||
stage: pre_check
|
||||
image: $ESP_ENV_IMAGE
|
||||
tags:
|
||||
- host_test
|
||||
dependencies: []
|
||||
|
||||
.pre_check_job_template:
|
||||
extends:
|
||||
- .pre_check_base_template
|
||||
- .before_script_no_sync_submodule
|
||||
|
||||
.check_pre_commit_template:
|
||||
extends: .pre_check_job_template
|
||||
image: "$CI_DOCKER_REGISTRY/esp-idf-pre-commit:1"
|
||||
before_script:
|
||||
- source tools/ci/utils.sh
|
||||
- export PYTHONPATH="$CI_PROJECT_DIR/tools:$CI_PROJECT_DIR/tools/ci/python_packages:$PYTHONPATH"
|
||||
|
||||
check_pre_commit_master_release:
|
||||
extends:
|
||||
- .check_pre_commit_template
|
||||
- .rules:protected
|
||||
script:
|
||||
- git diff-tree --no-commit-id --name-only -r $CI_COMMIT_SHA | xargs pre-commit run --files
|
||||
|
||||
check_pre_commit_MR:
|
||||
extends:
|
||||
- .check_pre_commit_template
|
||||
- .rules:dev
|
||||
script:
|
||||
- python ${CI_PROJECT_DIR}/tools/ci/ci_get_mr_info.py files ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} | xargs pre-commit run --files
|
||||
|
||||
check_version:
|
||||
# Don't run this for feature/bugfix branches, so that it is possible to modify
|
||||
# esp_idf_version.h in a branch before tagging the next version.
|
||||
extends:
|
||||
- .pre_check_job_template
|
||||
- .rules:protected
|
||||
script:
|
||||
- export IDF_PATH=$PWD
|
||||
- tools/ci/check_idf_version.sh
|
||||
|
||||
check_examples_cmake_make:
|
||||
extends: .pre_check_job_template
|
||||
script:
|
||||
- python ${IDF_PATH}/tools/ci/check_examples_cmake_make.py
|
||||
|
||||
check_rom_api_header:
|
||||
extends: .pre_check_job_template
|
||||
script:
|
||||
- tools/ci/check_examples_rom_header.sh
|
||||
- tools/ci/check_api_violation.sh
|
||||
|
||||
check_python_style:
|
||||
extends:
|
||||
- .pre_check_base_template
|
||||
- .rules:patterns:python-files
|
||||
variables:
|
||||
PYTHON_VER: 3.6.13
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
- flake8_output.txt
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- python -m flake8 --config=$IDF_PATH/.flake8 --output-file=flake8_output.txt --tee --benchmark $IDF_PATH
|
||||
|
||||
test_check_kconfigs:
|
||||
extends: .pre_check_job_template
|
||||
variables:
|
||||
PYTHON_VER: 3.6.13
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
- components/*/Kconfig*.new
|
||||
- examples/*/*/*/Kconfig*.new
|
||||
- examples/*/*/*/*/Kconfig*.new
|
||||
- tools/*/Kconfig*.new
|
||||
- tools/*/*/Kconfig*.new
|
||||
- tools/*/*/*/Kconfig*.new
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- python ${IDF_PATH}/tools/ci/test_check_kconfigs.py
|
||||
|
||||
check_wifi_lib_md5:
|
||||
extends: .pre_check_base_template
|
||||
tags:
|
||||
- build
|
||||
variables:
|
||||
SUBMODULES_TO_FETCH: "components/esp_wifi/lib"
|
||||
script:
|
||||
- IDF_TARGET=esp32 $IDF_PATH/components/esp_wifi/test_md5/test_md5.sh
|
||||
- IDF_TARGET=esp32s2 $IDF_PATH/components/esp_wifi/test_md5/test_md5.sh
|
||||
|
||||
check_fuzzer_compilation:
|
||||
extends: .pre_check_base_template
|
||||
image: $AFL_FUZZER_TEST_IMAGE
|
||||
script:
|
||||
- cd ${IDF_PATH}/components/lwip/test_afl_host
|
||||
- make MODE=dhcp_server
|
||||
- make MODE=dhcp_client
|
||||
- make MODE=dns
|
||||
- cd ${IDF_PATH}/components/mdns/test_afl_fuzz_host
|
||||
- make
|
||||
|
||||
check_public_headers:
|
||||
extends:
|
||||
- .pre_check_base_template
|
||||
- .rules:build
|
||||
tags:
|
||||
- build
|
||||
script:
|
||||
- python tools/ci/check_public_headers.py --jobs 4 --prefix xtensa-esp32-elf-
|
||||
|
||||
check_soc_struct_headers:
|
||||
extends:
|
||||
- .pre_check_base_template
|
||||
- .rules:build
|
||||
tags:
|
||||
- build
|
||||
script:
|
||||
- find ${IDF_PATH}/components/soc/*/include/soc/ -name "*_struct.h" -print0 | xargs -0 -n1 ./tools/ci/check_soc_struct_headers.py
|
||||
|
||||
check_esp_err_to_name:
|
||||
extends:
|
||||
- .pre_check_base_template
|
||||
- .rules:build
|
||||
tags:
|
||||
- build
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
- components/esp_common/esp_err_to_name.c
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- cd ${IDF_PATH}/tools/
|
||||
- ./gen_esp_err_to_name.py
|
||||
- git diff --exit-code -- ../components/esp_common/src/esp_err_to_name.c || { echo 'Differences found. Please run gen_esp_err_to_name.py and commit the changes.'; exit 1; }
|
||||
|
||||
scan_tests:
|
||||
extends:
|
||||
- .pre_check_base_template
|
||||
- .rules:build:target_test
|
||||
image: $CI_DOCKER_REGISTRY/ubuntu-test-env$BOT_DOCKER_IMAGE_TAG
|
||||
tags:
|
||||
- assign_test
|
||||
artifacts:
|
||||
paths:
|
||||
- $EXAMPLE_TEST_OUTPUT_DIR
|
||||
- $TEST_APPS_OUTPUT_DIR
|
||||
- $COMPONENT_UT_OUTPUT_DIR
|
||||
variables:
|
||||
EXAMPLE_TEST_DIR: ${CI_PROJECT_DIR}/examples
|
||||
EXAMPLE_TEST_OUTPUT_DIR: ${CI_PROJECT_DIR}/examples/test_configs
|
||||
TEST_APPS_TEST_DIR: ${CI_PROJECT_DIR}/tools/test_apps
|
||||
TEST_APPS_OUTPUT_DIR: ${CI_PROJECT_DIR}/tools/test_apps/test_configs
|
||||
COMPONENT_UT_OUTPUT_DIR: ${CI_PROJECT_DIR}/component_ut/test_configs
|
||||
CI_SCAN_TESTS_PY: ${CI_PROJECT_DIR}/tools/ci/python_packages/ttfw_idf/CIScanTests.py
|
||||
script:
|
||||
- set_component_ut_vars
|
||||
- run_cmd python $CI_SCAN_TESTS_PY example_test $EXAMPLE_TEST_DIR -b make --exclude examples/build_system/idf_as_lib -c $CI_TARGET_TEST_CONFIG_FILE -o $EXAMPLE_TEST_OUTPUT_DIR
|
||||
- run_cmd python $CI_SCAN_TESTS_PY example_test $EXAMPLE_TEST_DIR -b cmake --exclude examples/build_system/idf_as_lib -c $CI_TARGET_TEST_CONFIG_FILE -o $EXAMPLE_TEST_OUTPUT_DIR
|
||||
- run_cmd python $CI_SCAN_TESTS_PY test_apps $TEST_APPS_TEST_DIR -c $CI_TARGET_TEST_CONFIG_FILE -o $TEST_APPS_OUTPUT_DIR
|
||||
- run_cmd python $CI_SCAN_TESTS_PY component_ut $COMPONENT_UT_DIRS --exclude $COMPONENT_UT_EXCLUDES -c $CI_TARGET_TEST_CONFIG_FILE -o $COMPONENT_UT_OUTPUT_DIR
|
||||
|
||||
# For release tag pipelines only, make sure the tag was created with 'git tag -a' so it will update
|
||||
# the version returned by 'git describe'
|
||||
check_version_tag:
|
||||
extends:
|
||||
- .pre_check_job_template
|
||||
- .rules:tag:release
|
||||
script:
|
||||
- (git cat-file -t $CI_COMMIT_REF_NAME | grep tag) || (echo "ESP-IDF versions must be annotated tags." && exit 1)
|
||||
|
||||
check_ut_cmake_make:
|
||||
extends: .pre_check_job_template
|
||||
tags:
|
||||
- build
|
||||
script:
|
||||
- tools/ci/check_ut_cmake_make.sh
|
||||
|
||||
check_artifacts_expire_time:
|
||||
extends: .pre_check_job_template
|
||||
script:
|
||||
# check if we have set expire time for all artifacts
|
||||
- python tools/ci/check_artifacts_expire_time.py
|
||||
|
||||
check_commit_msg:
|
||||
extends: .pre_check_job_template
|
||||
script:
|
||||
- git status
|
||||
- git log -n10 --oneline
|
||||
# commit start with "WIP: " need to be squashed before merge
|
||||
- 'git log --pretty=%s master.. -- | grep "^WIP: " && exit 1 || exit 0'
|
||||
@@ -1,971 +0,0 @@
|
||||
############
|
||||
# Patterns #
|
||||
############
|
||||
.patterns-c-files: &patterns-c-files
|
||||
- ".gitlab/ci/static-code-analysis.yml"
|
||||
|
||||
- "tools/ci/static-analysis-rules.yml"
|
||||
- "tools/ci/clang_tidy_dirs.txt"
|
||||
|
||||
- "**/*.{c,C}"
|
||||
- "**/*.{h,H}"
|
||||
- "components/**/Kconfig"
|
||||
- "components/**/CMakeList.txt"
|
||||
|
||||
.patterns-python-files: &patterns-python-files
|
||||
- ".gitlab/ci/static-code-analysis.yml"
|
||||
- "**/*.py"
|
||||
|
||||
.patterns-sonarqube-files: &patterns-sonarqube-files
|
||||
- "tools/ci/sonar_exclude_list.txt"
|
||||
|
||||
.patterns-example_test: &patterns-example_test
|
||||
- "tools/ci/python_packages/gitlab_api.py"
|
||||
- "tools/ci/python_packages/idf_http_server_test/**/*"
|
||||
- "tools/ci/python_packages/idf_iperf_test_util/**/*"
|
||||
- "tools/ci/python_packages/tiny_test_fw/**/*"
|
||||
- "tools/ci/python_packages/ttfw_idf/**/*"
|
||||
|
||||
- "tools/ci/find_apps_build_apps.sh"
|
||||
- "tools/build_apps.py"
|
||||
- "tools/find_apps.py"
|
||||
- "tools/find_build_apps/**/*"
|
||||
|
||||
- "tools/esp_prov/**/*"
|
||||
- "examples/**/*"
|
||||
|
||||
.patterns-build-example_test: &patterns-build-example_test
|
||||
- "tools/ci/build_example_dirs.txt"
|
||||
- "tools/ci/get_supported_examples.sh"
|
||||
|
||||
.patterns-build_components: &patterns-build_components
|
||||
- "components/**/*"
|
||||
- "examples/cxx/experimental/experimental_cpp_component/*"
|
||||
|
||||
.patterns-build_system: &patterns-build_system
|
||||
- "tools/cmake/**/*"
|
||||
- "tools/kconfig_new/**/*"
|
||||
- "tools/tools.json"
|
||||
- "tools/ci/test_build_system*.sh"
|
||||
|
||||
.patterns-custom_test: &patterns-custom_test
|
||||
- "components/espcoredump/**/*"
|
||||
|
||||
- "tools/ci/python_packages/gitlab_api.py"
|
||||
- "tools/ci/python_packages/tiny_test_fw/**/*"
|
||||
- "tools/ci/python_packages/ttfw_idf/**/*"
|
||||
|
||||
- "tools/ci/find_apps_build_apps.sh"
|
||||
- "tools/build_apps.py"
|
||||
- "tools/find_apps.py"
|
||||
- "tools/find_build_apps/**/*"
|
||||
|
||||
- "tools/test_apps/**/*"
|
||||
- "tools/ldgen/**/*"
|
||||
|
||||
.patterns-unit_test: &patterns-unit_test
|
||||
- "tools/ci/python_packages/gitlab_api.py"
|
||||
- "tools/ci/python_packages/tiny_test_fw/**/*"
|
||||
- "tools/ci/python_packages/ttfw_idf/**/*"
|
||||
|
||||
- "tools/ci/find_apps_build_apps.sh"
|
||||
- "tools/build_apps.py"
|
||||
- "tools/find_apps.py"
|
||||
- "tools/find_build_apps/**/*"
|
||||
|
||||
- "tools/unit-test-app/**/*"
|
||||
|
||||
.patterns-component_ut: &patterns-component_ut
|
||||
- "tools/ci/python_packages/gitlab_api.py"
|
||||
- "tools/ci/python_packages/tiny_test_fw/**/*"
|
||||
- "tools/ci/python_packages/ttfw_idf/**/*"
|
||||
|
||||
- "tools/ci/find_apps_build_apps.sh"
|
||||
- "tools/build_apps.py"
|
||||
- "tools/find_apps.py"
|
||||
- "tools/find_build_apps/**/*"
|
||||
|
||||
- "components/**/test_apps/**/*"
|
||||
|
||||
.patterns-integration_test: &patterns-integration_test
|
||||
- "tools/ci/python_packages/tiny_test_fw/**/*"
|
||||
|
||||
.patterns-host_test: &patterns-host_test
|
||||
- ".gitlab/ci/host-test.yml"
|
||||
|
||||
- "components/**/*"
|
||||
|
||||
- "tools/ci/test_autocomplete.py"
|
||||
- "tools/ci/test_build_system.sh"
|
||||
- "tools/ci/test_build_system_cmake.sh"
|
||||
- "tools/ci/test_check_kconfigs.py"
|
||||
- "tools/ci/test_configure_ci_environment.sh"
|
||||
|
||||
- "tools/mass_mfg/**/*"
|
||||
|
||||
- "tools/esp_app_trace/**/*"
|
||||
- "tools/ldgen/**/*"
|
||||
|
||||
- "tools/idf_monitor_base/*"
|
||||
- "tools/idf_monitor.py"
|
||||
- "tools/test_idf_monitor/**/*"
|
||||
|
||||
- "tools/idf.py"
|
||||
- "tools/idf_py_actions/**/*"
|
||||
- "tools/test_idf_py/**/*"
|
||||
|
||||
- "tools/idf_size.py"
|
||||
- "tools/idf_size_yaml/*"
|
||||
- "tools/test_idf_size/**/*"
|
||||
|
||||
- "tools/tools.json"
|
||||
- "tools/tools_schema.json"
|
||||
- "tools/idf_tools.py"
|
||||
- "tools/test_idf_tools/**/*"
|
||||
|
||||
- "tools/mkdfu.py"
|
||||
- "tools/test_mkdfu/**/*"
|
||||
|
||||
- "tools/kconfig_new/**/*"
|
||||
|
||||
- "tools/detect_python.sh"
|
||||
- "tools/detect_python.fish"
|
||||
|
||||
.patterns-windows: &patterns-windows
|
||||
- "tools/windows/**/*"
|
||||
|
||||
.patterns-docker: &patterns-docker
|
||||
- "tools/docker/**/*"
|
||||
|
||||
.patterns-submodule: &patterns-submodule
|
||||
- "components/asio/asio"
|
||||
- "components/bootloader/subproject/components/micro-ecc/micro-ecc"
|
||||
- "components/bt/controller/lib_esp32"
|
||||
- "components/bt/controller/lib_esp32c3_family"
|
||||
- "components/bt/host/nimble/nimble"
|
||||
- "components/cbor/tinycbor"
|
||||
- "components/cmock/CMock"
|
||||
- "components/cmock/CMock/vendor/c_exception"
|
||||
- "components/cmock/CMock/vendor/unity"
|
||||
- "components/coap/libcoap"
|
||||
- "components/coap/libcoap/ext/tinydtls"
|
||||
- "components/esp_phy/lib"
|
||||
- "components/esp_wifi/lib"
|
||||
- "components/esptool_py/esptool"
|
||||
- "components/expat/expat"
|
||||
- "components/json/cJSON"
|
||||
- "components/libsodium/libsodium"
|
||||
- "components/lwip/lwip"
|
||||
- "components/mbedtls/mbedtls"
|
||||
- "components/mqtt/esp-mqtt"
|
||||
- "components/nghttp/nghttp2"
|
||||
- "components/nghttp/nghttp2/third-party/mruby"
|
||||
- "components/nghttp/nghttp2/third-party/neverbleed"
|
||||
- "components/openthread/lib"
|
||||
- "components/protobuf-c/protobuf-c"
|
||||
- "components/spiffs/spiffs"
|
||||
- "components/tinyusb/tinyusb"
|
||||
- "components/unity/unity"
|
||||
- "examples/build_system/cmake/import_lib/main/lib/tinyxml2"
|
||||
- "examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib"
|
||||
|
||||
##############
|
||||
# if anchors #
|
||||
##############
|
||||
.if-ref-master: &if-ref-master
|
||||
if: '$CI_COMMIT_REF_NAME == "master"'
|
||||
|
||||
.if-tag-release: &if-tag-release
|
||||
if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+(\.\d+)?($|-)/'
|
||||
|
||||
.if-protected: &if-protected
|
||||
if: '($CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_BRANCH =~ /^release\/v/ || $CI_COMMIT_TAG =~ /^v\d+\.\d+(\.\d+)?($|-)/)'
|
||||
|
||||
.if-protected-no_label: &if-protected-no_label
|
||||
if: '($CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_BRANCH =~ /^release\/v/ || $CI_COMMIT_TAG =~ /^v\d+\.\d+(\.\d+)?($|-)/) && $BOT_TRIGGER_WITH_LABEL == null'
|
||||
|
||||
.if-dev-push: &if-dev-push
|
||||
if: '$CI_COMMIT_REF_NAME != "master" && $CI_COMMIT_BRANCH !~ /^release\/v/ && $CI_COMMIT_TAG !~ /^v\d+\.\d+(\.\d+)?($|-)/ && ($CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event")'
|
||||
|
||||
.if-schedule: &if-schedule
|
||||
if: '$CI_PIPELINE_SOURCE == "schedule"'
|
||||
|
||||
.if-trigger: &if-trigger
|
||||
if: '$CI_PIPELINE_SOURCE == "trigger"'
|
||||
|
||||
.if-label-build-only: &if-label-build-only
|
||||
if: '$CI_JOB_STAGE == "target_test" && $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*For Maintainers: Only Build Tests(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
#########
|
||||
# Rules #
|
||||
#########
|
||||
.rules:protected:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
|
||||
.rules:protected-no_label:
|
||||
rules:
|
||||
- <<: *if-protected-no_label
|
||||
|
||||
.rules:dev:
|
||||
rules:
|
||||
- <<: *if-trigger
|
||||
- <<: *if-dev-push
|
||||
|
||||
.rules:tag:release:
|
||||
rules:
|
||||
- <<: *if-tag-release
|
||||
|
||||
.rules:ref:master-schedule:
|
||||
rules:
|
||||
- <<: *if-ref-master
|
||||
- <<: *if-schedule
|
||||
|
||||
.rules:ref:master-schedule-always:
|
||||
rules:
|
||||
- <<: *if-ref-master
|
||||
when: always
|
||||
- <<: *if-schedule
|
||||
when: always
|
||||
|
||||
.rules:patterns:clang_tidy:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-c-files
|
||||
|
||||
.rules:patterns:python-files:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-python-files
|
||||
|
||||
.rules:patterns:static-code-analysis-preview:
|
||||
rules:
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-c-files
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-python-files
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-sonarqube-files
|
||||
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
# DO NOT place comments or maintain any code from this line
|
||||
#
|
||||
# Use dependencies.yml and generate_rules.py under .gitlab/ci/dependencies dir
|
||||
# to generate labels and rules
|
||||
# Could also use pre-commit hook to finish this if detected changes on
|
||||
# these two files
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
##################
|
||||
# Auto Generated #
|
||||
##################
|
||||
.if-label-build: &if-label-build
|
||||
if: '$BOT_LABEL_BUILD || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*build(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-component_ut: &if-label-component_ut
|
||||
if: '$BOT_LABEL_COMPONENT_UT || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*component_ut(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-component_ut_esp32: &if-label-component_ut_esp32
|
||||
if: '$BOT_LABEL_COMPONENT_UT_ESP32 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*component_ut_esp32(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-component_ut_esp32c3: &if-label-component_ut_esp32c3
|
||||
if: '$BOT_LABEL_COMPONENT_UT_ESP32C3 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*component_ut_esp32c3(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-component_ut_esp32s2: &if-label-component_ut_esp32s2
|
||||
if: '$BOT_LABEL_COMPONENT_UT_ESP32S2 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*component_ut_esp32s2(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-component_ut_esp32s3: &if-label-component_ut_esp32s3
|
||||
if: '$BOT_LABEL_COMPONENT_UT_ESP32S3 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*component_ut_esp32s3(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-custom_test: &if-label-custom_test
|
||||
if: '$BOT_LABEL_CUSTOM_TEST || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*custom_test(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-custom_test_esp32: &if-label-custom_test_esp32
|
||||
if: '$BOT_LABEL_CUSTOM_TEST_ESP32 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*custom_test_esp32(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-custom_test_esp32c3: &if-label-custom_test_esp32c3
|
||||
if: '$BOT_LABEL_CUSTOM_TEST_ESP32C3 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*custom_test_esp32c3(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-custom_test_esp32s2: &if-label-custom_test_esp32s2
|
||||
if: '$BOT_LABEL_CUSTOM_TEST_ESP32S2 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*custom_test_esp32s2(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-custom_test_esp32s3: &if-label-custom_test_esp32s3
|
||||
if: '$BOT_LABEL_CUSTOM_TEST_ESP32S3 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*custom_test_esp32s3(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-docker: &if-label-docker
|
||||
if: '$BOT_LABEL_DOCKER || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*docker(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-example_test: &if-label-example_test
|
||||
if: '$BOT_LABEL_EXAMPLE_TEST || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*example_test(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-example_test_esp32: &if-label-example_test_esp32
|
||||
if: '$BOT_LABEL_EXAMPLE_TEST_ESP32 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*example_test_esp32(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-example_test_esp32c3: &if-label-example_test_esp32c3
|
||||
if: '$BOT_LABEL_EXAMPLE_TEST_ESP32C3 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*example_test_esp32c3(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-example_test_esp32s2: &if-label-example_test_esp32s2
|
||||
if: '$BOT_LABEL_EXAMPLE_TEST_ESP32S2 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*example_test_esp32s2(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-example_test_esp32s3: &if-label-example_test_esp32s3
|
||||
if: '$BOT_LABEL_EXAMPLE_TEST_ESP32S3 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*example_test_esp32s3(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-fuzzer_test: &if-label-fuzzer_test
|
||||
if: '$BOT_LABEL_FUZZER_TEST || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*fuzzer_test(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-host_test: &if-label-host_test
|
||||
if: '$BOT_LABEL_HOST_TEST || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*host_test(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-integration_test: &if-label-integration_test
|
||||
if: '$BOT_LABEL_INTEGRATION_TEST || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*integration_test(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-iperf_stress_test: &if-label-iperf_stress_test
|
||||
if: '$BOT_LABEL_IPERF_STRESS_TEST || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*iperf_stress_test(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-macos: &if-label-macos
|
||||
if: '$BOT_LABEL_MACOS || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*macos(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-macos_test: &if-label-macos_test
|
||||
if: '$BOT_LABEL_MACOS_TEST || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*macos_test(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-nvs_coverage: &if-label-nvs_coverage
|
||||
if: '$BOT_LABEL_NVS_COVERAGE || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*nvs_coverage(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-submodule: &if-label-submodule
|
||||
if: '$BOT_LABEL_SUBMODULE || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*submodule(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-unit_test: &if-label-unit_test
|
||||
if: '$BOT_LABEL_UNIT_TEST || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*unit_test(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-unit_test_esp32: &if-label-unit_test_esp32
|
||||
if: '$BOT_LABEL_UNIT_TEST_ESP32 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*unit_test_esp32(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-unit_test_esp32c3: &if-label-unit_test_esp32c3
|
||||
if: '$BOT_LABEL_UNIT_TEST_ESP32C3 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*unit_test_esp32c3(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-unit_test_esp32s2: &if-label-unit_test_esp32s2
|
||||
if: '$BOT_LABEL_UNIT_TEST_ESP32S2 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*unit_test_esp32s2(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-unit_test_esp32s3: &if-label-unit_test_esp32s3
|
||||
if: '$BOT_LABEL_UNIT_TEST_ESP32S3 || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*unit_test_esp32s3(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-weekend_test: &if-label-weekend_test
|
||||
if: '$BOT_LABEL_WEEKEND_TEST || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*weekend_test(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.if-label-windows: &if-label-windows
|
||||
if: '$BOT_LABEL_WINDOWS || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*windows(?:,[^,\n\r]+)*$/i'
|
||||
|
||||
.rules:build:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
|
||||
.rules:build:component_ut-esp32:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut
|
||||
|
||||
.rules:build:component_ut-esp32c3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32c3
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32c3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut
|
||||
|
||||
.rules:build:component_ut-esp32s2:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32s2
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32s2
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut
|
||||
|
||||
.rules:build:component_ut-esp32s3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32s3
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32s3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut
|
||||
|
||||
.rules:build:custom_test-esp32:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32
|
||||
- <<: *if-label-weekend_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-custom_test
|
||||
|
||||
.rules:build:custom_test-esp32c3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32c3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-custom_test
|
||||
|
||||
.rules:build:custom_test-esp32s2:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32s2
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-custom_test
|
||||
|
||||
.rules:build:custom_test-esp32s3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32s3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-custom_test
|
||||
|
||||
.rules:build:docker:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-docker
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-docker
|
||||
|
||||
.rules:build:example_test-esp32:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32
|
||||
- <<: *if-label-iperf_stress_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test
|
||||
|
||||
.rules:build:example_test-esp32c3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32c3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test
|
||||
|
||||
.rules:build:example_test-esp32s2:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32s2
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test
|
||||
|
||||
.rules:build:example_test-esp32s3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32s3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test
|
||||
|
||||
.rules:build:integration_test:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-integration_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-integration_test
|
||||
|
||||
.rules:build:macos:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-macos
|
||||
- <<: *if-label-macos_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
|
||||
.rules:build:target_test:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32
|
||||
- <<: *if-label-component_ut_esp32c3
|
||||
- <<: *if-label-component_ut_esp32s2
|
||||
- <<: *if-label-component_ut_esp32s3
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32
|
||||
- <<: *if-label-custom_test_esp32c3
|
||||
- <<: *if-label-custom_test_esp32s2
|
||||
- <<: *if-label-custom_test_esp32s3
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32
|
||||
- <<: *if-label-example_test_esp32c3
|
||||
- <<: *if-label-example_test_esp32s2
|
||||
- <<: *if-label-example_test_esp32s3
|
||||
- <<: *if-label-integration_test
|
||||
- <<: *if-label-iperf_stress_test
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32
|
||||
- <<: *if-label-unit_test_esp32c3
|
||||
- <<: *if-label-unit_test_esp32s2
|
||||
- <<: *if-label-unit_test_esp32s3
|
||||
- <<: *if-label-weekend_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-custom_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-integration_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test
|
||||
|
||||
.rules:build:unit_test-esp32:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test
|
||||
|
||||
.rules:build:unit_test-esp32c3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32c3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test
|
||||
|
||||
.rules:build:unit_test-esp32s2:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32s2
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test
|
||||
|
||||
.rules:build:unit_test-esp32s3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32s3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_components
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test
|
||||
|
||||
.rules:build:windows:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build
|
||||
- <<: *if-label-windows
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build_system
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-windows
|
||||
|
||||
.rules:labels:example_test-esp32c3:
|
||||
rules:
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-example_test_esp32c3
|
||||
|
||||
.rules:labels:fuzzer_test-weekend_test:
|
||||
rules:
|
||||
- <<: *if-label-fuzzer_test
|
||||
- <<: *if-label-weekend_test
|
||||
|
||||
.rules:labels:iperf_stress_test:
|
||||
rules:
|
||||
- <<: *if-label-iperf_stress_test
|
||||
|
||||
.rules:labels:nvs_coverage:
|
||||
rules:
|
||||
- <<: *if-label-nvs_coverage
|
||||
|
||||
.rules:labels:weekend_test:
|
||||
rules:
|
||||
- <<: *if-label-weekend_test
|
||||
|
||||
.rules:test:any_test:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32
|
||||
- <<: *if-label-component_ut_esp32c3
|
||||
- <<: *if-label-component_ut_esp32s2
|
||||
- <<: *if-label-component_ut_esp32s3
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32
|
||||
- <<: *if-label-custom_test_esp32c3
|
||||
- <<: *if-label-custom_test_esp32s2
|
||||
- <<: *if-label-custom_test_esp32s3
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32
|
||||
- <<: *if-label-example_test_esp32s2
|
||||
- <<: *if-label-example_test_esp32s3
|
||||
- <<: *if-label-host_test
|
||||
- <<: *if-label-integration_test
|
||||
- <<: *if-label-iperf_stress_test
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32
|
||||
- <<: *if-label-unit_test_esp32c3
|
||||
- <<: *if-label-unit_test_esp32s2
|
||||
- <<: *if-label-unit_test_esp32s3
|
||||
- <<: *if-label-weekend_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-custom_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-host_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-integration_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test
|
||||
|
||||
.rules:test:component_ut-esp32:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut
|
||||
|
||||
.rules:test:component_ut-esp32c3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32c3
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32c3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut
|
||||
|
||||
.rules:test:component_ut-esp32s2:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32s2
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32s2
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut
|
||||
|
||||
.rules:test:component_ut-esp32s3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32s3
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32s3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut
|
||||
|
||||
.rules:test:custom_test-esp32:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-custom_test
|
||||
|
||||
.rules:test:custom_test-esp32c3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32c3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-custom_test
|
||||
|
||||
.rules:test:custom_test-esp32s2:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32s2
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-custom_test
|
||||
|
||||
.rules:test:custom_test-esp32s3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32s3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-custom_test
|
||||
|
||||
.rules:test:example_test-esp32:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test
|
||||
|
||||
.rules:test:example_test-esp32s2:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32s2
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test
|
||||
|
||||
.rules:test:example_test-esp32s3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32s3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test
|
||||
|
||||
.rules:test:host_test:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-host_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-host_test
|
||||
|
||||
.rules:test:integration_test:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-integration_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-integration_test
|
||||
|
||||
.rules:test:submodule:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-submodule
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-submodule
|
||||
|
||||
.rules:test:target_test:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32
|
||||
- <<: *if-label-component_ut_esp32c3
|
||||
- <<: *if-label-component_ut_esp32s2
|
||||
- <<: *if-label-component_ut_esp32s3
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32
|
||||
- <<: *if-label-custom_test_esp32c3
|
||||
- <<: *if-label-custom_test_esp32s2
|
||||
- <<: *if-label-custom_test_esp32s3
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32
|
||||
- <<: *if-label-example_test_esp32s2
|
||||
- <<: *if-label-example_test_esp32s3
|
||||
- <<: *if-label-integration_test
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32
|
||||
- <<: *if-label-unit_test_esp32c3
|
||||
- <<: *if-label-unit_test_esp32s2
|
||||
- <<: *if-label-unit_test_esp32s3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-build-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-custom_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-integration_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test
|
||||
|
||||
.rules:test:unit_test-esp32:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test
|
||||
|
||||
.rules:test:unit_test-esp32c3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32c3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test
|
||||
|
||||
.rules:test:unit_test-esp32s2:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32s2
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test
|
||||
|
||||
.rules:test:unit_test-esp32s3:
|
||||
rules:
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32s3
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test
|
||||
@@ -1,130 +0,0 @@
|
||||
# pre_check stage
|
||||
clang_tidy_check:
|
||||
extends:
|
||||
- .pre_check_base_template
|
||||
- .rules:patterns:clang_tidy
|
||||
image: ${CLANG_STATIC_ANALYSIS_IMAGE}
|
||||
artifacts:
|
||||
paths:
|
||||
- $OUTPUT_DIR
|
||||
when: always
|
||||
expire_in: 1 day
|
||||
variables:
|
||||
CLANG_TIDY_RUNNER_PROJ: 2107 # idf/clang-tidy-runner
|
||||
CLANG_TIDY_DIRS_TXT: ${CI_PROJECT_DIR}/tools/ci/clang_tidy_dirs.txt
|
||||
RULES_FILE: ${CI_PROJECT_DIR}/tools/ci/static-analysis-rules.yml
|
||||
OUTPUT_DIR: ${CI_PROJECT_DIR}/clang_tidy_reports
|
||||
script:
|
||||
- python -m pip install -U pip
|
||||
- internal_pip_install $CLANG_TIDY_RUNNER_PROJ pyclang
|
||||
- export PATH=$PATH:$(python -c "import sys; print(sys.executable.rsplit('/', 1)[0])")
|
||||
- dirs=$(cat ${CLANG_TIDY_DIRS_TXT} | while read line; do echo ${CI_PROJECT_DIR}/${line}; done | xargs)
|
||||
- run_cmd idf_clang ${dirs}
|
||||
--output-path ${OUTPUT_DIR}
|
||||
--limit-file ${RULES_FILE}
|
||||
--xtensa-include-dir
|
||||
--run-clang-tidy-py ${RUN_CLANG_TIDY_PY}
|
||||
|
||||
check_pylint:
|
||||
extends:
|
||||
- .pre_check_base_template
|
||||
- .rules:patterns:python-files
|
||||
- .before_script_minimal
|
||||
image: $SONARQUBE_SCANNER_IMAGE
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- pylint-report.txt
|
||||
expire_in: 1 week
|
||||
script:
|
||||
- export PYTHONPATH="$IDF_PATH/tools:$IDF_PATH/tools/ci/python_packages:$PYTHONPATH"
|
||||
- |
|
||||
if [ -n "$CI_MERGE_REQUEST_IID" ]; then
|
||||
export files=$(python ${CI_PROJECT_DIR}/tools/ci/ci_get_mr_info.py files ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} | grep ".py");
|
||||
else
|
||||
export files=$(find . -iname "*.py" -print);
|
||||
fi
|
||||
- pylint --rcfile=.pylintrc $files -r n --output-format=parseable > pylint-report.txt || exit 0
|
||||
|
||||
# build stage
|
||||
# Sonarqube related jobs put here for this reason:
|
||||
# Here we have two jobs. code_quality_check and code_quality_report.
|
||||
#
|
||||
# code_quality_check will analyze the code changes between your MR and
|
||||
# code repo stored in sonarqube server. The analysis result is only shown in
|
||||
# the comments under this MR and won't be transferred to the server.
|
||||
#
|
||||
# code_quality_report will analyze and transfer both of the newly added code
|
||||
# and the analysis result to the server.
|
||||
#
|
||||
# Put in the front to ensure that the newly merged code can be stored in
|
||||
# sonarqube server ASAP, in order to avoid reporting unrelated code issues
|
||||
.sonar_scan_template:
|
||||
stage: build
|
||||
image:
|
||||
name: $SONARQUBE_SCANNER_IMAGE
|
||||
before_script:
|
||||
- source tools/ci/utils.sh
|
||||
- export PYTHONPATH="$CI_PROJECT_DIR/tools:$CI_PROJECT_DIR/tools/ci/python_packages:$PYTHONPATH"
|
||||
- fetch_submodules
|
||||
# Exclude the submodules, all paths ends with /**
|
||||
- submodules=$(get_all_submodules)
|
||||
# get all exclude paths specified in tools/ci/sonar_exclude_list.txt | ignore lines start with # | xargs | replace all <space> to <comma>
|
||||
- custom_excludes=$(cat $CI_PROJECT_DIR/tools/ci/sonar_exclude_list.txt | grep -v '^#' | xargs | sed -e 's/ /,/g')
|
||||
# Exclude the report dir as well
|
||||
- export EXCLUSIONS="$custom_excludes,$submodules"
|
||||
- export SONAR_SCANNER_OPTS="-Xmx2048m"
|
||||
|
||||
variables:
|
||||
GIT_DEPTH: 0
|
||||
REPORT_PATTERN: clang_tidy_reports/*.txt
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $REPORT_PATTERN
|
||||
tags:
|
||||
- host_test
|
||||
dependencies: # Here is not a hard dependency relationship, could be skipped when only python files changed. so we do not use "needs" here.
|
||||
- clang_tidy_check
|
||||
- check_pylint
|
||||
|
||||
code_quality_check:
|
||||
extends:
|
||||
- .sonar_scan_template
|
||||
- .rules:patterns:static-code-analysis-preview
|
||||
allow_failure: true # since now it's using exit code to indicate the code analysis result,
|
||||
# we don't want to block ci when critical issues founded
|
||||
script:
|
||||
- export CI_MERGE_REQUEST_COMMITS=$(python ${CI_PROJECT_DIR}/tools/ci/ci_get_mr_info.py commits ${CI_COMMIT_REF_NAME} | tr '\n' ',')
|
||||
# test if this branch have merge request, if not, exit 0
|
||||
- test -n "$CI_MERGE_REQUEST_IID" || exit 0
|
||||
- test -n "$CI_MERGE_REQUEST_COMMITS" || exit 0
|
||||
- sonar-scanner
|
||||
-Dsonar.analysis.mode=preview
|
||||
-Dsonar.branch.name=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
|
||||
-Dsonar.cxx.clangtidy.reportPath=$REPORT_PATTERN
|
||||
-Dsonar.exclusions=$EXCLUSIONS
|
||||
-Dsonar.gitlab.ci_merge_request_iid=$CI_MERGE_REQUEST_IID
|
||||
-Dsonar.gitlab.commit_sha=$CI_MERGE_REQUEST_COMMITS
|
||||
-Dsonar.gitlab.merge_request_discussion=true
|
||||
-Dsonar.gitlab.ref_name=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
|
||||
-Dsonar.host.url=$SONAR_HOST_URL
|
||||
-Dsonar.login=$SONAR_LOGIN
|
||||
-Dsonar.python.pylint.reportPath=pylint-report.txt
|
||||
|
||||
code_quality_report:
|
||||
extends:
|
||||
- .sonar_scan_template
|
||||
- .rules:protected
|
||||
allow_failure: true # since now it's using exit code to indicate the code analysis result,
|
||||
# we don't want to block ci when critical issues founded
|
||||
script:
|
||||
- sonar-scanner
|
||||
-Dsonar.branch.name=$CI_COMMIT_REF_NAME
|
||||
-Dsonar.cxx.clangtidy.reportPath=$REPORT_PATTERN
|
||||
-Dsonar.exclusions=$EXCLUSIONS
|
||||
-Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA
|
||||
-Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME
|
||||
-Dsonar.host.url=$SONAR_HOST_URL
|
||||
-Dsonar.login=$SONAR_LOGIN
|
||||
-Dsonar.python.pylint.reportPath=pylint-report.txt
|
||||
@@ -1,949 +0,0 @@
|
||||
# for parallel jobs, CI_JOB_NAME will be "job_name index/total" (for example, "IT_001 1/2")
|
||||
# we need to convert to pattern "job_name_index.yml"
|
||||
.define_config_file_name: &define_config_file_name |
|
||||
JOB_NAME_PREFIX=$(echo ${CI_JOB_NAME} | awk '{print $1}')
|
||||
JOB_FULL_NAME="${JOB_NAME_PREFIX}_${CI_NODE_INDEX}"
|
||||
CONFIG_FILE="${CONFIG_FILE_PATH}/${JOB_FULL_NAME}.yml"
|
||||
|
||||
.target_test_job_template:
|
||||
stage: target_test
|
||||
needs:
|
||||
- assign_test
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- "**/*.log"
|
||||
- $LOG_PATH
|
||||
expire_in: 1 week
|
||||
reports:
|
||||
junit: $LOG_PATH/*/XUNIT_RESULT.xml
|
||||
variables:
|
||||
TEST_FW_PATH: "$CI_PROJECT_DIR/tools/tiny-test-fw"
|
||||
LOG_PATH: "$CI_PROJECT_DIR/TEST_LOGS"
|
||||
ENV_FILE: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/EnvConfig.yml"
|
||||
SUBMODULES_TO_FETCH: "components/esptool_py/esptool"
|
||||
script:
|
||||
- *define_config_file_name
|
||||
# first test if config file exists, if not exist, exit 0
|
||||
- |
|
||||
{ [[ -e $CONFIG_FILE ]]; } || { echo 'No config file found. Consider decreasing the parallel count of this job in ".gitlab/ci/target-test.yml"'; exit 0; }
|
||||
# clone test env configs
|
||||
- retry_failed git clone $TEST_ENV_CONFIG_REPO
|
||||
- python $CHECKOUT_REF_SCRIPT ci-test-runner-configs ci-test-runner-configs
|
||||
# git clone the known failure cases repo, run test
|
||||
- retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases
|
||||
# run test
|
||||
- cd tools/ci/python_packages/tiny_test_fw/bin
|
||||
- run_cmd python Runner.py $TEST_CASE_PATH -c $CONFIG_FILE -e $ENV_FILE --known_failure_cases_file $CI_PROJECT_DIR/known_failure_cases/known_failure_cases.txt
|
||||
|
||||
.example_test_template:
|
||||
extends: .target_test_job_template
|
||||
variables:
|
||||
TEST_CASE_PATH: "$CI_PROJECT_DIR/examples"
|
||||
CONFIG_FILE_PATH: "${CI_PROJECT_DIR}/examples/test_configs"
|
||||
|
||||
.example_debug_template:
|
||||
extends:
|
||||
- .example_test_template
|
||||
- .rules:test:example_test-esp32
|
||||
variables:
|
||||
SUBMODULES_TO_FETCH: "all"
|
||||
|
||||
test_weekend_mqtt:
|
||||
extends:
|
||||
- .test_app_esp32_template
|
||||
- .rules:labels:weekend_test
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_WIFI
|
||||
script:
|
||||
- export MQTT_PUBLISH_TEST=1
|
||||
- export TEST_PATH=$CI_PROJECT_DIR/tools/test_apps/protocols/mqtt/publish_connect_test
|
||||
- cd $IDF_PATH/tools/ci/python_packages/tiny_test_fw/bin
|
||||
- run_cmd python Runner.py $TEST_PATH -c $TEST_PATH/publish_connect_mqtt_.yml
|
||||
|
||||
.example_test_esp32_template:
|
||||
extends:
|
||||
- .example_test_template
|
||||
- .rules:test:example_test-esp32
|
||||
|
||||
.example_test_esp32s2_template:
|
||||
extends:
|
||||
- .example_test_template
|
||||
- .rules:test:example_test-esp32s2
|
||||
|
||||
.example_test_esp32c3_template:
|
||||
extends:
|
||||
- .example_test_template
|
||||
- .rules:labels:example_test-esp32c3
|
||||
|
||||
.example_test_esp32s3_template:
|
||||
extends:
|
||||
- .example_test_template
|
||||
- .rules:test:example_test-esp32s3
|
||||
|
||||
example_test_001A:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_WIFI
|
||||
|
||||
example_test_001B:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_EthKitV1
|
||||
|
||||
example_test_001B_V3:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_EthKitV12
|
||||
|
||||
example_test_001C:
|
||||
extends: .example_test_esp32_template
|
||||
parallel: 4
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_GENERIC
|
||||
|
||||
example_test_001D:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_8Mflash_Ethernet
|
||||
|
||||
example_test_OTA:
|
||||
extends: .example_test_esp32_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_WIFI_OTA
|
||||
|
||||
example_test_protocols:
|
||||
extends: .example_test_esp32_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_WIFI_Protocols
|
||||
|
||||
example_test_002:
|
||||
extends: .example_test_esp32_template
|
||||
image: $CI_DOCKER_REGISTRY/ubuntu-test-env$BOT_DOCKER_IMAGE_TAG
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_ShieldBox_Basic
|
||||
|
||||
example_test_ethernet:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_Ethernet
|
||||
|
||||
.example_test_003:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_SDIO
|
||||
|
||||
example_test_004A:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_TWAI1
|
||||
|
||||
example_test_004B:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_TWAI2
|
||||
|
||||
example_test_005:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_WIFI_BT
|
||||
|
||||
example_test_006:
|
||||
extends:
|
||||
- .example_test_esp32_template
|
||||
- .rules:labels:iperf_stress_test
|
||||
image: $CI_DOCKER_REGISTRY/ubuntu-test-env$BOT_DOCKER_IMAGE_TAG
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_ShieldBox
|
||||
|
||||
example_test_007:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_I2C_CCS811_SENSOR
|
||||
|
||||
example_test_008A:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_Flash_Encryption
|
||||
|
||||
example_test_008B:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_Flash_Encryption_OTA
|
||||
|
||||
example_test_009:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- test_jtag_arm
|
||||
variables:
|
||||
SETUP_TOOLS: "1"
|
||||
PYTHON_VER: 3
|
||||
|
||||
example_test_010:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_ExtFlash
|
||||
|
||||
example_test_011:
|
||||
extends: .example_debug_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_T2_RS485
|
||||
variables:
|
||||
SETUP_TOOLS: "1"
|
||||
|
||||
example_test_012:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_RMT_IR_PROTOCOLS
|
||||
|
||||
example_test_013:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- UT_T1_SDMODE
|
||||
|
||||
example_test_014:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- 8Mpsram
|
||||
|
||||
example_test_015:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_PPP
|
||||
|
||||
example_test_016:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_Modbus_TCP
|
||||
|
||||
example_test_017:
|
||||
extends: .example_test_esp32s2_template
|
||||
tags:
|
||||
- ESP32S2
|
||||
- Example_GENERIC
|
||||
|
||||
example_test_C3_GENERIC:
|
||||
extends: .example_test_esp32c3_template
|
||||
parallel: 3
|
||||
tags:
|
||||
- ESP32C3
|
||||
- Example_GENERIC
|
||||
|
||||
example_test_C3_FLASH_ENC:
|
||||
extends: .example_test_esp32c3_template
|
||||
tags:
|
||||
- ESP32C3
|
||||
- Example_Flash_Encryption
|
||||
|
||||
example_test_C3_FLASH_ENC_OTA:
|
||||
extends: .example_test_esp32c3_template
|
||||
tags:
|
||||
- ESP32C3
|
||||
- Example_Flash_Encryption_OTA_WiFi
|
||||
|
||||
example_test_ESP32_SDSPI:
|
||||
extends: .example_test_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- UT_T1_SPIMODE
|
||||
|
||||
example_test_S3_GENERIC:
|
||||
extends: .example_test_esp32s3_template
|
||||
tags:
|
||||
- ESP32S3
|
||||
- Example_GENERIC
|
||||
|
||||
example_test_ESP32S2_SDSPI:
|
||||
extends: .example_test_esp32s2_template
|
||||
tags:
|
||||
- ESP32S2
|
||||
- UT_T1_SPIMODE
|
||||
|
||||
example_test_ESP32C3_SDSPI:
|
||||
extends: .example_test_esp32c3_template
|
||||
tags:
|
||||
- ESP32C3
|
||||
- UT_T1_SPIMODE
|
||||
|
||||
.test_app_template:
|
||||
extends: .target_test_job_template
|
||||
variables:
|
||||
TEST_CASE_PATH: "$CI_PROJECT_DIR/tools/test_apps"
|
||||
CONFIG_FILE_PATH: "${CI_PROJECT_DIR}/tools/test_apps/test_configs"
|
||||
|
||||
.test_app_esp32_template:
|
||||
extends:
|
||||
- .test_app_template
|
||||
- .rules:test:custom_test-esp32
|
||||
|
||||
.test_app_esp32s2_template:
|
||||
extends:
|
||||
- .test_app_template
|
||||
- .rules:test:custom_test-esp32s2
|
||||
|
||||
.test_app_esp32c3_template:
|
||||
extends:
|
||||
- .test_app_template
|
||||
- .rules:test:custom_test-esp32c3
|
||||
|
||||
.test_app_esp32s3_template:
|
||||
extends:
|
||||
- .test_app_template
|
||||
- .rules:test:custom_test-esp32s3
|
||||
|
||||
test_app_test_001:
|
||||
extends: .test_app_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- test_jtag_arm
|
||||
variables:
|
||||
SETUP_TOOLS: "1"
|
||||
|
||||
test_app_test_002:
|
||||
extends: .test_app_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_WIFI
|
||||
|
||||
test_app_test_003:
|
||||
extends: .test_app_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_PPP
|
||||
|
||||
test_app_test_004:
|
||||
extends: .test_app_esp32s2_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32S2
|
||||
- Example_GENERIC
|
||||
|
||||
test_app_test_005:
|
||||
extends: .test_app_esp32c3_template
|
||||
tags:
|
||||
- ESP32C3
|
||||
- Example_GENERIC
|
||||
|
||||
test_app_test_esp32_generic:
|
||||
extends: .test_app_esp32_template
|
||||
parallel: 5
|
||||
tags:
|
||||
- ESP32
|
||||
- Example_GENERIC
|
||||
variables:
|
||||
SETUP_TOOLS: "1"
|
||||
|
||||
test_app_test_flash_psram_f4r4:
|
||||
extends: .test_app_esp32s3_template
|
||||
tags:
|
||||
- ESP32S3
|
||||
- MSPI_F4R4
|
||||
|
||||
test_app_test_flash_psram_f4r8:
|
||||
extends: .test_app_esp32s3_template
|
||||
tags:
|
||||
- ESP32S3
|
||||
- MSPI_F4R8
|
||||
|
||||
test_app_test_flash_psram_f8r8:
|
||||
extends: .test_app_esp32s3_template
|
||||
tags:
|
||||
- ESP32S3
|
||||
- MSPI_F8R8
|
||||
|
||||
.component_ut_template:
|
||||
extends: .target_test_job_template
|
||||
variables:
|
||||
CONFIG_FILE_PATH: "${CI_PROJECT_DIR}/component_ut/test_configs"
|
||||
script:
|
||||
- *define_config_file_name
|
||||
# first test if config file exists, if not exist, exit 0
|
||||
- test -e $CONFIG_FILE || exit 0
|
||||
- set_component_ut_vars
|
||||
# clone test env configs
|
||||
- retry_failed git clone $TEST_ENV_CONFIG_REPO
|
||||
- python $CHECKOUT_REF_SCRIPT ci-test-runner-configs ci-test-runner-configs
|
||||
# git clone the known failure cases repo, run test
|
||||
- retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases
|
||||
# run test
|
||||
- cd tools/ci/python_packages/tiny_test_fw/bin
|
||||
- run_cmd python Runner.py $COMPONENT_UT_DIRS -c $CONFIG_FILE -e $ENV_FILE --known_failure_cases_file $CI_PROJECT_DIR/known_failure_cases/known_failure_cases.txt
|
||||
|
||||
.component_ut_esp32_template:
|
||||
extends:
|
||||
- .component_ut_template
|
||||
- .rules:test:component_ut-esp32
|
||||
|
||||
.component_ut_esp32s2_template:
|
||||
extends:
|
||||
- .component_ut_template
|
||||
- .rules:test:component_ut-esp32s2
|
||||
|
||||
.component_ut_esp32s3_template:
|
||||
extends:
|
||||
- .component_ut_template
|
||||
- .rules:test:component_ut-esp32s3
|
||||
|
||||
.component_ut_esp32c3_template:
|
||||
extends:
|
||||
- .component_ut_template
|
||||
- .rules:test:component_ut-esp32c3
|
||||
|
||||
component_ut_test_001:
|
||||
extends: .component_ut_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- COMPONENT_UT_GENERIC
|
||||
|
||||
component_ut_test_esp32s2:
|
||||
extends: .component_ut_esp32s2_template
|
||||
tags:
|
||||
- ESP32S2
|
||||
- COMPONENT_UT_GENERIC
|
||||
|
||||
component_ut_test_esp32s3:
|
||||
extends: .component_ut_esp32s3_template
|
||||
tags:
|
||||
- ESP32S3
|
||||
- COMPONENT_UT_GENERIC
|
||||
|
||||
component_ut_test_esp32c3:
|
||||
extends: .component_ut_esp32c3_template
|
||||
tags:
|
||||
- ESP32C3
|
||||
- COMPONENT_UT_GENERIC
|
||||
|
||||
.unit_test_template:
|
||||
extends: .target_test_job_template
|
||||
variables:
|
||||
TEST_CASE_PATH: "$CI_PROJECT_DIR/tools/unit-test-app"
|
||||
CONFIG_FILE_PATH: "${CI_PROJECT_DIR}/components/idf_test/unit_test/CIConfigs"
|
||||
|
||||
.unit_test_esp32_template:
|
||||
extends:
|
||||
- .unit_test_template
|
||||
- .rules:test:unit_test-esp32
|
||||
|
||||
.unit_test_esp32s2_template:
|
||||
extends:
|
||||
- .unit_test_template
|
||||
- .rules:test:unit_test-esp32s2
|
||||
|
||||
.unit_test_esp32s3_template:
|
||||
extends:
|
||||
- .unit_test_template
|
||||
- .rules:test:unit_test-esp32s3
|
||||
|
||||
.unit_test_esp32c3_template:
|
||||
extends:
|
||||
- .unit_test_template
|
||||
- .rules:test:unit_test-esp32c3
|
||||
|
||||
UT_001:
|
||||
extends: .unit_test_esp32_template
|
||||
parallel: 50
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
|
||||
# Max. allowed value of 'parallel' is 50.
|
||||
|
||||
UT_002:
|
||||
extends: .unit_test_esp32_template
|
||||
parallel: 15
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
- psram
|
||||
|
||||
UT_003:
|
||||
extends: .unit_test_esp32_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_SDMODE
|
||||
|
||||
UT_004:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_SPIMODE
|
||||
|
||||
UT_005:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_SDMODE
|
||||
- psram
|
||||
|
||||
UT_006:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_SPIMODE
|
||||
- psram
|
||||
|
||||
UT_007:
|
||||
extends: .unit_test_esp32_template
|
||||
parallel: 4
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
|
||||
UT_008:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_GPIO
|
||||
- psram
|
||||
|
||||
UT_012:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_LEDC
|
||||
- psram
|
||||
|
||||
UT_014:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T2_RS485
|
||||
- psram
|
||||
|
||||
UT_017:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- EMMC
|
||||
|
||||
UT_018:
|
||||
extends: .unit_test_esp32_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
- 8Mpsram
|
||||
|
||||
UT_020:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- Example_SPI_Multi_device
|
||||
- psram
|
||||
|
||||
UT_021:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- psram
|
||||
- UT_T1_FlashEncryption
|
||||
|
||||
UT_022:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T2_I2C
|
||||
- psram
|
||||
|
||||
UT_028:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T2_1
|
||||
- psram
|
||||
|
||||
UT_031:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_FlashEncryption
|
||||
|
||||
UT_033:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T2_Ethernet
|
||||
- psram
|
||||
|
||||
UT_034:
|
||||
extends: .unit_test_esp32_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_ESP_FLASH
|
||||
|
||||
UT_035:
|
||||
extends: .unit_test_esp32s2_template
|
||||
parallel: 50
|
||||
tags:
|
||||
- ESP32S2_IDF
|
||||
- UT_T1_1
|
||||
|
||||
UT_036:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_PSRAMV0
|
||||
- psram
|
||||
|
||||
# ToDo: re-enable this job when ESP32-S2 LEDC runner installed
|
||||
# UT_037:
|
||||
# extends: .unit_test_esp32s2_template
|
||||
# tags:
|
||||
# - ESP32S2_IDF
|
||||
# - UT_T1_LEDC
|
||||
|
||||
UT_038:
|
||||
extends: .unit_test_esp32s2_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32S2_IDF
|
||||
- UT_T1_ESP_FLASH
|
||||
|
||||
UT_041:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_no32kXTAL
|
||||
- psram
|
||||
|
||||
UT_043:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_32kXTAL
|
||||
- psram
|
||||
|
||||
UT_044:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_SDIO
|
||||
|
||||
UT_045:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_SDIO
|
||||
- psram
|
||||
|
||||
UT_046:
|
||||
extends: .unit_test_esp32_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_GPIO
|
||||
|
||||
UT_047:
|
||||
extends: .unit_test_esp32s2_template
|
||||
parallel: 5
|
||||
tags:
|
||||
- ESP32S2_IDF
|
||||
- UT_T1_1
|
||||
|
||||
UT_S2_SPI_DUAL:
|
||||
extends: .unit_test_esp32s2_template
|
||||
tags:
|
||||
- ESP32S2_IDF
|
||||
- Example_SPI_Multi_device
|
||||
|
||||
UT_S2_SDSPI:
|
||||
extends: .unit_test_esp32s2_template
|
||||
tags:
|
||||
- ESP32S2_IDF
|
||||
- UT_T1_SPIMODE
|
||||
|
||||
UT_C3:
|
||||
extends: .unit_test_esp32c3_template
|
||||
parallel: 33
|
||||
tags:
|
||||
- ESP32C3_IDF
|
||||
- UT_T1_1
|
||||
|
||||
UT_C3_FLASH:
|
||||
extends: .unit_test_esp32c3_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32C3_IDF
|
||||
- UT_T1_ESP_FLASH
|
||||
|
||||
UT_C3_SPI_DUAL:
|
||||
extends: .unit_test_esp32c3_template
|
||||
tags:
|
||||
- ESP32C3_IDF
|
||||
- Example_SPI_Multi_device
|
||||
|
||||
UT_C3_FLASH_ENC:
|
||||
extends: .unit_test_esp32c3_template
|
||||
tags:
|
||||
- ESP32C3_IDF
|
||||
- UT_T1_FlashEncryption
|
||||
|
||||
UT_C3_I2C:
|
||||
extends: .unit_test_esp32c3_template
|
||||
tags:
|
||||
- ESP32C3_IDF
|
||||
- UT_T2_I2C
|
||||
|
||||
UT_C3_FLASH_SUSPEND:
|
||||
extends: .unit_test_esp32c3_template
|
||||
tags:
|
||||
- ESP32C3_IDF
|
||||
- UT_T1_Flash_Suspend
|
||||
|
||||
UT_C3_SDSPI:
|
||||
extends: .unit_test_esp32c3_template
|
||||
tags:
|
||||
- ESP32C3_IDF
|
||||
- UT_T1_SPIMODE
|
||||
|
||||
UT_S3:
|
||||
extends: .unit_test_esp32s3_template
|
||||
parallel: 31
|
||||
tags:
|
||||
- ESP32S3_IDF
|
||||
- UT_T1_1
|
||||
|
||||
UT_S3_SPI_DUAL:
|
||||
extends: .unit_test_esp32s3_template
|
||||
tags:
|
||||
- ESP32S3_IDF
|
||||
- Example_SPI_Multi_device
|
||||
|
||||
UT_S3_FLASH:
|
||||
extends: .unit_test_esp32s3_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32S3_IDF
|
||||
- UT_T1_ESP_FLASH
|
||||
|
||||
component_ut_test_ip101:
|
||||
extends: .component_ut_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- COMPONENT_UT_IP101
|
||||
|
||||
component_ut_test_lan8720:
|
||||
extends: .component_ut_esp32_template
|
||||
tags:
|
||||
- ESP32
|
||||
- COMPONENT_UT_LAN8720
|
||||
|
||||
.integration_test_template:
|
||||
extends:
|
||||
- .target_test_job_template
|
||||
- .rules:test:integration_test
|
||||
needs:
|
||||
- assign_test
|
||||
- build_ssc_esp32
|
||||
variables:
|
||||
LOCAL_ENV_CONFIG_PATH: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF"
|
||||
LOG_PATH: "${CI_PROJECT_DIR}/TEST_LOGS"
|
||||
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/auto_test_script/TestCaseFiles"
|
||||
MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/components/idf_test/ModuleDefinition.yml"
|
||||
CONFIG_FILE_PATH: "${CI_PROJECT_DIR}/components/idf_test/integration_test/CIConfigs"
|
||||
KNOWN_ISSUE_FILE: "${CI_PROJECT_DIR}/components/idf_test/integration_test/KnownIssues"
|
||||
CI_RUNNER_SCRIPT: "${CI_PROJECT_DIR}/auto_test_script/bin/CIRunner.py"
|
||||
PYTHONPATH: ${CI_PROJECT_DIR}/auto_test_script/packages
|
||||
# auto_test_script only supports python 3.7.x
|
||||
PYTHON_VER: 3.7.7
|
||||
script:
|
||||
- *define_config_file_name
|
||||
# first test if config file exists, if not exist, exit 0
|
||||
- test -e $CONFIG_FILE || exit 0
|
||||
# clone local test env configs
|
||||
- retry_failed git clone $TEST_ENV_CONFIG_REPO
|
||||
- python $CHECKOUT_REF_SCRIPT ci-test-runner-configs ci-test-runner-configs
|
||||
# clone test bench
|
||||
# can not retry if downing git lfs files failed, so using empty_branch first.
|
||||
- retry_failed git clone ${CI_AUTO_TEST_SCRIPT_REPO_URL} -b empty_branch
|
||||
- retry_failed git -C auto_test_script checkout -f ${CI_AUTO_TEST_SCRIPT_REPO_BRANCH}
|
||||
- python $CHECKOUT_REF_SCRIPT auto_test_script auto_test_script --customized_only
|
||||
- cat ${KNOWN_ISSUE_FILE} >> ${TEST_CASE_FILE_PATH}/KnownIssues
|
||||
# run test
|
||||
- python ${CI_RUNNER_SCRIPT} -l "$LOG_PATH/$JOB_FULL_NAME" -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH
|
||||
|
||||
nvs_compatible_test:
|
||||
extends: .integration_test_template
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $LOG_PATH
|
||||
- nvs_wifi.bin
|
||||
expire_in: 1 mos
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- NVS_Compatible
|
||||
script:
|
||||
- *define_config_file_name
|
||||
# first test if config file exists, if not exist, exit 0
|
||||
- test -e $CONFIG_FILE || exit 0
|
||||
# clone local test env configs
|
||||
- retry_failed git clone $TEST_ENV_CONFIG_REPO
|
||||
- python $CHECKOUT_REF_SCRIPT ci-test-runner-configs ci-test-runner-configs
|
||||
# clone test bench
|
||||
# can not retry if downing git lfs files failed, so using empty_branch first.
|
||||
- retry_failed git clone ${CI_AUTO_TEST_SCRIPT_REPO_URL} -b empty_branch
|
||||
- retry_failed git -C auto_test_script checkout -f ${CI_AUTO_TEST_SCRIPT_REPO_BRANCH}
|
||||
- python $CHECKOUT_REF_SCRIPT auto_test_script auto_test_script --customized_only
|
||||
# prepare nvs bins
|
||||
- cd auto_test_script
|
||||
- ./tools/prepare_nvs_bin.sh
|
||||
# run test
|
||||
- python ${CI_RUNNER_SCRIPT} -l "$LOG_PATH/$JOB_FULL_NAME" -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH
|
||||
|
||||
IT_001:
|
||||
extends: .integration_test_template
|
||||
parallel: 3
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_4
|
||||
|
||||
IT_002:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_2
|
||||
|
||||
IT_003:
|
||||
extends: .integration_test_template
|
||||
parallel: 14
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_5
|
||||
|
||||
IT_004:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_APC
|
||||
|
||||
IT_005:
|
||||
extends: .integration_test_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_5
|
||||
|
||||
IT_006:
|
||||
extends: .integration_test_template
|
||||
parallel: 12
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_6
|
||||
|
||||
IT_007:
|
||||
extends: .integration_test_template
|
||||
parallel: 3
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_7
|
||||
|
||||
IT_008:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_8
|
||||
|
||||
IT_009:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_3
|
||||
|
||||
IT_011:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_MESH1
|
||||
|
||||
IT_012:
|
||||
extends: .integration_test_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_MESH1
|
||||
|
||||
IT_013:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T3_MESH1
|
||||
|
||||
IT_014:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T6_MESH1
|
||||
|
||||
IT_015:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T12_MESH1
|
||||
|
||||
IT_016:
|
||||
extends: .integration_test_template
|
||||
allow_failure: true
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T50_MESH1
|
||||
|
||||
IT_017:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_MESH2
|
||||
|
||||
IT_018:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_9
|
||||
|
||||
IT_019:
|
||||
extends: .integration_test_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_2
|
||||
|
||||
IT_020:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_3
|
||||
|
||||
IT_021:
|
||||
extends: .integration_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_4
|
||||
@@ -1,63 +0,0 @@
|
||||
_All texts in italics are instructional and should be replaced by contents or removed._
|
||||
|
||||
## Checklist
|
||||
|
||||
_This entire section can be deleted if all items are checked._
|
||||
|
||||
* [ ] Enough information to help reviewers understand the issue, its root cause, impact, and the proposed solution
|
||||
* [ ] Enough information to help reviewers understand the feature, its functional description, example, documentation, test cases, test results, feature TODO list
|
||||
* [ ] The MR Title describes the change, including the component name, ie "lwip: Add support for IP over Pigeon"
|
||||
* [ ] All related links, including JIRA, backport, submodule MR, are mentioned in the `Related` subsection.
|
||||
* [ ] Any GitHub issues are linked inside the git commit message and corresponding release notes
|
||||
* [ ] Add label for the area this MR is part of
|
||||
* [ ] For documentation updates, check if label `Docs` and `needs translation:CN` or `needs translation:EN` have been added when the other language version still needs the update. Skip adding the label if the document is not yet translated.
|
||||
* [ ] Check if documents requiring translation fall under get-started section. If yes, add the labels mentioned above. Then the documentation team will assign a translator for you. Please inform the translator to prepare translation once your MR is ready to merge. The translation should be included in your MR to get it merged. For more information, see documentation workflow in Wiki.
|
||||
* [ ] Any necessary "needs backport" labels are added
|
||||
* [ ] Check if this is a breaking change. If it is, add notes to the `Breaking change notes` subsection below
|
||||
* [ ] Release note entry if this is a new public feature, or a fix for an issue introduced in the previous release.
|
||||
* [ ] The commit log is clean and ready to merge.
|
||||
* [ ] All relevant CI jobs have been run, i.e. jobs which cover the code changed by the MR.
|
||||
|
||||
---
|
||||
|
||||
_For issues, put enough information here to help reviewers understand the issue, its root cause, impact, and the proposed solution._
|
||||
|
||||
_If this issue is a regression, specify in the `Related` subsection below, in which commit or MR it was introduced. This helps reviewers to check if the backport labels are set correctly._
|
||||
|
||||
---
|
||||
|
||||
_For features, put enough information here to help reviewers understand the feature, its functional description, example, documentation, test cases, test results, feature TODO list._
|
||||
|
||||
---
|
||||
|
||||
_For other small/non-public changes, which are not expected to be in the release notes, can be mentioned here, include:_
|
||||
|
||||
* changes that don't apply to customers, e.g. some CI fixes, test only MR and etc
|
||||
|
||||
## Related
|
||||
|
||||
* Mention or related JIRA tasks (e.g. IDF-0000), to make sure they get updated.
|
||||
* Mention submodule MR, if there is
|
||||
* Mention backport(ed) MR, if there is
|
||||
|
||||
_Don't touch the subsection titles below, they will be parsed by scripts._
|
||||
|
||||
## Release notes (Mandatory)
|
||||
|
||||
_Changes made in this MR that should go into the **Release Notes** should be listed here. Please use **past tense** and *specify the area (see maintainers page of IDF internal wiki)*. If there is a subscope, include it and separate with slash (`/`). Minor changes can go to the descriptions above without a release notes entry._
|
||||
|
||||
_Write all the changes in a **list** (Start at the beginning of the line with `-` or `*`). If multiple changes are made, each of them should take a single line. If there is only one change to list, it should still be the only line of a list. If this MR does not need any release notes, write "No release notes" here without the `-` or `*`. e.g._
|
||||
|
||||
* [WiFi] Changed/fixed/updated xxx
|
||||
* [WiFi] Added support of xxx
|
||||
* [Peripheral Drivers/I2S] Fixed xxx (https://github.com/espressif/esp-idf/issues/xxxx)
|
||||
|
||||
## Breaking change notes
|
||||
|
||||
_Remove this subsection if not used._
|
||||
|
||||
_If there are any breaking changes, please mention it here. Talking about (1) what is not accepted any more, (2) the alternative solution and (3) the benefits/reason. e.g._
|
||||
|
||||
_Please strictly follow the breaking change restriction, which means, if there is a breaking change but you are merging to non-major versions, you have to separate the breaking part out to another MR for a major version. The breaking change subsection is only accepted in MRs merging to major versions._
|
||||
|
||||
* [VFS/UART] Now vfs_uart_set_rts_cts accept one more instance argument, to support configuration to different ports.
|
||||
109
.gitmodules
vendored
109
.gitmodules
vendored
@@ -1,112 +1,43 @@
|
||||
#
|
||||
# All the relative URL paths are intended to be GitHub ones
|
||||
# For Espressif's public projects please use '../../espressif/proj', not a '../proj'
|
||||
#
|
||||
[submodule "components/esp32/lib"]
|
||||
path = components/esp32/lib
|
||||
url = https://github.com/espressif/esp32-wifi-lib.git
|
||||
|
||||
[submodule "components/esptool_py/esptool"]
|
||||
path = components/esptool_py/esptool
|
||||
url = ../../espressif/esptool.git
|
||||
url = https://github.com/espressif/esptool.git
|
||||
|
||||
[submodule "components/bt/controller/lib_esp32"]
|
||||
path = components/bt/controller/lib_esp32
|
||||
url = ../../espressif/esp32-bt-lib.git
|
||||
[submodule "components/bt/lib"]
|
||||
path = components/bt/lib
|
||||
url = https://github.com/espressif/esp32-bt-lib.git
|
||||
|
||||
[submodule "components/bootloader/subproject/components/micro-ecc/micro-ecc"]
|
||||
path = components/bootloader/subproject/components/micro-ecc/micro-ecc
|
||||
url = ../../kmackay/micro-ecc.git
|
||||
[submodule "components/micro-ecc/micro-ecc"]
|
||||
path = components/micro-ecc/micro-ecc
|
||||
url = https://github.com/kmackay/micro-ecc.git
|
||||
|
||||
[submodule "components/coap/libcoap"]
|
||||
path = components/coap/libcoap
|
||||
url = ../../obgm/libcoap.git
|
||||
url = https://github.com/obgm/libcoap.git
|
||||
|
||||
[submodule "components/aws_iot/aws-iot-device-sdk-embedded-C"]
|
||||
path = components/aws_iot/aws-iot-device-sdk-embedded-C
|
||||
url = https://github.com/espressif/aws-iot-device-sdk-embedded-C.git
|
||||
|
||||
[submodule "components/nghttp/nghttp2"]
|
||||
path = components/nghttp/nghttp2
|
||||
url = ../../nghttp2/nghttp2.git
|
||||
url = https://github.com/nghttp2/nghttp2.git
|
||||
|
||||
[submodule "components/libsodium/libsodium"]
|
||||
path = components/libsodium/libsodium
|
||||
url = ../../jedisct1/libsodium.git
|
||||
url = https://github.com/jedisct1/libsodium.git
|
||||
|
||||
[submodule "components/spiffs/spiffs"]
|
||||
path = components/spiffs/spiffs
|
||||
url = ../../pellepl/spiffs.git
|
||||
url = https://github.com/pellepl/spiffs.git
|
||||
|
||||
[submodule "components/json/cJSON"]
|
||||
path = components/json/cJSON
|
||||
url = ../../DaveGamble/cJSON.git
|
||||
url = https://github.com/DaveGamble/cJSON.git
|
||||
|
||||
[submodule "components/mbedtls/mbedtls"]
|
||||
path = components/mbedtls/mbedtls
|
||||
url = ../../espressif/mbedtls.git
|
||||
|
||||
[submodule "components/asio/asio"]
|
||||
path = components/asio/asio
|
||||
url = ../../espressif/asio.git
|
||||
|
||||
[submodule "components/expat/expat"]
|
||||
path = components/expat/expat
|
||||
url = ../../libexpat/libexpat.git
|
||||
|
||||
[submodule "components/lwip/lwip"]
|
||||
path = components/lwip/lwip
|
||||
url = ../../espressif/esp-lwip.git
|
||||
|
||||
[submodule "components/mqtt/esp-mqtt"]
|
||||
path = components/mqtt/esp-mqtt
|
||||
url = ../../espressif/esp-mqtt.git
|
||||
|
||||
[submodule "components/protobuf-c/protobuf-c"]
|
||||
path = components/protobuf-c/protobuf-c
|
||||
url = ../../protobuf-c/protobuf-c.git
|
||||
|
||||
[submodule "components/unity/unity"]
|
||||
path = components/unity/unity
|
||||
url = ../../ThrowTheSwitch/Unity.git
|
||||
|
||||
[submodule "examples/build_system/cmake/import_lib/main/lib/tinyxml2"]
|
||||
path = examples/build_system/cmake/import_lib/main/lib/tinyxml2
|
||||
url = ../../leethomason/tinyxml2.git
|
||||
|
||||
[submodule "components/bt/host/nimble/nimble"]
|
||||
path = components/bt/host/nimble/nimble
|
||||
url = ../../espressif/esp-nimble.git
|
||||
|
||||
[submodule "components/cbor/tinycbor"]
|
||||
path = components/cbor/tinycbor
|
||||
url = ../../intel/tinycbor.git
|
||||
|
||||
[submodule "components/esp_wifi/lib"]
|
||||
path = components/esp_wifi/lib
|
||||
url = ../../espressif/esp32-wifi-lib.git
|
||||
|
||||
[submodule "components/tinyusb/tinyusb"]
|
||||
path = components/tinyusb/tinyusb
|
||||
url = ../../espressif/tinyusb.git
|
||||
|
||||
[submodule "examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib"]
|
||||
path = examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib
|
||||
url = ../../espressif/esp-cryptoauthlib.git
|
||||
|
||||
[submodule "components/cmock/CMock"]
|
||||
path = components/cmock/CMock
|
||||
url = ../../ThrowTheSwitch/CMock.git
|
||||
|
||||
[submodule "components/openthread/openthread"]
|
||||
path = components/openthread/openthread
|
||||
url = ../../espressif/openthread.git
|
||||
|
||||
[submodule "components/bt/controller/lib_esp32c3_family"]
|
||||
path = components/bt/controller/lib_esp32c3_family
|
||||
url = ../../espressif/esp32c3-bt-lib.git
|
||||
|
||||
[submodule "components/esp_phy/lib"]
|
||||
path = components/esp_phy/lib
|
||||
url = ../../espressif/esp-phy-lib.git
|
||||
|
||||
[submodule "components/openthread/lib"]
|
||||
path = components/openthread/lib
|
||||
url = ../../espressif/esp-thread-lib.git
|
||||
|
||||
[submodule "components/ieee802154/lib"]
|
||||
path = components/ieee802154/lib
|
||||
url = ../../espressif/esp-ieee802154-lib.git
|
||||
url = https://github.com/espressif/mbedtls.git
|
||||
|
||||
26
.mypy.ini
26
.mypy.ini
@@ -1,26 +0,0 @@
|
||||
[mypy]
|
||||
|
||||
# Specifies the Python version used to parse and check the target program
|
||||
python_version = 3.9
|
||||
|
||||
# Disallows defining functions without type annotations or with incomplete type annotations
|
||||
# True => enforce type annotation in all function definitions
|
||||
disallow_untyped_defs = True
|
||||
|
||||
# Shows a warning when returning a value with type Any from a function declared with a non- Any return type
|
||||
warn_return_any = True
|
||||
|
||||
# Shows errors for missing return statements on some execution paths
|
||||
warn_no_return = True
|
||||
|
||||
# Suppress error messages about imports that cannot be resolved
|
||||
# True => ignore all import errors
|
||||
ignore_missing_imports = True
|
||||
|
||||
# Disallows defining functions with incomplete type annotations
|
||||
disallow_incomplete_defs = False
|
||||
|
||||
# Directs what to do with imports when the imported module is found as a .py file and not part of the files,
|
||||
# modules and packages provided on the command line.
|
||||
# SKIP -> mypy checks only single file, not included imports
|
||||
follow_imports = skip
|
||||
@@ -1,123 +0,0 @@
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.0.1
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
# note: whitespace exclusions use multiline regex, see https://pre-commit.com/#regular-expressions
|
||||
# items are:
|
||||
# 1 - some file extensions
|
||||
# 2 - any file matching *test*/*expected* (for host tests, if possible use this naming pattern always)
|
||||
# 3 - any directory named 'testdata'
|
||||
# 4 - IDF monitor test data
|
||||
exclude: &whitespace_excludes |
|
||||
(?x)^(
|
||||
.+\.(md|rst|map|bin)|
|
||||
.+test.*\/.*expected.*|
|
||||
.+\/testdata\/.+|
|
||||
.+test_idf_monitor\/tests\/.+
|
||||
)$
|
||||
- id: end-of-file-fixer
|
||||
exclude: *whitespace_excludes
|
||||
- id: check-executables-have-shebangs
|
||||
- id: mixed-line-ending
|
||||
args: ['-f=lf']
|
||||
- id: double-quote-string-fixer
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.9.2
|
||||
hooks:
|
||||
- id: flake8
|
||||
args: ['--config=.flake8', '--tee', '--benchmark']
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.9.3
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort (python)
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: check-executables
|
||||
name: Check File Permissions
|
||||
entry: tools/ci/check_executables.py --action executables
|
||||
language: python
|
||||
types: [executable]
|
||||
exclude: '\.pre-commit/.+'
|
||||
- id: check-executable-list
|
||||
name: Validate executable-list.txt
|
||||
entry: tools/ci/check_executables.py --action list
|
||||
language: python
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
- id: check-kconfigs
|
||||
name: Validate Kconfig files
|
||||
entry: tools/ci/check_kconfigs.py
|
||||
language: python
|
||||
files: '^Kconfig$|Kconfig.*$'
|
||||
- id: check-deprecated-kconfigs-options
|
||||
name: Check if any Kconfig Options Deprecated
|
||||
entry: tools/ci/check_deprecated_kconfigs.py
|
||||
language: python
|
||||
files: 'sdkconfig\.ci$|sdkconfig\.rename$|sdkconfig.*$'
|
||||
- id: cmake-lint
|
||||
name: Check CMake Files Format
|
||||
entry: cmakelint --linelength=120 --spaces=4 --filter=-whitespace/indent
|
||||
language: python
|
||||
additional_dependencies:
|
||||
- cmakelint==1.4.1
|
||||
files: 'CMakeLists.txt$|\.cmake$'
|
||||
exclude: '\/third_party\/'
|
||||
- id: check-codeowners
|
||||
name: Validate Codeowner File
|
||||
entry: tools/ci/check_codeowners.py ci-check
|
||||
language: python
|
||||
files: '\.gitlab/CODEOWNERS'
|
||||
pass_filenames: false
|
||||
- id: check-rules-yml
|
||||
name: Check rules.yml all rules have at lease one job applied, all rules needed exist
|
||||
entry: tools/ci/check_rules_yml.py
|
||||
language: python
|
||||
files: '\.gitlab/ci/.+\.yml|\.gitlab-ci.yml'
|
||||
pass_filenames: false
|
||||
additional_dependencies:
|
||||
- PyYAML == 5.3.1
|
||||
- id: check-generated-rules
|
||||
name: Check rules are generated (based on .gitlab/ci/dependencies/dependencies.yml)
|
||||
entry: .gitlab/ci/dependencies/generate_rules.py
|
||||
language: python
|
||||
files: '\.gitlab/ci/dependencies/.+|\.gitlab/ci/rules\.yml'
|
||||
pass_filenames: false
|
||||
additional_dependencies:
|
||||
- PyYAML == 5.3.1
|
||||
- id: mypy-check
|
||||
name: Check type annotations in python files
|
||||
entry: tools/ci/check_type_comments.py
|
||||
additional_dependencies:
|
||||
- 'mypy==0.800'
|
||||
- 'mypy-extensions==0.4.3'
|
||||
language: python
|
||||
types: [python]
|
||||
- id: check-copyright
|
||||
name: Check copyright notices
|
||||
entry: tools/ci/check_copyright.py --verbose --replace
|
||||
additional_dependencies:
|
||||
- 'comment_parser == 1.2.3'
|
||||
- 'thefuzz == 0.19.0'
|
||||
- 'thefuzz[speedup] == 0.19.0; sys_platform != "win32"'
|
||||
# don't depend on python-Levenshtein on Windows, as it requires Microsoft C++ Build Tools to install
|
||||
language: python
|
||||
files: \.(py|c|h|cpp|hpp|ld)$
|
||||
require_serial: true
|
||||
- id: check-tools-files-patterns
|
||||
name: Check tools dir files patterns
|
||||
entry: tools/ci/check_tools_files_patterns.py
|
||||
language: python
|
||||
files: '^tools/.+'
|
||||
additional_dependencies:
|
||||
- PyYAML == 5.3.1
|
||||
pass_filenames: false
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.0.1
|
||||
hooks:
|
||||
- id: file-contents-sorter
|
||||
files: 'tools\/ci\/(executable-list\.txt|mypy_ignore_list\.txt|check_copyright_ignore\.txt|check_copyright_permanent_ignore\.txt)'
|
||||
606
.pylintrc
606
.pylintrc
@@ -1,606 +0,0 @@
|
||||
[MASTER]
|
||||
|
||||
# A comma-separated list of package or module names from where C extensions may
|
||||
# be loaded. Extensions are loading into the active Python interpreter and may
|
||||
# run arbitrary code.
|
||||
extension-pkg-whitelist=
|
||||
|
||||
# Specify a score threshold to be exceeded before program exits with error.
|
||||
fail-under=10
|
||||
|
||||
# Add files or directories to the blacklist. They should be base names, not
|
||||
# paths.
|
||||
ignore=CVS
|
||||
|
||||
# Add files or directories matching the regex patterns to the blacklist. The
|
||||
# regex matches against base names, not paths.
|
||||
ignore-patterns=
|
||||
|
||||
# Python code to execute, usually for sys.path manipulation such as
|
||||
# pygtk.require().
|
||||
#init-hook=
|
||||
|
||||
# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
|
||||
# number of processors available to use.
|
||||
jobs=1
|
||||
|
||||
# Control the amount of potential inferred values when inferring a single
|
||||
# object. This can help the performance when dealing with large functions or
|
||||
# complex, nested conditions.
|
||||
limit-inference-results=100
|
||||
|
||||
# List of plugins (as comma separated values of python module names) to load,
|
||||
# usually to register additional checkers.
|
||||
load-plugins=
|
||||
|
||||
# Pickle collected data for later comparisons.
|
||||
persistent=yes
|
||||
|
||||
# When enabled, pylint would attempt to guess common misconfiguration and emit
|
||||
# user-friendly hints instead of false-positive error messages.
|
||||
suggestion-mode=yes
|
||||
|
||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
||||
# active Python interpreter and may run arbitrary code.
|
||||
unsafe-load-any-extension=no
|
||||
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
|
||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.
|
||||
confidence=
|
||||
|
||||
# Disable the message, report, category or checker with the given id(s). You
|
||||
# can either give multiple identifiers separated by comma (,) or put this
|
||||
# option multiple times (only on the command line, not in the configuration
|
||||
# file where it should appear only once). You can also use "--disable=all" to
|
||||
# disable everything first and then reenable specific checks. For example, if
|
||||
# you want to run only the similarities checker, you can use "--disable=all
|
||||
# --enable=similarities". If you want to run only the classes checker, but have
|
||||
# no Warning level messages displayed, use "--disable=all --enable=classes
|
||||
# --disable=W".
|
||||
disable=print-statement,
|
||||
parameter-unpacking,
|
||||
unpacking-in-except,
|
||||
old-raise-syntax,
|
||||
backtick,
|
||||
long-suffix,
|
||||
old-ne-operator,
|
||||
old-octal-literal,
|
||||
import-star-module-level,
|
||||
non-ascii-bytes-literal,
|
||||
raw-checker-failed,
|
||||
bad-inline-option,
|
||||
locally-disabled,
|
||||
file-ignored,
|
||||
suppressed-message,
|
||||
useless-suppression,
|
||||
deprecated-pragma,
|
||||
use-symbolic-message-instead,
|
||||
apply-builtin,
|
||||
basestring-builtin,
|
||||
buffer-builtin,
|
||||
cmp-builtin,
|
||||
coerce-builtin,
|
||||
execfile-builtin,
|
||||
file-builtin,
|
||||
long-builtin,
|
||||
raw_input-builtin,
|
||||
reduce-builtin,
|
||||
standarderror-builtin,
|
||||
unicode-builtin,
|
||||
xrange-builtin,
|
||||
coerce-method,
|
||||
delslice-method,
|
||||
getslice-method,
|
||||
setslice-method,
|
||||
no-absolute-import,
|
||||
old-division,
|
||||
dict-iter-method,
|
||||
dict-view-method,
|
||||
next-method-called,
|
||||
metaclass-assignment,
|
||||
indexing-exception,
|
||||
raising-string,
|
||||
reload-builtin,
|
||||
oct-method,
|
||||
hex-method,
|
||||
nonzero-method,
|
||||
cmp-method,
|
||||
input-builtin,
|
||||
round-builtin,
|
||||
intern-builtin,
|
||||
unichr-builtin,
|
||||
map-builtin-not-iterating,
|
||||
zip-builtin-not-iterating,
|
||||
range-builtin-not-iterating,
|
||||
filter-builtin-not-iterating,
|
||||
using-cmp-argument,
|
||||
eq-without-hash,
|
||||
div-method,
|
||||
idiv-method,
|
||||
rdiv-method,
|
||||
exception-message-attribute,
|
||||
invalid-str-codec,
|
||||
sys-max-int,
|
||||
bad-python3-import,
|
||||
deprecated-string-function,
|
||||
deprecated-str-translate-call,
|
||||
deprecated-itertools-function,
|
||||
deprecated-types-field,
|
||||
next-method-defined,
|
||||
dict-items-not-iterating,
|
||||
dict-keys-not-iterating,
|
||||
dict-values-not-iterating,
|
||||
deprecated-operator-function,
|
||||
deprecated-urllib-function,
|
||||
xreadlines-attribute,
|
||||
deprecated-sys-function,
|
||||
exception-escape,
|
||||
comprehension-escape,
|
||||
missing-function-docstring, # Modified since here, include this line
|
||||
missing-class-docstring,
|
||||
missing-module-docstring,
|
||||
wrong-import-order,
|
||||
invalid-name,
|
||||
too-few-public-methods,
|
||||
too-many-locals,
|
||||
bad-super-call, # since we still haven't drop python2 support
|
||||
too-many-nested-blocks,
|
||||
too-many-branches,
|
||||
too-many-statements,
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
# either give multiple identifier separated by comma (,) or put this option
|
||||
# multiple time (only on the command line, not in the configuration file where
|
||||
# it should appear only once). See also the "--disable" option for examples.
|
||||
enable=c-extension-no-member
|
||||
|
||||
|
||||
[REPORTS]
|
||||
|
||||
# Python expression which should return a score less than or equal to 10. You
|
||||
# have access to the variables 'error', 'warning', 'refactor', and 'convention'
|
||||
# which contain the number of messages in each category, as well as 'statement'
|
||||
# which is the total number of statements analyzed. This score is used by the
|
||||
# global evaluation report (RP0004).
|
||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
||||
|
||||
# Template used to display messages. This is a python new-style format string
|
||||
# used to format the message information. See doc for all details.
|
||||
#msg-template=
|
||||
|
||||
# Set the output format. Available formats are text, parseable, colorized, json
|
||||
# and msvs (visual studio). You can also give a reporter class, e.g.
|
||||
# mypackage.mymodule.MyReporterClass.
|
||||
output-format=text
|
||||
|
||||
# Tells whether to display a full report or only the messages.
|
||||
reports=no
|
||||
|
||||
# Activate the evaluation score.
|
||||
score=yes
|
||||
|
||||
|
||||
[REFACTORING]
|
||||
|
||||
# Maximum number of nested blocks for function / method body
|
||||
max-nested-blocks=5
|
||||
|
||||
# Complete name of functions that never returns. When checking for
|
||||
# inconsistent-return-statements if a never returning function is called then
|
||||
# it will be considered as an explicit return statement and no message will be
|
||||
# printed.
|
||||
never-returning-functions=sys.exit
|
||||
|
||||
|
||||
[TYPECHECK]
|
||||
|
||||
# List of decorators that produce context managers, such as
|
||||
# contextlib.contextmanager. Add to this list to register other decorators that
|
||||
# produce valid context managers.
|
||||
contextmanager-decorators=contextlib.contextmanager
|
||||
|
||||
# List of members which are set dynamically and missed by pylint inference
|
||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
||||
# expressions are accepted.
|
||||
generated-members=
|
||||
|
||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
||||
ignore-mixin-members=yes
|
||||
|
||||
# Tells whether to warn about missing members when the owner of the attribute
|
||||
# is inferred to be None.
|
||||
ignore-none=yes
|
||||
|
||||
# This flag controls whether pylint should warn about no-member and similar
|
||||
# checks whenever an opaque object is returned when inferring. The inference
|
||||
# can return multiple potential results while evaluating a Python object, but
|
||||
# some branches might not be evaluated, which results in partial inference. In
|
||||
# that case, it might be useful to still emit no-member and other checks for
|
||||
# the rest of the inferred objects.
|
||||
ignore-on-opaque-inference=yes
|
||||
|
||||
# List of class names for which member attributes should not be checked (useful
|
||||
# for classes with dynamically set attributes). This supports the use of
|
||||
# qualified names.
|
||||
ignored-classes=optparse.Values,thread._local,_thread._local
|
||||
|
||||
# List of module names for which member attributes should not be checked
|
||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
||||
# and thus existing member attributes cannot be deduced by static analysis). It
|
||||
# supports qualified module names, as well as Unix pattern matching.
|
||||
ignored-modules=
|
||||
|
||||
# Show a hint with possible names when a member name was not found. The aspect
|
||||
# of finding the hint is based on edit distance.
|
||||
missing-member-hint=yes
|
||||
|
||||
# The minimum edit distance a name should have in order to be considered a
|
||||
# similar match for a missing member name.
|
||||
missing-member-hint-distance=1
|
||||
|
||||
# The total number of similar names that should be taken in consideration when
|
||||
# showing a hint for a missing member.
|
||||
missing-member-max-choices=1
|
||||
|
||||
# List of decorators that change the signature of a decorated function.
|
||||
signature-mutators=ttfw_idf.idf_example_test,ttfw_idf.idf_unit_test,ttfw_idf.idf_custom_test,ttfw_idf.idf_component_unit_test
|
||||
|
||||
|
||||
[SPELLING]
|
||||
|
||||
# Limits count of emitted suggestions for spelling mistakes.
|
||||
max-spelling-suggestions=4
|
||||
|
||||
# Spelling dictionary name. Available dictionaries: none. To make it work,
|
||||
# install the python-enchant package.
|
||||
spelling-dict=
|
||||
|
||||
# List of comma separated words that should not be checked.
|
||||
spelling-ignore-words=
|
||||
|
||||
# A path to a file that contains the private dictionary; one word per line.
|
||||
spelling-private-dict-file=
|
||||
|
||||
# Tells whether to store unknown words to the private dictionary (see the
|
||||
# --spelling-private-dict-file option) instead of raising a message.
|
||||
spelling-store-unknown-words=no
|
||||
|
||||
|
||||
[FORMAT]
|
||||
|
||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
||||
expected-line-ending-format=
|
||||
|
||||
# Regexp for a line that is allowed to be longer than the limit.
|
||||
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
||||
|
||||
# Number of spaces of indent required inside a hanging or continued line.
|
||||
indent-after-paren=4
|
||||
|
||||
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
||||
# tab).
|
||||
indent-string=' '
|
||||
|
||||
# Maximum number of characters on a single line.
|
||||
max-line-length=160
|
||||
|
||||
# Maximum number of lines in a module.
|
||||
max-module-lines=1000
|
||||
|
||||
# List of optional constructs for which whitespace checking is disabled. `dict-
|
||||
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
|
||||
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
|
||||
# `empty-line` allows space-only lines.
|
||||
no-space-check=trailing-comma,
|
||||
dict-separator
|
||||
|
||||
# Allow the body of a class to be on the same line as the declaration if body
|
||||
# contains single statement.
|
||||
single-line-class-stmt=no
|
||||
|
||||
# Allow the body of an if to be on the same line as the test if there is no
|
||||
# else.
|
||||
single-line-if-stmt=no
|
||||
|
||||
|
||||
[STRING]
|
||||
|
||||
# This flag controls whether inconsistent-quotes generates a warning when the
|
||||
# character used as a quote delimiter is used inconsistently within a module.
|
||||
check-quote-consistency=no
|
||||
|
||||
# This flag controls whether the implicit-str-concat should generate a warning
|
||||
# on implicit string concatenation in sequences defined over several lines.
|
||||
check-str-concat-over-line-jumps=no
|
||||
|
||||
|
||||
[LOGGING]
|
||||
|
||||
# The type of string formatting that logging methods do. `old` means using %
|
||||
# formatting, `new` is for `{}` formatting.
|
||||
logging-format-style=old
|
||||
|
||||
# Logging modules to check that the string format arguments are in logging
|
||||
# function parameter format.
|
||||
logging-modules=logging
|
||||
|
||||
|
||||
[MISCELLANEOUS]
|
||||
|
||||
# List of note tags to take in consideration, separated by a comma.
|
||||
notes=FIXME,
|
||||
XXX,
|
||||
TODO
|
||||
|
||||
# Regular expression of note tags to take in consideration.
|
||||
#notes-rgx=
|
||||
|
||||
|
||||
[SIMILARITIES]
|
||||
|
||||
# Ignore comments when computing similarities.
|
||||
ignore-comments=yes
|
||||
|
||||
# Ignore docstrings when computing similarities.
|
||||
ignore-docstrings=yes
|
||||
|
||||
# Ignore imports when computing similarities.
|
||||
ignore-imports=no
|
||||
|
||||
# Minimum lines number of a similarity.
|
||||
min-similarity-lines=4
|
||||
|
||||
|
||||
[VARIABLES]
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid defining new builtins when possible.
|
||||
additional-builtins=
|
||||
|
||||
# Tells whether unused global variables should be treated as a violation.
|
||||
allow-global-unused-variables=yes
|
||||
|
||||
# List of strings which can identify a callback function by name. A callback
|
||||
# name must start or end with one of those strings.
|
||||
callbacks=cb_,
|
||||
_cb
|
||||
|
||||
# A regular expression matching the name of dummy variables (i.e. expected to
|
||||
# not be used).
|
||||
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
|
||||
|
||||
# Argument names that match this expression will be ignored. Default to name
|
||||
# with leading underscore.
|
||||
ignored-argument-names=_.*|^ignored_|^unused_
|
||||
|
||||
# Tells whether we should check for unused import in __init__ files.
|
||||
init-import=no
|
||||
|
||||
# List of qualified module names which can have objects that can redefine
|
||||
# builtins.
|
||||
redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
|
||||
|
||||
|
||||
[BASIC]
|
||||
|
||||
# Naming style matching correct argument names.
|
||||
argument-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct argument names. Overrides argument-
|
||||
# naming-style.
|
||||
#argument-rgx=
|
||||
|
||||
# Naming style matching correct attribute names.
|
||||
attr-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct attribute names. Overrides attr-naming-
|
||||
# style.
|
||||
#attr-rgx=
|
||||
|
||||
# Bad variable names which should always be refused, separated by a comma.
|
||||
bad-names=foo,
|
||||
bar,
|
||||
baz,
|
||||
toto,
|
||||
tutu,
|
||||
tata
|
||||
|
||||
# Bad variable names regexes, separated by a comma. If names match any regex,
|
||||
# they will always be refused
|
||||
bad-names-rgxs=
|
||||
|
||||
# Naming style matching correct class attribute names.
|
||||
class-attribute-naming-style=any
|
||||
|
||||
# Regular expression matching correct class attribute names. Overrides class-
|
||||
# attribute-naming-style.
|
||||
#class-attribute-rgx=
|
||||
|
||||
# Naming style matching correct class names.
|
||||
class-naming-style=PascalCase
|
||||
|
||||
# Regular expression matching correct class names. Overrides class-naming-
|
||||
# style.
|
||||
#class-rgx=
|
||||
|
||||
# Naming style matching correct constant names.
|
||||
const-naming-style=UPPER_CASE
|
||||
|
||||
# Regular expression matching correct constant names. Overrides const-naming-
|
||||
# style.
|
||||
#const-rgx=
|
||||
|
||||
# Minimum line length for functions/classes that require docstrings, shorter
|
||||
# ones are exempt.
|
||||
docstring-min-length=-1
|
||||
|
||||
# Naming style matching correct function names.
|
||||
function-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct function names. Overrides function-
|
||||
# naming-style.
|
||||
#function-rgx=
|
||||
|
||||
# Good variable names which should always be accepted, separated by a comma.
|
||||
good-names=i,
|
||||
j,
|
||||
k,
|
||||
ex,
|
||||
Run,
|
||||
_
|
||||
|
||||
# Good variable names regexes, separated by a comma. If names match any regex,
|
||||
# they will always be accepted
|
||||
good-names-rgxs=
|
||||
|
||||
# Include a hint for the correct naming format with invalid-name.
|
||||
include-naming-hint=no
|
||||
|
||||
# Naming style matching correct inline iteration names.
|
||||
inlinevar-naming-style=any
|
||||
|
||||
# Regular expression matching correct inline iteration names. Overrides
|
||||
# inlinevar-naming-style.
|
||||
#inlinevar-rgx=
|
||||
|
||||
# Naming style matching correct method names.
|
||||
method-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct method names. Overrides method-naming-
|
||||
# style.
|
||||
#method-rgx=
|
||||
|
||||
# Naming style matching correct module names.
|
||||
module-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct module names. Overrides module-naming-
|
||||
# style.
|
||||
#module-rgx=
|
||||
|
||||
# Colon-delimited sets of names that determine each other's naming style when
|
||||
# the name regexes allow several styles.
|
||||
name-group=
|
||||
|
||||
# Regular expression which should only match function or class names that do
|
||||
# not require a docstring.
|
||||
no-docstring-rgx=^_
|
||||
|
||||
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
||||
# to this list to register other decorators that produce valid properties.
|
||||
# These decorators are taken in consideration only for invalid-name.
|
||||
property-classes=abc.abstractproperty
|
||||
|
||||
# Naming style matching correct variable names.
|
||||
variable-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct variable names. Overrides variable-
|
||||
# naming-style.
|
||||
#variable-rgx=
|
||||
|
||||
|
||||
[DESIGN]
|
||||
|
||||
# Maximum number of arguments for function / method.
|
||||
max-args=5
|
||||
|
||||
# Maximum number of attributes for a class (see R0902).
|
||||
max-attributes=12
|
||||
|
||||
# Maximum number of boolean expressions in an if statement (see R0916).
|
||||
max-bool-expr=5
|
||||
|
||||
# Maximum number of branch for function / method body.
|
||||
max-branches=12
|
||||
|
||||
# Maximum number of locals for function / method body.
|
||||
max-locals=15
|
||||
|
||||
# Maximum number of parents for a class (see R0901).
|
||||
max-parents=7
|
||||
|
||||
# Maximum number of public methods for a class (see R0904).
|
||||
max-public-methods=20
|
||||
|
||||
# Maximum number of return / yield for function / method body.
|
||||
max-returns=6
|
||||
|
||||
# Maximum number of statements in function / method body.
|
||||
max-statements=50
|
||||
|
||||
# Minimum number of public methods for a class (see R0903).
|
||||
min-public-methods=2
|
||||
|
||||
|
||||
[CLASSES]
|
||||
|
||||
# List of method names used to declare (i.e. assign) instance attributes.
|
||||
defining-attr-methods=__init__,
|
||||
__new__,
|
||||
setUp,
|
||||
__post_init__
|
||||
|
||||
# List of member names, which should be excluded from the protected access
|
||||
# warning.
|
||||
exclude-protected=_asdict,
|
||||
_fields,
|
||||
_replace,
|
||||
_source,
|
||||
_make
|
||||
|
||||
# List of valid names for the first argument in a class method.
|
||||
valid-classmethod-first-arg=cls
|
||||
|
||||
# List of valid names for the first argument in a metaclass class method.
|
||||
valid-metaclass-classmethod-first-arg=cls
|
||||
|
||||
|
||||
[IMPORTS]
|
||||
|
||||
# List of modules that can be imported at any level, not just the top level
|
||||
# one.
|
||||
allow-any-import-level=
|
||||
|
||||
# Allow wildcard imports from modules that define __all__.
|
||||
allow-wildcard-with-all=no
|
||||
|
||||
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
||||
# 3 compatible code, which means that the block might have code that exists
|
||||
# only in one or another interpreter, leading to false positives when analysed.
|
||||
analyse-fallback-blocks=no
|
||||
|
||||
# Deprecated modules which should not be used, separated by a comma.
|
||||
deprecated-modules=optparse,tkinter.tix
|
||||
|
||||
# Create a graph of external dependencies in the given file (report RP0402 must
|
||||
# not be disabled).
|
||||
ext-import-graph=
|
||||
|
||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
||||
# given file (report RP0402 must not be disabled).
|
||||
import-graph=
|
||||
|
||||
# Create a graph of internal dependencies in the given file (report RP0402 must
|
||||
# not be disabled).
|
||||
int-import-graph=
|
||||
|
||||
# Force import order to recognize a module as part of the standard
|
||||
# compatibility libraries.
|
||||
known-standard-library=
|
||||
|
||||
# Force import order to recognize a module as part of a third party library.
|
||||
known-third-party=enchant
|
||||
|
||||
# Couples of modules and preferred modules, separated by a comma.
|
||||
preferred-modules=
|
||||
|
||||
|
||||
[EXCEPTIONS]
|
||||
|
||||
# Exceptions that will emit a warning when being caught. Defaults to
|
||||
# "BaseException, Exception".
|
||||
overgeneral-exceptions=BaseException,
|
||||
Exception
|
||||
@@ -13,9 +13,4 @@ formats:
|
||||
python:
|
||||
version: 2.7
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
|
||||
# We need to list all the submodules included in documenation build by DOxygen
|
||||
submodules:
|
||||
include:
|
||||
- components/mqtt/esp-mqtt
|
||||
- requirements: docs/requirements.txt
|
||||
207
CMakeLists.txt
207
CMakeLists.txt
@@ -1,207 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(esp-idf C CXX ASM)
|
||||
|
||||
if(CMAKE_CURRENT_LIST_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
message(FATAL_ERROR "Current directory '${CMAKE_CURRENT_LIST_DIR}' is not buildable. "
|
||||
"Change directories to one of the example projects in '${CMAKE_CURRENT_LIST_DIR}/examples' and try "
|
||||
"again.")
|
||||
endif()
|
||||
|
||||
unset(compile_options)
|
||||
unset(c_compile_options)
|
||||
unset(cxx_compile_options)
|
||||
unset(compile_definitions)
|
||||
unset(link_options)
|
||||
|
||||
# Add the following build specifications here, since these seem to be dependent
|
||||
# on config values on the root Kconfig.
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
|
||||
if(CONFIG_COMPILER_OPTIMIZATION_SIZE)
|
||||
list(APPEND compile_options "-Os")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
list(APPEND compile_options "-freorder-blocks")
|
||||
endif()
|
||||
elseif(CONFIG_COMPILER_OPTIMIZATION_DEFAULT)
|
||||
list(APPEND compile_options "-Og")
|
||||
elseif(CONFIG_COMPILER_OPTIMIZATION_NONE)
|
||||
list(APPEND compile_options "-O0")
|
||||
elseif(CONFIG_COMPILER_OPTIMIZATION_PERF)
|
||||
list(APPEND compile_options "-O2")
|
||||
endif()
|
||||
|
||||
else() # BOOTLOADER_BUILD
|
||||
|
||||
if(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE)
|
||||
list(APPEND compile_options "-Os")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
list(APPEND compile_options "-freorder-blocks")
|
||||
endif()
|
||||
elseif(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG)
|
||||
list(APPEND compile_options "-Og")
|
||||
elseif(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE)
|
||||
list(APPEND compile_options "-O0")
|
||||
elseif(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF)
|
||||
list(APPEND compile_options "-O2")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_CXX_EXCEPTIONS)
|
||||
list(APPEND cxx_compile_options "-fexceptions")
|
||||
else()
|
||||
list(APPEND cxx_compile_options "-fno-exceptions")
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_CXX_RTTI)
|
||||
list(APPEND cxx_compile_options "-frtti")
|
||||
else()
|
||||
list(APPEND cxx_compile_options "-fno-rtti")
|
||||
list(APPEND link_options "-fno-rtti") # used to invoke correct multilib variant (no-rtti) during linking
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS)
|
||||
list(APPEND compile_options "-msave-restore")
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_DISABLE_GCC8_WARNINGS)
|
||||
list(APPEND compile_options "-Wno-parentheses"
|
||||
"-Wno-sizeof-pointer-memaccess"
|
||||
"-Wno-clobbered")
|
||||
|
||||
list(APPEND compile_options "-Wno-format-overflow"
|
||||
"-Wno-stringop-truncation"
|
||||
"-Wno-misleading-indentation"
|
||||
"-Wno-cast-function-type"
|
||||
"-Wno-implicit-fallthrough"
|
||||
"-Wno-unused-const-variable"
|
||||
"-Wno-switch-unreachable"
|
||||
"-Wno-format-truncation"
|
||||
"-Wno-memset-elt-size"
|
||||
"-Wno-int-in-bool-context")
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
list(APPEND c_compile_options "-Wno-old-style-declaration")
|
||||
endif()
|
||||
|
||||
# Clang finds some warnings in IDF code which GCC doesn't.
|
||||
# All these warnings should be fixed before Clang is presented
|
||||
# as a toolchain choice for users.
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
# Clang checks Doxygen comments for being in sync with function prototype.
|
||||
# There are some inconsistencies, especially in ROM headers.
|
||||
list(APPEND compile_options "-Wno-documentation")
|
||||
# GCC allows repeated typedefs when the source and target types are the same.
|
||||
# Clang doesn't allow this. This occurs in many components due to forward
|
||||
# declarations.
|
||||
list(APPEND compile_options "-Wno-typedef-redefinition")
|
||||
# This issue is seemingly related to newlib's char type functions.
|
||||
# Fix is not clear yet.
|
||||
list(APPEND compile_options "-Wno-char-subscripts")
|
||||
# Clang seems to notice format string issues which GCC doesn't.
|
||||
list(APPEND compile_options "-Wno-format-security")
|
||||
# Logic bug in essl component
|
||||
list(APPEND compile_options "-Wno-tautological-overlap-compare")
|
||||
# Some pointer checks in mDNS component check addresses which can't be NULL
|
||||
list(APPEND compile_options "-Wno-tautological-pointer-compare")
|
||||
# Similar to the above, in tcp_transport
|
||||
list(APPEND compile_options "-Wno-pointer-bool-conversion")
|
||||
# mbedTLS md5.c triggers this warning in md5_test_buf (false positive)
|
||||
list(APPEND compile_options "-Wno-string-concatenation")
|
||||
# multiple cases of implict convertions between unrelated enum types
|
||||
list(APPEND compile_options "-Wno-enum-conversion")
|
||||
# When IRAM_ATTR is specified both in function declaration and definition,
|
||||
# it produces different section names, since section names include __COUNTER__.
|
||||
# Occurs in multiple places.
|
||||
list(APPEND compile_options "-Wno-section")
|
||||
# Multiple cases of attributes unknown to clang, for example
|
||||
# __attribute__((optimize("-O3")))
|
||||
list(APPEND compile_options "-Wno-unknown-attributes")
|
||||
# Clang also produces many -Wunused-function warnings which GCC doesn't.
|
||||
# However these aren't treated as errors.
|
||||
endif()
|
||||
# More warnings may exist in unit tests and example projects.
|
||||
|
||||
if(CONFIG_COMPILER_WARN_WRITE_STRINGS)
|
||||
list(APPEND compile_options "-Wwrite-strings")
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE)
|
||||
list(APPEND compile_definitions "-DNDEBUG")
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_STACK_CHECK_MODE_NORM)
|
||||
list(APPEND compile_options "-fstack-protector")
|
||||
elseif(CONFIG_COMPILER_STACK_CHECK_MODE_STRONG)
|
||||
list(APPEND compile_options "-fstack-protector-strong")
|
||||
elseif(CONFIG_COMPILER_STACK_CHECK_MODE_ALL)
|
||||
list(APPEND compile_options "-fstack-protector-all")
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_DUMP_RTL_FILES)
|
||||
list(APPEND compile_options "-fdump-rtl-expand")
|
||||
endif()
|
||||
|
||||
if(NOT ${CMAKE_C_COMPILER_VERSION} VERSION_LESS 8.0.0)
|
||||
if(CONFIG_COMPILER_HIDE_PATHS_MACROS)
|
||||
list(APPEND compile_options "-fmacro-prefix-map=${CMAKE_SOURCE_DIR}=.")
|
||||
list(APPEND compile_options "-fmacro-prefix-map=${IDF_PATH}=IDF")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# GCC-specific options
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
list(APPEND compile_options "-fstrict-volatile-bitfields"
|
||||
"-Wno-error=unused-but-set-variable"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CONFIG_ESP_SYSTEM_USE_EH_FRAME)
|
||||
list(APPEND compile_options "-fasynchronous-unwind-tables")
|
||||
list(APPEND link_options "-Wl,--eh-frame-hdr")
|
||||
endif()
|
||||
|
||||
list(APPEND link_options "-fno-lto")
|
||||
|
||||
# Placing jump tables in flash would cause issues with code that required
|
||||
# to be placed in IRAM
|
||||
list(APPEND compile_options "-fno-jump-tables")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
# This flag is GCC-specific.
|
||||
# Not clear yet if some other flag should be used for Clang.
|
||||
list(APPEND compile_options "-fno-tree-switch-conversion")
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "LLVM")
|
||||
list(APPEND compile_options "-fno-use-cxa-atexit")
|
||||
endif()
|
||||
|
||||
idf_build_set_property(COMPILE_OPTIONS "${compile_options}" APPEND)
|
||||
idf_build_set_property(C_COMPILE_OPTIONS "${c_compile_options}" APPEND)
|
||||
idf_build_set_property(CXX_COMPILE_OPTIONS "${cxx_compile_options}" APPEND)
|
||||
idf_build_set_property(COMPILE_DEFINITIONS "${compile_definitions}" APPEND)
|
||||
idf_build_set_property(LINK_OPTIONS "${link_options}" APPEND)
|
||||
|
||||
idf_build_get_property(build_component_targets __BUILD_COMPONENT_TARGETS)
|
||||
|
||||
# Add each component as a subdirectory, processing each component's CMakeLists.txt
|
||||
foreach(component_target ${build_component_targets})
|
||||
__component_get_property(dir ${component_target} COMPONENT_DIR)
|
||||
__component_get_property(_name ${component_target} COMPONENT_NAME)
|
||||
__component_get_property(prefix ${component_target} __PREFIX)
|
||||
__component_get_property(alias ${component_target} COMPONENT_ALIAS)
|
||||
set(COMPONENT_NAME ${_name})
|
||||
set(COMPONENT_DIR ${dir})
|
||||
set(COMPONENT_ALIAS ${alias})
|
||||
set(COMPONENT_PATH ${dir}) # for backward compatibility only, COMPONENT_DIR is preferred
|
||||
idf_build_get_property(build_prefix __PREFIX)
|
||||
set(__idf_component_context 1)
|
||||
if(NOT prefix STREQUAL build_prefix)
|
||||
add_subdirectory(${dir} ${prefix}_${_name})
|
||||
else()
|
||||
add_subdirectory(${dir} ${_name})
|
||||
endif()
|
||||
set(__idf_component_context 0)
|
||||
endforeach()
|
||||
@@ -6,7 +6,7 @@ We welcome contributions to the esp-idf project!
|
||||
How to Contribute
|
||||
-----------------
|
||||
|
||||
Contributions to esp-idf - fixing bugs, adding features, adding documentation - are welcome. We accept contributions via `Github Pull Requests <https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests>`_.
|
||||
Contributions to esp-idf - fixing bugs, adding features, adding documentation - are welcome. We accept contributions via `Github Pull Requests <https://help.github.com/articles/about-pull-requests/>`_.
|
||||
|
||||
Before Contributing
|
||||
-------------------
|
||||
@@ -17,8 +17,6 @@ Before sending us a Pull Request, please consider this list of points:
|
||||
|
||||
* Does any new code conform to the esp-idf :doc:`Style Guide <style-guide>`?
|
||||
|
||||
* Have you installed the :doc:`pre-commit hook <install-pre-commit-hook>` for esp-idf project?
|
||||
|
||||
* Does the code documentation follow requirements in :doc:`documenting-code`?
|
||||
|
||||
* Is the code adequately commented for people to understand how it is structured?
|
||||
@@ -27,9 +25,7 @@ Before sending us a Pull Request, please consider this list of points:
|
||||
|
||||
* Are comments and documentation written in clear English, with no spelling or grammar errors?
|
||||
|
||||
* Example contributions are also welcome. Please check the :doc:`creating-examples` guide for these.
|
||||
|
||||
* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" `squashed into previous commits <https://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/>`_?
|
||||
* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" `squashed into previous commits <http://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/>`_?
|
||||
|
||||
* If you're unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback.
|
||||
|
||||
@@ -54,8 +50,6 @@ Related Documents
|
||||
:maxdepth: 1
|
||||
|
||||
style-guide
|
||||
install-pre-commit-hook
|
||||
documenting-code
|
||||
creating-examples
|
||||
../api-reference/template
|
||||
contributor-agreement
|
||||
contributor-agreement
|
||||
621
Kconfig
621
Kconfig
@@ -4,443 +4,184 @@
|
||||
#
|
||||
mainmenu "Espressif IoT Development Framework Configuration"
|
||||
|
||||
config IDF_CMAKE
|
||||
bool
|
||||
option env="IDF_CMAKE"
|
||||
|
||||
config IDF_ENV_FPGA
|
||||
# This option is for internal use only
|
||||
bool
|
||||
option env="IDF_ENV_FPGA"
|
||||
|
||||
config IDF_TARGET_ARCH_RISCV
|
||||
bool
|
||||
default "n"
|
||||
|
||||
config IDF_TARGET_ARCH_XTENSA
|
||||
bool
|
||||
default "n"
|
||||
|
||||
config IDF_TARGET
|
||||
# This option records the IDF target when sdkconfig is generated the first time.
|
||||
# It is not updated if environment variable $IDF_TARGET changes later, and
|
||||
# the build system is responsible for detecting the mismatch between
|
||||
# CONFIG_IDF_TARGET and $IDF_TARGET.
|
||||
string
|
||||
default "$IDF_TARGET"
|
||||
|
||||
config IDF_TARGET_ESP32
|
||||
bool
|
||||
default "y" if IDF_TARGET="esp32"
|
||||
select IDF_TARGET_ARCH_XTENSA
|
||||
|
||||
config IDF_TARGET_ESP32S2
|
||||
bool
|
||||
default "y" if IDF_TARGET="esp32s2"
|
||||
select FREERTOS_UNICORE
|
||||
select IDF_TARGET_ARCH_XTENSA
|
||||
|
||||
config IDF_TARGET_ESP32S3
|
||||
bool
|
||||
default "y" if IDF_TARGET="esp32s3"
|
||||
select IDF_TARGET_ARCH_XTENSA
|
||||
|
||||
config IDF_TARGET_ESP32C3
|
||||
bool
|
||||
default "y" if IDF_TARGET="esp32c3"
|
||||
select FREERTOS_UNICORE
|
||||
select IDF_TARGET_ARCH_RISCV
|
||||
|
||||
config IDF_TARGET_ESP32H2
|
||||
bool
|
||||
default "y" if IDF_TARGET="esp32h2"
|
||||
select FREERTOS_UNICORE
|
||||
select IDF_TARGET_ARCH_RISCV
|
||||
|
||||
config IDF_TARGET_LINUX
|
||||
bool
|
||||
default "y" if IDF_TARGET="linux"
|
||||
|
||||
config IDF_FIRMWARE_CHIP_ID
|
||||
hex
|
||||
default 0x0000 if IDF_TARGET_ESP32
|
||||
default 0x0002 if IDF_TARGET_ESP32S2
|
||||
default 0x0005 if IDF_TARGET_ESP32C3
|
||||
default 0x0009 if IDF_TARGET_ESP32S3
|
||||
default 0x000A if IDF_TARGET_ESP32H2 # ESP32H2-TODO: IDF-3475
|
||||
default 0xFFFF
|
||||
|
||||
menu "SDK tool configuration"
|
||||
config SDK_TOOLPREFIX
|
||||
string "Compiler toolchain path/prefix"
|
||||
default "xtensa-esp32-elf-" if IDF_TARGET_ESP32
|
||||
default "xtensa-esp32s2-elf-" if IDF_TARGET_ESP32S2
|
||||
default "xtensa-esp32s3-elf-" if IDF_TARGET_ESP32S3
|
||||
default "riscv32-esp-elf-" if IDF_TARGET_ESP32C3
|
||||
default "riscv32-esp-elf-" if IDF_TARGET_ESP32H2
|
||||
|
||||
help
|
||||
The prefix/path that is used to call the toolchain. The default setting assumes
|
||||
a crosstool-ng gcc setup that is in your PATH.
|
||||
|
||||
config SDK_PYTHON
|
||||
string "Python interpreter"
|
||||
depends on !IDF_CMAKE
|
||||
default "python"
|
||||
help
|
||||
The executable name/path that is used to run python.
|
||||
|
||||
(Note: This option is used with the legacy GNU Make build system only.)
|
||||
|
||||
config SDK_MAKE_WARN_UNDEFINED_VARIABLES
|
||||
bool "'make' warns on undefined variables"
|
||||
depends on !IDF_CMAKE
|
||||
default "y"
|
||||
help
|
||||
Adds --warn-undefined-variables to MAKEFLAGS. This causes make to
|
||||
print a warning any time an undefined variable is referenced.
|
||||
|
||||
This option helps find places where a variable reference is misspelled
|
||||
or otherwise missing, but it can be unwanted if you have Makefiles which
|
||||
depend on undefined variables expanding to an empty string.
|
||||
|
||||
(Note: this option is used with the legacy GNU Make build system only.)
|
||||
|
||||
config SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS
|
||||
bool "Toolchain supports time_t wide 64-bits"
|
||||
default n
|
||||
help
|
||||
Enable this option in case you have a custom toolchain which supports time_t wide 64-bits.
|
||||
This option checks time_t is 64-bits and disables ROM time functions
|
||||
to use the time functions from the toolchain instead.
|
||||
This option allows resolving the Y2K38 problem.
|
||||
See "Setup Linux Toolchain from Scratch" to build
|
||||
a custom toolchain which supports 64-bits time_t.
|
||||
|
||||
Note: ESP-IDF does not currently come with any pre-compiled toolchain
|
||||
that supports 64-bit wide time_t.
|
||||
This will change in a future major release,
|
||||
but currently 64-bit time_t requires a custom built toolchain.
|
||||
|
||||
endmenu # SDK tool configuration
|
||||
|
||||
menu "Build type"
|
||||
|
||||
choice APP_BUILD_TYPE
|
||||
prompt "Application build type"
|
||||
default APP_BUILD_TYPE_APP_2NDBOOT
|
||||
help
|
||||
Select the way the application is built.
|
||||
|
||||
By default, the application is built as a binary file in a format compatible with
|
||||
the ESP-IDF bootloader. In addition to this application, 2nd stage bootloader is
|
||||
also built. Application and bootloader binaries can be written into flash and
|
||||
loaded/executed from there.
|
||||
|
||||
Another option, useful for only very small and limited applications, is to only link
|
||||
the .elf file of the application, such that it can be loaded directly into RAM over
|
||||
JTAG. Note that since IRAM and DRAM sizes are very limited, it is not possible to
|
||||
build any complex application this way. However for kinds of testing and debugging,
|
||||
this option may provide faster iterations, since the application does not need to be
|
||||
written into flash.
|
||||
Note that at the moment, ESP-IDF does not contain all the startup code required to
|
||||
initialize the CPUs and ROM memory (data/bss). Therefore it is necessary to execute
|
||||
a bit of ROM code prior to executing the application. A gdbinit file may look as follows (for ESP32):
|
||||
|
||||
# Connect to a running instance of OpenOCD
|
||||
target remote :3333
|
||||
# Reset and halt the target
|
||||
mon reset halt
|
||||
# Run to a specific point in ROM code,
|
||||
# where most of initialization is complete.
|
||||
thb *0x40007d54
|
||||
c
|
||||
# Load the application into RAM
|
||||
load
|
||||
# Run till app_main
|
||||
tb app_main
|
||||
c
|
||||
|
||||
Execute this gdbinit file as follows:
|
||||
|
||||
xtensa-esp32-elf-gdb build/app-name.elf -x gdbinit
|
||||
|
||||
Example gdbinit files for other targets can be found in tools/test_apps/system/gdb_loadable_elf/
|
||||
|
||||
Recommended sdkconfig.defaults for building loadable ELF files is as follows.
|
||||
CONFIG_APP_BUILD_TYPE_ELF_RAM is required, other options help reduce application
|
||||
memory footprint.
|
||||
|
||||
CONFIG_APP_BUILD_TYPE_ELF_RAM=y
|
||||
CONFIG_VFS_SUPPORT_TERMIOS=
|
||||
CONFIG_NEWLIB_NANO_FORMAT=y
|
||||
CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y
|
||||
CONFIG_ESP_DEBUG_STUBS_ENABLE=
|
||||
CONFIG_ESP_ERR_TO_NAME_LOOKUP=
|
||||
|
||||
|
||||
config APP_BUILD_TYPE_APP_2NDBOOT
|
||||
bool
|
||||
prompt "Default (binary application + 2nd stage bootloader)"
|
||||
select APP_BUILD_GENERATE_BINARIES
|
||||
select APP_BUILD_BOOTLOADER
|
||||
select APP_BUILD_USE_FLASH_SECTIONS
|
||||
|
||||
config APP_BUILD_TYPE_ELF_RAM
|
||||
bool
|
||||
prompt "ELF file, loadable into RAM (EXPERIMENTAL))"
|
||||
endchoice # APP_BUILD_TYPE
|
||||
|
||||
# Hidden options, set according to the choice above
|
||||
config APP_BUILD_GENERATE_BINARIES
|
||||
bool # Whether to generate .bin files or not
|
||||
|
||||
config APP_BUILD_BOOTLOADER
|
||||
bool # Whether to build the bootloader
|
||||
|
||||
config APP_BUILD_USE_FLASH_SECTIONS
|
||||
bool # Whether to place code/data into memory-mapped flash sections
|
||||
|
||||
endmenu # Build type
|
||||
|
||||
source "$COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE"
|
||||
|
||||
menu "Compiler options"
|
||||
|
||||
choice COMPILER_OPTIMIZATION
|
||||
prompt "Optimization Level"
|
||||
default COMPILER_OPTIMIZATION_DEFAULT
|
||||
help
|
||||
This option sets compiler optimization level (gcc -O argument) for the app.
|
||||
|
||||
- The "Default" setting will add the -0g flag to CFLAGS.
|
||||
- The "Size" setting will add the -0s flag to CFLAGS.
|
||||
- The "Performance" setting will add the -O2 flag to CFLAGS.
|
||||
- The "None" setting will add the -O0 flag to CFLAGS.
|
||||
|
||||
The "Size" setting cause the compiled code to be smaller and faster, but
|
||||
may lead to difficulties of correlating code addresses to source file
|
||||
lines when debugging.
|
||||
|
||||
The "Performance" setting causes the compiled code to be larger and faster,
|
||||
but will be easier to correlated code addresses to source file lines.
|
||||
|
||||
"None" with -O0 produces compiled code without optimization.
|
||||
|
||||
Note that custom optimization levels may be unsupported.
|
||||
|
||||
Compiler optimization for the IDF bootloader is set separately,
|
||||
see the BOOTLOADER_COMPILER_OPTIMIZATION setting.
|
||||
|
||||
config COMPILER_OPTIMIZATION_DEFAULT
|
||||
bool "Debug (-Og)"
|
||||
config COMPILER_OPTIMIZATION_SIZE
|
||||
bool "Optimize for size (-Os)"
|
||||
config COMPILER_OPTIMIZATION_PERF
|
||||
bool "Optimize for performance (-O2)"
|
||||
config COMPILER_OPTIMIZATION_NONE
|
||||
bool "Debug without optimization (-O0)"
|
||||
|
||||
endchoice
|
||||
|
||||
choice COMPILER_OPTIMIZATION_ASSERTION_LEVEL
|
||||
prompt "Assertion level"
|
||||
default COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE
|
||||
help
|
||||
Assertions can be:
|
||||
|
||||
- Enabled. Failure will print verbose assertion details. This is the default.
|
||||
|
||||
- Set to "silent" to save code size (failed assertions will abort() but user
|
||||
needs to use the aborting address to find the line number with the failed assertion.)
|
||||
|
||||
- Disabled entirely (not recommended for most configurations.) -DNDEBUG is added
|
||||
to CPPFLAGS in this case.
|
||||
|
||||
config COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE
|
||||
prompt "Enabled"
|
||||
bool
|
||||
help
|
||||
Enable assertions. Assertion content and line number will be printed on failure.
|
||||
|
||||
config COMPILER_OPTIMIZATION_ASSERTIONS_SILENT
|
||||
prompt "Silent (saves code size)"
|
||||
bool
|
||||
help
|
||||
Enable silent assertions. Failed assertions will abort(), user needs to
|
||||
use the aborting address to find the line number with the failed assertion.
|
||||
|
||||
config COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE
|
||||
prompt "Disabled (sets -DNDEBUG)"
|
||||
bool
|
||||
help
|
||||
If assertions are disabled, -DNDEBUG is added to CPPFLAGS.
|
||||
|
||||
endchoice # assertions
|
||||
|
||||
config COMPILER_OPTIMIZATION_ASSERTION_LEVEL
|
||||
int
|
||||
default 0 if COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE
|
||||
default 1 if COMPILER_OPTIMIZATION_ASSERTIONS_SILENT
|
||||
default 2 if COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE
|
||||
|
||||
config COMPILER_OPTIMIZATION_CHECKS_SILENT
|
||||
bool "Disable messages in ESP_RETURN_ON_* and ESP_EXIT_ON_* macros"
|
||||
default n
|
||||
help
|
||||
If enabled, the error messages will be discarded in following check macros:
|
||||
- ESP_RETURN_ON_ERROR
|
||||
- ESP_EXIT_ON_ERROR
|
||||
- ESP_RETURN_ON_FALSE
|
||||
- ESP_EXIT_ON_FALSE
|
||||
|
||||
menuconfig COMPILER_HIDE_PATHS_MACROS
|
||||
bool "Replace ESP-IDF and project paths in binaries"
|
||||
default y
|
||||
depends on IDF_CMAKE
|
||||
help
|
||||
When expanding the __FILE__ and __BASE_FILE__ macros, replace paths inside ESP-IDF
|
||||
with paths relative to the placeholder string "IDF", and convert paths inside the
|
||||
project directory to relative paths.
|
||||
|
||||
This allows building the project with assertions or other code that embeds file paths,
|
||||
without the binary containing the exact path to the IDF or project directories.
|
||||
|
||||
This option passes -fmacro-prefix-map options to the GCC command line. To replace additional
|
||||
paths in your binaries, modify the project CMakeLists.txt file to pass custom -fmacro-prefix-map or
|
||||
-ffile-prefix-map arguments.
|
||||
|
||||
menuconfig COMPILER_CXX_EXCEPTIONS
|
||||
bool "Enable C++ exceptions"
|
||||
default n
|
||||
help
|
||||
Enabling this option compiles all IDF C++ files with exception support enabled.
|
||||
|
||||
Disabling this option disables C++ exception support in all compiled files, and any libstdc++ code
|
||||
which throws an exception will abort instead.
|
||||
|
||||
Enabling this option currently adds an additional ~500 bytes of heap overhead
|
||||
when an exception is thrown in user code for the first time.
|
||||
|
||||
config COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE
|
||||
int "Emergency Pool Size"
|
||||
default 0
|
||||
depends on COMPILER_CXX_EXCEPTIONS
|
||||
help
|
||||
Size (in bytes) of the emergency memory pool for C++ exceptions. This pool will be used to allocate
|
||||
memory for thrown exceptions when there is not enough memory on the heap.
|
||||
|
||||
config COMPILER_CXX_RTTI
|
||||
bool "Enable C++ run-time type info (RTTI)"
|
||||
default n
|
||||
help
|
||||
Enabling this option compiles all C++ files with RTTI support enabled.
|
||||
This increases binary size (typically by tens of kB) but allows using
|
||||
dynamic_cast conversion and typeid operator.
|
||||
|
||||
choice COMPILER_STACK_CHECK_MODE
|
||||
prompt "Stack smashing protection mode"
|
||||
default COMPILER_STACK_CHECK_MODE_NONE
|
||||
help
|
||||
Stack smashing protection mode. Emit extra code to check for buffer overflows, such as stack
|
||||
smashing attacks. This is done by adding a guard variable to functions with vulnerable objects.
|
||||
The guards are initialized when a function is entered and then checked when the function exits.
|
||||
If a guard check fails, program is halted. Protection has the following modes:
|
||||
|
||||
- In NORMAL mode (GCC flag: -fstack-protector) only functions that call alloca, and functions with
|
||||
buffers larger than 8 bytes are protected.
|
||||
|
||||
- STRONG mode (GCC flag: -fstack-protector-strong) is like NORMAL, but includes additional functions
|
||||
to be protected -- those that have local array definitions, or have references to local frame
|
||||
addresses.
|
||||
|
||||
- In OVERALL mode (GCC flag: -fstack-protector-all) all functions are protected.
|
||||
|
||||
Modes have the following impact on code performance and coverage:
|
||||
|
||||
- performance: NORMAL > STRONG > OVERALL
|
||||
|
||||
- coverage: NORMAL < STRONG < OVERALL
|
||||
|
||||
The performance impact includes increasing the amount of stack memory required for each task.
|
||||
|
||||
config COMPILER_STACK_CHECK_MODE_NONE
|
||||
bool "None"
|
||||
config COMPILER_STACK_CHECK_MODE_NORM
|
||||
bool "Normal"
|
||||
config COMPILER_STACK_CHECK_MODE_STRONG
|
||||
bool "Strong"
|
||||
config COMPILER_STACK_CHECK_MODE_ALL
|
||||
bool "Overall"
|
||||
endchoice
|
||||
|
||||
config COMPILER_STACK_CHECK
|
||||
bool
|
||||
default !COMPILER_STACK_CHECK_MODE_NONE
|
||||
help
|
||||
Stack smashing protection.
|
||||
|
||||
config COMPILER_WARN_WRITE_STRINGS
|
||||
bool "Enable -Wwrite-strings warning flag"
|
||||
default "n"
|
||||
help
|
||||
Adds -Wwrite-strings flag for the C/C++ compilers.
|
||||
|
||||
For C, this gives string constants the type ``const char[]`` so that
|
||||
copying the address of one into a non-const ``char *`` pointer
|
||||
produces a warning. This warning helps to find at compile time code
|
||||
that tries to write into a string constant.
|
||||
|
||||
For C++, this warns about the deprecated conversion from string
|
||||
literals to ``char *``.
|
||||
|
||||
config COMPILER_SAVE_RESTORE_LIBCALLS
|
||||
bool "Enable -msave-restore flag to reduce code size"
|
||||
depends on IDF_TARGET_ARCH_RISCV
|
||||
help
|
||||
Adds -msave-restore to C/C++ compilation flags.
|
||||
|
||||
When this flag is enabled, compiler will call library functions to
|
||||
save/restore registers in function prologues/epilogues. This results
|
||||
in lower overall code size, at the expense of slightly reduced performance.
|
||||
|
||||
This option can be enabled for RISC-V targets only.
|
||||
|
||||
config COMPILER_DISABLE_GCC8_WARNINGS
|
||||
bool "Disable new warnings introduced in GCC 6 - 8"
|
||||
default "n"
|
||||
help
|
||||
Enable this option if using GCC 6 or newer, and wanting to disable warnings which don't appear with
|
||||
GCC 5.
|
||||
|
||||
config COMPILER_DUMP_RTL_FILES
|
||||
bool "Dump RTL files during compilation"
|
||||
help
|
||||
If enabled, RTL files will be produced during compilation. These files
|
||||
can be used by other tools, for example to calculate call graphs.
|
||||
|
||||
|
||||
endmenu # Compiler Options
|
||||
|
||||
menu "Component config"
|
||||
source "$COMPONENT_KCONFIGS_SOURCE_FILE"
|
||||
endmenu
|
||||
|
||||
menu "Compatibility options"
|
||||
config LEGACY_INCLUDE_COMMON_HEADERS
|
||||
bool "Include headers across components as before IDF v4.0"
|
||||
default n
|
||||
help
|
||||
Soc, esp32, and driver components, the most common
|
||||
components. Some header of these components are included
|
||||
implicitly by headers of other components before IDF v4.0.
|
||||
It's not required for high-level components, but still
|
||||
included through long header chain everywhere.
|
||||
|
||||
This is harmful to the modularity. So it's changed in IDF
|
||||
v4.0.
|
||||
|
||||
You can still include these headers in a legacy way until it
|
||||
is totally deprecated by enable this option.
|
||||
|
||||
endmenu #Compatibility options
|
||||
config IDF_CMAKE
|
||||
bool
|
||||
option env="IDF_CMAKE"
|
||||
|
||||
config IDF_FIRMWARE_CHIP_ID
|
||||
hex
|
||||
default 0x0000
|
||||
|
||||
menu "SDK tool configuration"
|
||||
config TOOLPREFIX
|
||||
string "Compiler toolchain path/prefix"
|
||||
default "xtensa-esp32-elf-"
|
||||
help
|
||||
The prefix/path that is used to call the toolchain. The default setting assumes
|
||||
a crosstool-ng gcc setup that is in your PATH.
|
||||
|
||||
config PYTHON
|
||||
string "Python 2 interpreter"
|
||||
depends on !IDF_CMAKE
|
||||
default "python"
|
||||
help
|
||||
The executable name/path that is used to run python. On some systems Python 2.x
|
||||
may need to be invoked as python2.
|
||||
|
||||
(Note: This option is used with the GNU Make build system only, not idf.py
|
||||
or CMake-based builds.)
|
||||
|
||||
config MAKE_WARN_UNDEFINED_VARIABLES
|
||||
bool "'make' warns on undefined variables"
|
||||
default "y"
|
||||
help
|
||||
Adds --warn-undefined-variables to MAKEFLAGS. This causes make to
|
||||
print a warning any time an undefined variable is referenced.
|
||||
|
||||
This option helps find places where a variable reference is misspelled
|
||||
or otherwise missing, but it can be unwanted if you have Makefiles which
|
||||
depend on undefined variables expanding to an empty string.
|
||||
|
||||
endmenu # SDK tool configuration
|
||||
|
||||
source "$COMPONENT_KCONFIGS_PROJBUILD"
|
||||
|
||||
menu "Compiler options"
|
||||
|
||||
choice OPTIMIZATION_COMPILER
|
||||
prompt "Optimization Level"
|
||||
default OPTIMIZATION_LEVEL_DEBUG
|
||||
help
|
||||
This option sets compiler optimization level (gcc -O argument).
|
||||
|
||||
- for "Release" setting, -Os flag is added to CFLAGS.
|
||||
- for "Debug" setting, -Og flag is added to CFLAGS.
|
||||
|
||||
"Release" with -Os produces smaller & faster compiled code but it
|
||||
may be harder to correlated code addresses to source files when debugging.
|
||||
|
||||
To add custom optimization settings, set CFLAGS and/or CPPFLAGS
|
||||
in project makefile, before including $(IDF_PATH)/make/project.mk. Note that
|
||||
custom optimization levels may be unsupported.
|
||||
|
||||
config OPTIMIZATION_LEVEL_DEBUG
|
||||
bool "Debug (-Og)"
|
||||
config OPTIMIZATION_LEVEL_RELEASE
|
||||
bool "Release (-Os)"
|
||||
endchoice
|
||||
|
||||
choice OPTIMIZATION_ASSERTION_LEVEL
|
||||
prompt "Assertion level"
|
||||
default OPTIMIZATION_ASSERTIONS_ENABLED
|
||||
help
|
||||
Assertions can be:
|
||||
|
||||
- Enabled. Failure will print verbose assertion details. This is the default.
|
||||
|
||||
- Set to "silent" to save code size (failed assertions will abort() but user
|
||||
needs to use the aborting address to find the line number with the failed assertion.)
|
||||
|
||||
- Disabled entirely (not recommended for most configurations.) -DNDEBUG is added
|
||||
to CPPFLAGS in this case.
|
||||
|
||||
config OPTIMIZATION_ASSERTIONS_ENABLED
|
||||
prompt "Enabled"
|
||||
bool
|
||||
help
|
||||
Enable assertions. Assertion content and line number will be printed on failure.
|
||||
|
||||
config OPTIMIZATION_ASSERTIONS_SILENT
|
||||
prompt "Silent (saves code size)"
|
||||
bool
|
||||
help
|
||||
Enable silent assertions. Failed assertions will abort(), user needs to
|
||||
use the aborting address to find the line number with the failed assertion.
|
||||
|
||||
config OPTIMIZATION_ASSERTIONS_DISABLED
|
||||
prompt "Disabled (sets -DNDEBUG)"
|
||||
bool
|
||||
help
|
||||
If assertions are disabled, -DNDEBUG is added to CPPFLAGS.
|
||||
|
||||
endchoice # assertions
|
||||
|
||||
menuconfig CXX_EXCEPTIONS
|
||||
bool "Enable C++ exceptions"
|
||||
default n
|
||||
help
|
||||
Enabling this option compiles all IDF C++ files with exception support enabled.
|
||||
|
||||
Disabling this option disables C++ exception support in all compiled files, and any libstdc++ code which throws
|
||||
an exception will abort instead.
|
||||
|
||||
Enabling this option currently adds an additional ~500 bytes of heap overhead
|
||||
when an exception is thrown in user code for the first time.
|
||||
|
||||
config CXX_EXCEPTIONS_EMG_POOL_SIZE
|
||||
int "Emergency Pool Size"
|
||||
default 0
|
||||
depends on CXX_EXCEPTIONS
|
||||
help
|
||||
Size (in bytes) of the emergency memory pool for C++ exceptions. This pool will be used to allocate
|
||||
memory for thrown exceptions when there is not enough memory on the heap.
|
||||
|
||||
choice STACK_CHECK_MODE
|
||||
prompt "Stack smashing protection mode"
|
||||
default STACK_CHECK_NONE
|
||||
help
|
||||
Stack smashing protection mode. Emit extra code to check for buffer overflows, such as stack
|
||||
smashing attacks. This is done by adding a guard variable to functions with vulnerable objects.
|
||||
The guards are initialized when a function is entered and then checked when the function exits.
|
||||
If a guard check fails, program is halted. Protection has the following modes:
|
||||
|
||||
- In NORMAL mode (GCC flag: -fstack-protector) only functions that call alloca,
|
||||
and functions with buffers larger than 8 bytes are protected.
|
||||
|
||||
- STRONG mode (GCC flag: -fstack-protector-strong) is like NORMAL, but includes
|
||||
additional functions to be protected -- those that have local array definitions,
|
||||
or have references to local frame addresses.
|
||||
|
||||
- In OVERALL mode (GCC flag: -fstack-protector-all) all functions are protected.
|
||||
|
||||
Modes have the following impact on code performance and coverage:
|
||||
|
||||
- performance: NORMAL > STRONG > OVERALL
|
||||
|
||||
- coverage: NORMAL < STRONG < OVERALL
|
||||
|
||||
|
||||
config STACK_CHECK_NONE
|
||||
bool "None"
|
||||
config STACK_CHECK_NORM
|
||||
bool "Normal"
|
||||
config STACK_CHECK_STRONG
|
||||
bool "Strong"
|
||||
config STACK_CHECK_ALL
|
||||
bool "Overall"
|
||||
endchoice
|
||||
|
||||
config STACK_CHECK
|
||||
bool
|
||||
default !STACK_CHECK_NONE
|
||||
help
|
||||
Stack smashing protection.
|
||||
|
||||
config WARN_WRITE_STRINGS
|
||||
bool "Enable -Wwrite-strings warning flag"
|
||||
default "n"
|
||||
help
|
||||
Adds -Wwrite-strings flag for the C/C++ compilers.
|
||||
|
||||
For C, this gives string constants the type ``const char[]`` so that
|
||||
copying the address of one into a non-const ``char *`` pointer
|
||||
produces a warning. This warning helps to find at compile time code
|
||||
that tries to write into a string constant.
|
||||
|
||||
For C++, this warns about the deprecated conversion from string
|
||||
literals to ``char *``.
|
||||
|
||||
endmenu # Compiler Options
|
||||
|
||||
menu "Component config"
|
||||
source "$COMPONENT_KCONFIGS"
|
||||
endmenu
|
||||
|
||||
111
README.md
111
README.md
@@ -1,41 +1,17 @@
|
||||
# Espressif IoT Development Framework
|
||||
|
||||
* [中文版](./README_CN.md)
|
||||
[](https://docs.espressif.com/projects/esp-idf/en/latest/?badge=latest)
|
||||
|
||||
ESP-IDF is the development framework for Espressif SoCs supported on Windows, Linux and macOS.
|
||||
|
||||
# ESP-IDF Release and SoC Compatibility
|
||||
|
||||
The following table shows ESP-IDF support of Espressif SoCs where ![alt text][preview] and ![alt text][supported] denote preview status and support, respectively. In preview status the build is not yet enabled and some crucial parts could be missing (like documentation, datasheet). Please use an ESP-IDF release where the desired SoC is already supported.
|
||||
|
||||
|Chip | v3.3 | v4.0 | v4.1 | v4.2 | v4.3 | v4.4 | |
|
||||
|:----------- |:---------------------: | :---------------------:| :---------------------:| :---------------------:| :---------------------:| :---------------------:|:---------------------------------------------------------- |
|
||||
|ESP32 | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | |
|
||||
|ESP32-S2 | | | | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | |
|
||||
|ESP32-C3 | | | | | ![alt text][supported] | ![alt text][supported] | |
|
||||
|ESP32-S3 | | | | | ![alt text][preview] | ![alt text][supported] | [Announcement](https://www.espressif.com/en/news/ESP32_S3) |
|
||||
|ESP32-H2 | | | | | | ![alt text][preview] | [Announcement](https://www.espressif.com/en/news/ESP32_H2) |
|
||||
|
||||
[supported]: https://img.shields.io/badge/-supported-green "supported"
|
||||
[preview]: https://img.shields.io/badge/-preview-orange "preview"
|
||||
|
||||
Espressif SoCs released before 2016 (ESP8266 and ESP8285) are supported by [RTOS SDK](https://github.com/espressif/ESP8266_RTOS_SDK) instead.
|
||||
ESP-IDF is the official development framework for the [ESP32](https://espressif.com/en/products/hardware/esp32/overview) chip.
|
||||
|
||||
# Developing With ESP-IDF
|
||||
|
||||
## Setting Up ESP-IDF
|
||||
|
||||
See https://idf.espressif.com/ for links to detailed instructions on how to set up the ESP-IDF depending on chip you use.
|
||||
See setup guides for detailed instructions to set up the ESP-IDF:
|
||||
|
||||
**Note:** Each SoC series and each ESP-IDF release has its own documentation. Please see Section [Versions](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/versions.html) on how to find documentation and how to checkout specific release of ESP-IDF.
|
||||
|
||||
### Non-GitHub forks
|
||||
|
||||
ESP-IDF uses relative locations as its submodules URLs ([.gitmodules](.gitmodules)). So they link to GitHub.
|
||||
If ESP-IDF is forked to a Git repository which is not on GitHub, you will need to run the script
|
||||
[tools/set-submodules-to-github.sh](tools/set-submodules-to-github.sh) after git clone.
|
||||
The script sets absolute URLs for all submodules, allowing `git submodule update --init --recursive` to complete.
|
||||
If cloning ESP-IDF from GitHub, this step is not needed.
|
||||
* [Getting Started Guide for the stable ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/)
|
||||
* [Getting Started Guide for the latest (master branch) ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/)
|
||||
|
||||
## Finding a Project
|
||||
|
||||
@@ -49,63 +25,92 @@ To start your own project based on an example, copy the example project director
|
||||
|
||||
See the Getting Started guide links above for a detailed setup guide. This is a quick reference for common commands when working with ESP-IDF projects:
|
||||
|
||||
## Setup Build Environment
|
||||
|
||||
(See the Getting Started guide listed above for a full list of required steps with more details.)
|
||||
|
||||
* Install host build dependencies mentioned in the Getting Started guide.
|
||||
* Run the install script to set up the build environment. The options include `install.bat` or `install.ps1` for Windows, and `install.sh` or `install.fish` for Unix shells.
|
||||
* Run the export script on Windows (`export.bat`) or source it on Unix (`source export.sh`) in every shell environment before using ESP-IDF.
|
||||
|
||||
## Configuring the Project
|
||||
|
||||
* `idf.py set-target <chip_name>` sets the target of the project to `<chip_name>`. Run `idf.py set-target` without any arguments to see a list of supported targets.
|
||||
* `idf.py menuconfig` opens a text-based configuration menu where you can configure the project.
|
||||
`make menuconfig`
|
||||
|
||||
* Opens a text-based configuration menu for the project.
|
||||
* Use up & down arrow keys to navigate the menu.
|
||||
* Use Enter key to go into a submenu, Escape key to go out or to exit.
|
||||
* Type `?` to see a help screen. Enter key exits the help screen.
|
||||
* Use Space key, or `Y` and `N` keys to enable (Yes) and disable (No) configuration items with checkboxes "`[*]`"
|
||||
* Pressing `?` while highlighting a configuration item displays help about that item.
|
||||
* Type `/` to search the configuration items.
|
||||
|
||||
Once done configuring, press Escape multiple times to exit and say "Yes" to save the new configuration when prompted.
|
||||
|
||||
## Compiling the Project
|
||||
|
||||
`idf.py build`
|
||||
`make -j4 all`
|
||||
|
||||
... will compile app, bootloader and generate a partition table based on the config.
|
||||
|
||||
NOTE: The `-j4` option causes `make` to run 4 parallel jobs. This is much faster than the default single job. The recommended number to pass to this option is `-j(number of CPUs + 1)`.
|
||||
|
||||
## Flashing the Project
|
||||
|
||||
When the build finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this automatically by running:
|
||||
|
||||
`idf.py -p PORT flash`
|
||||
`make -j4 flash`
|
||||
|
||||
Replace PORT with the name of your serial port (like `COM3` on Windows, `/dev/ttyUSB0` on Linux, or `/dev/cu.usbserial-X` on MacOS. If the `-p` option is left out, `idf.py flash` will try to flash the first available serial port.
|
||||
This will flash the entire project (app, bootloader and partition table) to a new chip. The settings for serial port flashing can be configured with `make menuconfig`.
|
||||
|
||||
This will flash the entire project (app, bootloader and partition table) to a new chip. The settings for serial port flashing can be configured with `idf.py menuconfig`.
|
||||
|
||||
You don't need to run `idf.py build` before running `idf.py flash`, `idf.py flash` will automatically rebuild anything which needs it.
|
||||
You don't need to run `make all` before running `make flash`, `make flash` will automatically rebuild anything which needs it.
|
||||
|
||||
## Viewing Serial Output
|
||||
|
||||
The `idf.py monitor` target uses the [idf_monitor tool](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html) to display serial output from Espressif SoCs. idf_monitor also has a range of features to decode crash output and interact with the device. [Check the documentation page for details](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html).
|
||||
The `make monitor` target uses the [idf_monitor tool](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html) to display serial output from the ESP32. idf_monitor also has a range of features to decode crash output and interact with the device. [Check the documentation page for details](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html).
|
||||
|
||||
Exit the monitor by typing Ctrl-].
|
||||
|
||||
To build, flash and monitor output in one pass, you can run:
|
||||
|
||||
`idf.py flash monitor`
|
||||
`make -j4 flash monitor`
|
||||
|
||||
## Compiling & Flashing Only the App
|
||||
|
||||
After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table:
|
||||
|
||||
* `idf.py app` - build just the app.
|
||||
* `idf.py app-flash` - flash just the app.
|
||||
* `make app` - build just the app.
|
||||
* `make app-flash` - flash just the app.
|
||||
|
||||
`idf.py app-flash` will automatically rebuild the app if any source files have changed.
|
||||
`make app-flash` will automatically rebuild the app if any source files have changed.
|
||||
|
||||
(In normal development there's no downside to reflashing the bootloader and partition table each time, if they haven't changed.)
|
||||
|
||||
## Parallel Builds
|
||||
|
||||
ESP-IDF supports compiling multiple files in parallel, so all of the above commands can be run as `make -jN` where `N` is the number of parallel make processes to run (generally N should be equal to the number of CPU cores in your system, plus one.)
|
||||
|
||||
Multiple make functions can be combined into one. For example: to build the app & bootloader using 5 jobs in parallel, then flash everything, and then display serial output from the ESP32 run:
|
||||
|
||||
```
|
||||
make -j5 flash monitor
|
||||
```
|
||||
|
||||
|
||||
## The Partition Table
|
||||
|
||||
Once you've compiled your project, the "build" directory will contain a binary file with a name like "my_app.bin". This is an ESP32 image binary that can be loaded by the bootloader.
|
||||
|
||||
A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to offset 0x8000 in the flash.
|
||||
|
||||
Each entry in the partition table has a name (label), type (app, data, or something else), subtype and the offset in flash where the partition is loaded.
|
||||
|
||||
The simplest way to use the partition table is to `make menuconfig` and choose one of the simple predefined partition tables:
|
||||
|
||||
* "Single factory app, no OTA"
|
||||
* "Factory app, two OTA definitions"
|
||||
|
||||
In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table.
|
||||
|
||||
For more details about partition tables and how to create custom variations, view the [`docs/en/api-guides/partition-tables.rst`](docs/en/api-guides/partition-tables.rst) file.
|
||||
|
||||
## Erasing Flash
|
||||
|
||||
The `idf.py flash` target does not erase the entire flash contents. However it is sometimes useful to set the device back to a totally erased state, particularly when making partition table changes or OTA app updates. To erase the entire flash, run `idf.py erase-flash`.
|
||||
The `make flash` target does not erase the entire flash contents. However it is sometimes useful to set the device back to a totally erased state, particularly when making partition table changes or OTA app updates. To erase the entire flash, run `make erase_flash`.
|
||||
|
||||
This can be combined with other targets, ie `idf.py -p PORT erase-flash flash` will erase everything and then re-flash the new app, bootloader and partition table.
|
||||
This can be combined with other targets, ie `make erase_flash flash` will erase everything and then re-flash the new app, bootloader and partition table.
|
||||
|
||||
# Resources
|
||||
|
||||
@@ -116,3 +121,5 @@ This can be combined with other targets, ie `idf.py -p PORT erase-flash flash` w
|
||||
* [Check the Issues section on github](https://github.com/espressif/esp-idf/issues) if you find a bug or have a feature request. Please check existing Issues before opening a new one.
|
||||
|
||||
* If you're interested in contributing to ESP-IDF, please check the [Contributions Guide](https://docs.espressif.com/projects/esp-idf/en/latest/contribute/index.html).
|
||||
|
||||
|
||||
|
||||
118
README_CN.md
118
README_CN.md
@@ -1,118 +0,0 @@
|
||||
# Espressif 物联网开发框架
|
||||
|
||||
* [English Version](./README.md)
|
||||
|
||||
ESP-IDF 是乐鑫官方推出的物联网开发框架,支持 Windows、Linux 和 macOS 操作系统。
|
||||
|
||||
# ESP-IDF 与乐鑫芯片
|
||||
|
||||
下表总结了乐鑫芯片在 ESP-IDF 各版本中的支持状态,其中 ![alt text][supported] 代表已支持,![alt text][preview] 代表目前处于预览支持状态。在预览支持阶段,因为新芯片尚未完全添加到构建系统目录,所以一些重要的内容(如文档和技术规格书等)可能会缺失。请确保使用与芯片相匹配的 ESP-IDF 版本。
|
||||
|
||||
| 芯片 | v3.3 | v4.0 | v4.1 | v4.2 | v4.3 | v4.4 | |
|
||||
|:----------- |:---------------------: | :---------------------:| :---------------------:| :---------------------:| :---------------------:| :---------------------:|:---------------------------------------------------------- |
|
||||
|ESP32 | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | |
|
||||
|ESP32-S2 | | | | ![alt text][supported] | ![alt text][supported] | ![alt text][supported] | |
|
||||
|ESP32-C3 | | | | | ![alt text][supported] | ![alt text][supported] | |
|
||||
|ESP32-S3 | | | | | ![alt text][preview] | ![alt text][supported] | [芯片发布公告](https://www.espressif.com/en/news/ESP32_S3) |
|
||||
|ESP32-H2 | | | | | | ![alt text][preview] | [芯片发布公告](https://www.espressif.com/en/news/ESP32_H2) |
|
||||
|
||||
[supported]: https://img.shields.io/badge/-%E6%94%AF%E6%8C%81-green "supported"
|
||||
[preview]: https://img.shields.io/badge/-%E9%A2%84%E8%A7%88-orange "preview"
|
||||
|
||||
对于 2016 年之前发布的乐鑫芯片(包括 ESP8266 和 ESP8285),请参考 [RTOS SDK](https://github.com/espressif/ESP8266_RTOS_SDK)。
|
||||
|
||||
# 使用 ESP-IDF 进行开发
|
||||
|
||||
## 搭建 ESP-IDF 开发环境
|
||||
|
||||
关于不同芯片如何搭建 ESP-IDF 的开发环境,请参考 https://idf.espressif.com/ 。
|
||||
|
||||
**注意:** 不同系列芯片和不同 ESP-IDF 版本都有其对应的文档。请参阅[版本](https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/versions.html)部分,获得关于如何查找文档以及如何检出 ESP-IDF 的特定发行版的详细信息。
|
||||
|
||||
### 非 GitHub 分叉的 ESP-IDF 项目
|
||||
|
||||
ESP-IDF 中的子模块采用相对路径([详见 .gitmodules 文件](.gitmodules)),所以它们会指向 GitHub。
|
||||
如果 ESP-IDF 被分叉到的仓库不在 GitHub 上,那么你需要在克隆结束后运行该脚本 [tools/set-submodules-to-github.sh](tools/set-submodules-to-github.sh)。
|
||||
|
||||
这个脚本会为所有的子模块设置绝对路径,接着可以通过 `git submodule update --init --recursive` 完成子模块的更新。
|
||||
如果 ESP-IDF 是从 GitHub 上克隆得到,则不需要此步骤。
|
||||
|
||||
## 寻找项目
|
||||
|
||||
除了入门指南中提到的 [esp-idf 模板项目](https://github.com/espressif/esp-idf-template),ESP-IDF 的 [examples](examples) 目录下还带有很多其它示例项目。
|
||||
|
||||
一旦找到了需要的项目,便可以进入该目录,执行配置和构建操作。
|
||||
|
||||
如果要基于示例工程开始你自己的项目,请将示例工程复制到 ESP-IDF 目录之外。
|
||||
|
||||
# 快速参考
|
||||
|
||||
详细的使用方法请参考上面入门指南的链接,这里仅仅列举一些 ESP-IDF 项目开发中常用的命令:
|
||||
|
||||
## 设置构建环境
|
||||
|
||||
请参考入门指南中列出的详细步骤。
|
||||
|
||||
* 在主机中安装入门指南中提到的构建所依赖的工具。
|
||||
* 运行安装脚本来设置构建环境。可为 Windows shell 选择 `install.bat` 或 `install.ps1`,为 Unix shell 选择 `install.sh` 和 `install.fish`。
|
||||
* 在使用 ESP-IDF 之前,需要在 shell 中运行导出脚本。Windows 下可运行 `export.bat`,Unix 下可运行 `source export.sh`。
|
||||
|
||||
## 配置项目
|
||||
|
||||
* `idf.py set-target <chip_name>` 可将项目的目标芯片设置为 `<chip_name>`。运行 `idf.py set-target`,不用带任何参数,可查看所有支持的目标芯片列表。
|
||||
* `idf.py menuconfig` 可打开一个基于文本的配置菜单,可以用来对项目进行配置。
|
||||
|
||||
## 编译项目
|
||||
|
||||
`idf.py build`
|
||||
|
||||
编译应用程序,引导程序,并根据配置生成分区表。
|
||||
|
||||
## 烧写项目
|
||||
|
||||
当构建结束,终端会打印出一条命令行,告知如何使用 esptool.py 工具烧写项目到芯片中。但你也可以运行下面这条命令来自动烧写:
|
||||
|
||||
`idf.py -p PORT flash`
|
||||
|
||||
将其中的 PORT 替换为系统中实际串口的名字(比如 Windows 下的 `COM3`,Linux 下的 `/dev/ttyUSB0`,或者 macOS 下的 `/dev/cu.usbserial-X`。如果省略 `-p` 选项,`idf.py flash` 会尝试使用第一个可用的串口进行烧写。
|
||||
|
||||
这会烧写整个项目(包括应用程序,引导程序和分区表)到芯片中,此外还可以使用 `idf.py menuconfig` 来调整串口烧写相关的配置。
|
||||
|
||||
不必先运行 `idf.py build` 再运行 `idf.py flash`,`idf.py flash` 会根据需要自动重新构建项目。
|
||||
|
||||
## 观察串口输入
|
||||
|
||||
`idf.py monitor` 会调用 [idf_monitor 工具](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html)来显示乐鑫芯片的串口输出。`idf_monitor` 还包含一系列的功能来解析程序崩溃后的输出结果并与设备进行交互。更多详细内容,请参阅[文档](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html).
|
||||
|
||||
输入 `Ctrl-]` 可退出监视器。
|
||||
|
||||
想要一次性执行构建、烧写和监视,可以运行如下命令:
|
||||
|
||||
`idf.py flash monitor`
|
||||
|
||||
## 仅编译并烧写应用程序
|
||||
|
||||
在第一次烧写过后,你可能只想构建并烧写你的应用程序,不包括引导程序和分区表:
|
||||
|
||||
* `idf.py app` - 仅构建应用程序。
|
||||
* `idf.py app-flash` - 仅烧写应用程序。
|
||||
|
||||
`idf.py app-flash` 会自动判断是否有源文件发生了改变然后重新构建应用程序。
|
||||
|
||||
(在正常的开发中,即使引导程序和分区表没有发生变化,每次都重新烧写它们并不会带来什么危害。)
|
||||
|
||||
## 擦除 Flash
|
||||
|
||||
`idf.py flash` 并不会擦除 flash 上所有的内容,但是有时候我们需要设备恢复到完全擦除的状态,尤其是分区表发生了变化或者 OTA 应用升级时。要擦除整块 flash 请运行 `idf.py erase-flash`。
|
||||
|
||||
这条命令还可以和其余命令整合在一起,`idf.py -p PORT erase-flash flash` 会擦除一切然后重新烧写新的应用程序、引导程序和分区表。
|
||||
|
||||
# 其它参考资源
|
||||
|
||||
* 最新版的文档:https://docs.espressif.com/projects/esp-idf/ ,该文档是由本仓库 [docs 目录](docs) 构建得到。
|
||||
|
||||
* 可以前往 [esp32.com 论坛](https://esp32.com/) 提问,挖掘社区资源。
|
||||
|
||||
* 如果你在使用中发现了错误或者需要新的功能,请先[查看 GitHub Issues](https://github.com/espressif/esp-idf/issues),确保该问题没有重复提交。
|
||||
|
||||
* 如果你有兴趣为 ESP-IDF 作贡献,请先阅读[贡献指南](https://docs.espressif.com/projects/esp-idf/en/latest/contribute/index.html)。
|
||||
@@ -1,86 +0,0 @@
|
||||
The latest support policy for ESP-IDF can be found at [https://github.com/espressif/esp-idf/blob/master/SUPPORT_POLICY.md](https://github.com/espressif/esp-idf/blob/master/SUPPORT_POLICY.md)
|
||||
|
||||
Support Period Policy
|
||||
=====================
|
||||
|
||||
* [中文版](./SUPPORT_POLICY_CN.md)
|
||||
|
||||
Each ESP-IDF major and minor release (V4.1, V4.2, etc) is supported for
|
||||
30 months after the initial stable release date.
|
||||
|
||||
Supported means that the ESP-IDF team will continue to apply bug fixes,
|
||||
security fixes, etc to the release branch on GitHub, and periodically
|
||||
make new bugfix releases as needed.
|
||||
|
||||
Support period is divided into "Service" and "Maintenance" period:
|
||||
|
||||
| Period | Duration | Recommended for new projects? |
|
||||
| ------- | ------------ | ------------------------------------- |
|
||||
| Service | 12 months | Yes |
|
||||
| Maintenance | 18 months | No |
|
||||
|
||||
During the Service period, bugfixes releases are more frequent. In some cases,
|
||||
support for new features may be added during the Service period (this is
|
||||
reserved for features which are needed to meet particular regulatory
|
||||
requirements or standards for new products, and which carry a very low risk of
|
||||
introducing regressions.)
|
||||
|
||||
During the Maintenance period, the version is still supported but only bugfixes
|
||||
for high severity issues or security issues will be applied.
|
||||
|
||||
Using an “In Service” version is recommended when starting a new project.
|
||||
|
||||
Users are encouraged to upgrade all projects to a newer ESP-IDF release before
|
||||
the support period finishes and the release becomes End of Life (EOL). It is our
|
||||
policy to not continue fixing bugs in End of Life releases.
|
||||
|
||||
Pre-release versions (betas, previews, `-rc` and `-dev` versions, etc)
|
||||
are not covered by any support period. Sometimes a particular feature is
|
||||
marked as "Preview" in a release, which means it is also not covered
|
||||
by the support period.
|
||||
|
||||
ESP-IDF should be used in an up-to-date software environment. The operating system
|
||||
and other third-party tools should be supported by their maintainers.
|
||||
ESP-IDF cannot keep compatibility with unsupported third-party tools.
|
||||
|
||||
The ESP-IDF Programming Guide has information about the
|
||||
[different versions of ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/versions.html)
|
||||
(major, minor, bugfix, etc).
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
ESP-IDF V3.3 was released in September 2019. It will be supported for 30 months
|
||||
until February 2022.
|
||||
|
||||
- The first V3.3 release was `v3.3` in September 2019.
|
||||
- The ESP-IDF team continues to backport bug fixes, security fixes,
|
||||
etc to the release branch `release/v3.3`.
|
||||
- Periodically stable bugfix releases are created from the release
|
||||
branch. For example `v3.3.1`, `v3.3.2`, etc. Users are encouraged to
|
||||
always update to the latest bugfix release.
|
||||
- V3.3 bugfix releases continue until February 2022, when all V3.3.x
|
||||
releases become End of Life.
|
||||
|
||||
Existing Releases
|
||||
-----------------
|
||||
|
||||
ESP-IDF release V4.1 and all newer releases will follow this support period
|
||||
policy. The support period for each release will be announced when the release
|
||||
is made.
|
||||
|
||||
For releases made before the current support period policy was announced, the
|
||||
original support periods apply:
|
||||
|
||||
* ESP-IDF V4.0.x will be supported until October 2021
|
||||
* ESP-IDF V3.3.x will be supported until February 2022
|
||||
* ESP-IDF versions before V3.3 are already End of Life.
|
||||
|
||||
Policy History
|
||||
--------------
|
||||
|
||||
* September 2019. This policy split ESP-IDF releases into Standard and Long Term
|
||||
Support.
|
||||
* July 2020. All releases from now will have the same support period, which is
|
||||
equal to the previous Long Term Support period. Added “In Service” period,
|
||||
during which versions will receive more updates.
|
||||
@@ -1,55 +0,0 @@
|
||||
有关 ESP-IDF 的最新支持政策,详见 [支持期限政策](https://github.com/espressif/esp-idf/blob/master/SUPPORT_POLICY_CN.md)
|
||||
|
||||
支持期限政策
|
||||
=====================
|
||||
|
||||
ESP-IDF 的每个主要版本和次要版本(如 V4.1、V4.2 等)自其首次稳定版本发布之日起将支持 30 个月。
|
||||
|
||||
支持意味着 ESP-IDF 团队将会对 GitHub 上的发布分支继续进行 bug 修复、安全修补等,并根据需求定期发布新的 bugfix 版本。
|
||||
|
||||
支持周期包括“服务周期“和“维护周期”:
|
||||
|
||||
| 周期 | 期限 | 是否建议新项目使用? |
|
||||
| ------- | ------------ | ------------------------------------- |
|
||||
| 服务周期 | 12 个月 | 是 |
|
||||
| 维护周期 | 18 个月 | 否 |
|
||||
|
||||
在版本的服务周期内,bug 修复版本会较为频繁发布。某些情况下,版本在其服务周期内可能会增加对新功能的支持(这仅适用于需要达到新产品特定规管标准或要求的功能,并且引入新问题的风险极低。)
|
||||
|
||||
在版本的维护周期内,版本仍然会继续支持,但仅会对严重问题或安全问题进行 bug 修复。
|
||||
|
||||
建议在开始新项目的时候使用处于服务周期的版本。
|
||||
|
||||
在某一版本支持期限结束,停止更新维护 (EOL) 前,建议用户升级所有项目至较新的 ESP-IDF 版本。根据《支持期限政策》,我们将停止对 EOL 版本进行 bug 修复。
|
||||
|
||||
《支持期限政策》不适用于预发布版本(包括 beta、preview、-rc 和 -dev 版本等)。有时,在发布的版本中存在被标记为 "Preview" 的特定功能,则该功能也不在支持期限内。
|
||||
|
||||
有关 [ESP-IDF 不同版本](https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/versions.html)(主要版本、次要版本、bugfix 版本等)信息,可参阅《ESP-IDF 编程指南》。
|
||||
|
||||
示例
|
||||
-------
|
||||
|
||||
ESP-IDF V3.3 于 2019 年 9 月发布,将支持 30 个月至 2022 年 2 月停止。
|
||||
|
||||
- V3.3 的首个发布版本为 2019 年 9 月发布的 v3.3。
|
||||
- ESP-IDF 团队将持续进行 bug 修复、安全修补等更新,并 backport 至分支 release/v3.3。
|
||||
- 定期从 release 分支创建稳定的 bugfix 版本,比如,v3.3.1、v3.3.2 等,并建议用户保持使用最新的 bugfix 版本。
|
||||
- V3.3 的 bugfix 版本发布将持续至 2022 年 2 月,届时所有 V3.3.x 将停止更新维护。
|
||||
|
||||
现有版本
|
||||
-----------------
|
||||
|
||||
ESP-IDF V4.1 及所有后续更新版本都将遵守该《支持期限政策》。每一版本发布时将同时公布其支持期限。
|
||||
|
||||
对于该政策公布之日前发布的版本,应适用下述支持期限:
|
||||
|
||||
* ESP-IDF V4.0.x 将支持至 2021 年 10 月。
|
||||
* ESP-IDF V3.3.x 将支持至 2022 年 2 月。
|
||||
* ESP-IDF V3.1.x 和 V3.2.x 都将在 2020 年 10 月停止支持。
|
||||
* ESP-IDF v3.1.x 之前的版本已经停止支持。
|
||||
|
||||
政策历史
|
||||
--------------
|
||||
|
||||
* 2019 年 9 月。该政策将 ESP-IDF 版本发布分为标准支持版本和长期支持版本。
|
||||
* 2020 年 7 月。从现在开始,所有发布的版本都将有相同的支持周期,等同于之前的长期支持周期。新增了”服务周期“,期间版本的更新将较为频繁。
|
||||
@@ -9,10 +9,9 @@
|
||||
if [ -z ${IDF_PATH} ]; then
|
||||
echo "IDF_PATH must be set before including this script."
|
||||
else
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_PATH}/components/esptool_py/esptool"
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/components/espcoredump"
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/components/partition_table/"
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/tools/"
|
||||
export PATH="${IDF_ADD_PATHS_EXTRAS}:${PATH}"
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_PATH}/components/esptool_py/esptool:${IDF_PATH}/components/espcoredump:${IDF_PATH}/components/partition_table/"
|
||||
export PATH="${PATH}:${IDF_ADD_PATHS_EXTRAS}"
|
||||
echo "Added to PATH: ${IDF_ADD_PATHS_EXTRAS}"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
# Core Components
|
||||
|
||||
## Overview
|
||||
|
||||
This document contains details about what the core components are, what they contain, and how they are organized.
|
||||
|
||||
## Organization
|
||||
|
||||
The core components are organized into two groups.
|
||||
|
||||
The first group (referred to as `G0` from now on) contains `hal`, `xtensa` and `riscv` (referred to as `arch` components from now on), `esp_rom`, `esp_common`, and `soc`. This
|
||||
group contain information about and low-level access to underlying hardware; or in the case of `esp_common`, hardware-agnostic code and utilities.
|
||||
These components can depend on each other, but as much as possible have no dependencies outside the group. The reason for this is that, due to the
|
||||
nature of what these components contain, the likelihood is high that a lot of other components will require these. Ideally, then, the dependency
|
||||
relationship only goes one way. This makes it easier for these components, as a group, to be usable in another project. One can conceivably implement
|
||||
a competing SDK to ESP-IDF on top of these components.
|
||||
|
||||
The second group (referred to as `G1` from now on) sits at a higher level than the first group. This group contains the components `esp_hw_support`, `esp_system`, `newlib`, `spi_flash`,
|
||||
`freertos`, `log`, and `heap`. Like the first group, circular dependencies within the group are allowed; and being at a higher level, dependency on the first group
|
||||
is allowed. These components represent software mechanisms essential to building other components.
|
||||
|
||||
## Descriptions
|
||||
|
||||
The following is a short description of the components mentioned above.
|
||||
|
||||
### `G0` Components
|
||||
|
||||
#### `hal`
|
||||
|
||||
Contains the hardware abstraction layer and low-level operation implementations for the various peripherals. The low-level functions assign meaningful names to register-level manipulations; the hardware abstraction provide operations one level above this, grouping these low-level functions
|
||||
into routines that achieve a meaningful action or state of the peripheral.
|
||||
|
||||
Example:
|
||||
|
||||
- `spi_flash_ll_set_address` is a low-level function part of the hardware abstraction `spi_flash_hal_read_block`
|
||||
|
||||
#### `arch`
|
||||
|
||||
Contains low-level architecture operations and definitions, including those for customizations (can be thought of on the same level as the low-level functions of `hal`).
|
||||
This can also contain files provided by the architecture vendor.
|
||||
|
||||
Example:
|
||||
|
||||
- `xt_set_exception_handler`
|
||||
- `riscv_global_interrupts_enable`
|
||||
- `ERI_PERFMON_MAX`
|
||||
|
||||
#### `esp_common`
|
||||
|
||||
Contains hardware-agnostic definitions, constants, macros, utilities, 'pure' and/or algorithmic functions that is useable by all other components (that is, barring there being a more appropriate component to put them in).
|
||||
|
||||
Example:
|
||||
|
||||
- `BIT(nr)` and other bit manipulation utilities in the future
|
||||
- `IDF_DEPRECATED(REASON)`
|
||||
- `ESP_IDF_VERSION_MAJOR`
|
||||
|
||||
#### `soc`
|
||||
|
||||
Contains description of the underlying hardware: register structure, addresses, pins, capabilities, etc.
|
||||
|
||||
Example:
|
||||
|
||||
- `DR_REG_DPORT_BASE`
|
||||
- `SOC_MCPWM_SUPPORTED`
|
||||
- `uart_dev_s`
|
||||
|
||||
#### `esp_rom`
|
||||
|
||||
Contains headers, linker scripts, abstraction layer, patches, and other related files to ROM functions.
|
||||
|
||||
Example:
|
||||
|
||||
- `esp32.rom.eco3.ld`
|
||||
- `rom/aes.h`
|
||||
|
||||
### `G1` Components
|
||||
|
||||
#### `spi_flash`
|
||||
|
||||
SPI flash device access implementation.
|
||||
|
||||
#### `freertos`
|
||||
|
||||
FreeRTOS port to targets supported by ESP-IDF.
|
||||
|
||||
#### `log`
|
||||
|
||||
Logging library.
|
||||
|
||||
#### `heap`
|
||||
|
||||
Heap implementation.
|
||||
|
||||
#### `newlib`
|
||||
|
||||
Some functions n the standard library are implemented here, especially those needing other `G1` components.
|
||||
|
||||
Example:
|
||||
|
||||
- `malloc` is implemented in terms of the component `heap`'s functions
|
||||
- `gettimeofday` is implemented in terms of system time in `esp_system`
|
||||
|
||||
#### `esp_system`
|
||||
|
||||
Contains implementation of system services and controls system behavior. The implementations
|
||||
here may take hardware resources and/or decide on a hardware state needed for support of a system service/feature/mechanism.
|
||||
Currently, this encompasses the following, but not limited to:
|
||||
|
||||
- Startup and initialization
|
||||
- Panic and debug
|
||||
- Reset and reset reason
|
||||
- Task and interrupt watchdogs
|
||||
|
||||
#### `esp_hw_support`
|
||||
|
||||
Contains implementations that provide hardware operations, arbitration, or resource sharing, especially those that
|
||||
is used in the system. Unlike `esp_system`, implementations here do not decide on a hardware state or takes hardware resource, acting
|
||||
merely as facilitator to hardware access. Currently, this encompasses the following, but not limited to:
|
||||
|
||||
- Interrupt allocation
|
||||
- Sleep functions
|
||||
- Memory functions (external SPIRAM, async memory, etc.)
|
||||
- Clock and clock control
|
||||
- Random generation
|
||||
- CPU utilities
|
||||
- MAC settings
|
||||
|
||||
### `esp_hw_support` vs `esp_system`
|
||||
|
||||
This section details list some implementations and the reason for placing it in either `esp_hw_support` or `esp_system`.
|
||||
|
||||
#### `task_wdt.c` (`esp_system`) vs `intr_alloc.c` (`esp_hw_support`)
|
||||
|
||||
The task watchdog fits the definition of taking and configuring hardware resources (wdt, interrupt) for implementation of a system service/mechanism.
|
||||
|
||||
This is in contrast with interrupt allocation that merely facilitates access to the underlying hardware for other implementations -
|
||||
drivers, user code, and even the task watchdog mentioned previously!
|
||||
|
||||
#### `crosscore_int.c` (`esp_system`)
|
||||
|
||||
The current implementation of crosscore interrupts is tightly coupled with a number of interrupt reasons
|
||||
associated with system services/mechanisms: REASON_YIELD (scheduler), REASON_FREQ_SWITCH (power management)
|
||||
REASON_PRINT_BACKTRACE (panic and debug).
|
||||
|
||||
However, if an implementation exists that makes it possible to register an arbitrary interrupt reason - a
|
||||
lower level inter-processor call if you will, then this implementation is a good candidate for `esp_hw_support`.
|
||||
The current implementation in `esp_system` can then just register the interrupt reasons mentioned above.
|
||||
|
||||
#### `esp_mac.h`, `esp_chip_info.h`, `esp_random.h` (`esp_hw_support`)
|
||||
|
||||
The functions in these headers used to be in `esp_system.h`, but have been split-off.
|
||||
However, to maintain backward compatibility, `esp_system.h` includes these headers.
|
||||
|
||||
The remaining functions in `esp_system.h` are those that deal with system behavior, such
|
||||
as `esp_register_shutdown_handler`, or are proxy for other system components's APIs such as
|
||||
`esp_get_free_heap_size`.
|
||||
|
||||
The functions split-off from `esp_system.h` are much more hardware manipulation oriented such as:
|
||||
`esp_read_mac`, `esp_random` and `esp_chip_info`.
|
||||
@@ -1,59 +1,28 @@
|
||||
set(srcs
|
||||
"app_trace.c"
|
||||
"app_trace_util.c"
|
||||
"host_file_io.c"
|
||||
"gcov/gcov_rtio.c")
|
||||
set(COMPONENT_SRCS "app_trace.c"
|
||||
"app_trace_util.c"
|
||||
"host_file_io.c"
|
||||
"gcov/gcov_rtio.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||
|
||||
set(include_dirs "include")
|
||||
|
||||
set(priv_include_dirs "private_include" "port/include")
|
||||
|
||||
if(CONFIG_APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE)
|
||||
list(APPEND srcs
|
||||
"app_trace_membufs_proto.c")
|
||||
|
||||
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
|
||||
list(APPEND srcs
|
||||
"port/xtensa/port.c")
|
||||
endif()
|
||||
if(CONFIG_IDF_TARGET_ARCH_RISCV)
|
||||
list(APPEND srcs
|
||||
"port/riscv/port.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_APPTRACE_SV_ENABLE)
|
||||
list(APPEND include_dirs
|
||||
if(CONFIG_SYSVIEW_ENABLE)
|
||||
list(APPEND COMPONENT_ADD_INCLUDEDIRS
|
||||
sys_view/Config
|
||||
sys_view/SEGGER
|
||||
sys_view/Sample/OS)
|
||||
|
||||
list(APPEND srcs
|
||||
"sys_view/SEGGER/SEGGER_SYSVIEW.c"
|
||||
"sys_view/Sample/Config/SEGGER_SYSVIEW_Config_FreeRTOS.c"
|
||||
"sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.c"
|
||||
"sys_view/esp/SEGGER_RTT_esp.c"
|
||||
"sys_view/ext/heap_trace_module.c"
|
||||
"sys_view/ext/logging.c")
|
||||
list(APPEND COMPONENT_SRCS "sys_view/SEGGER/SEGGER_SYSVIEW.c"
|
||||
"sys_view/Sample/Config/SEGGER_SYSVIEW_Config_FreeRTOS.c"
|
||||
"sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.c"
|
||||
"sys_view/esp32/SEGGER_RTT_esp32.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_HEAP_TRACING_TOHOST)
|
||||
list(APPEND srcs "heap_trace_tohost.c")
|
||||
set_source_files_properties(heap_trace_tohost.c
|
||||
PROPERTIES COMPILE_FLAGS
|
||||
-Wno-frame-address)
|
||||
endif()
|
||||
set(COMPONENT_REQUIRES)
|
||||
set(COMPONENT_PRIV_REQUIRES xtensa-debug-module)
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS "${include_dirs}"
|
||||
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
|
||||
PRIV_REQUIRES soc esp_ipc
|
||||
LDFRAGMENTS linker.lf)
|
||||
register_component()
|
||||
|
||||
# disable --coverage for this component, as it is used as transport
|
||||
# for gcov
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-profile-arcs" "-fno-test-coverage")
|
||||
component_compile_options("-fno-profile-arcs" "-fno-test-coverage")
|
||||
|
||||
# Force app_trace to also appear later than gcov in link line
|
||||
idf_component_get_property(app_trace app_trace COMPONENT_LIB)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE $<TARGET_FILE:${app_trace}> gcov $<TARGET_FILE:${app_trace}> c)
|
||||
target_link_libraries(app_trace gcov)
|
||||
|
||||
@@ -1,243 +1,202 @@
|
||||
menu "Application Level Tracing"
|
||||
|
||||
choice APPTRACE_DESTINATION
|
||||
prompt "Data Destination"
|
||||
default APPTRACE_DEST_NONE
|
||||
help
|
||||
Select destination for application trace: JTAG or none (to disable).
|
||||
choice ESP32_APPTRACE_DESTINATION
|
||||
prompt "Data Destination"
|
||||
default ESP32_APPTRACE_DEST_NONE
|
||||
help
|
||||
Select destination for application trace: trace memory or none (to disable).
|
||||
|
||||
config APPTRACE_DEST_JTAG
|
||||
bool "JTAG"
|
||||
select APPTRACE_DEST_TRAX if IDF_TARGET_ARCH_XTENSA
|
||||
select APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE
|
||||
select APPTRACE_ENABLE
|
||||
config ESP32_APPTRACE_DEST_TRAX
|
||||
bool "Trace memory"
|
||||
select ESP32_APPTRACE_ENABLE
|
||||
config ESP32_APPTRACE_DEST_NONE
|
||||
bool "None"
|
||||
endchoice
|
||||
|
||||
config APPTRACE_DEST_NONE
|
||||
bool "None"
|
||||
endchoice
|
||||
config ESP32_APPTRACE_ENABLE
|
||||
bool
|
||||
depends on !ESP32_TRAX
|
||||
select MEMMAP_TRACEMEM
|
||||
select MEMMAP_TRACEMEM_TWOBANKS
|
||||
default n
|
||||
help
|
||||
Enables/disable application tracing module.
|
||||
|
||||
config APPTRACE_DEST_TRAX
|
||||
bool
|
||||
depends on IDF_TARGET_ARCH_XTENSA && !ESP32_TRAX && !ESP32S2_TRAX
|
||||
select ESP32_MEMMAP_TRACEMEM
|
||||
select ESP32S2_MEMMAP_TRACEMEM
|
||||
select ESP32_MEMMAP_TRACEMEM_TWOBANKS
|
||||
select ESP32S2_MEMMAP_TRACEMEM_TWOBANKS
|
||||
default n
|
||||
help
|
||||
Enables/disable TRAX tracing HW.
|
||||
config ESP32_APPTRACE_LOCK_ENABLE
|
||||
bool
|
||||
default !SYSVIEW_ENABLE
|
||||
help
|
||||
Enables/disable application tracing module internal sync lock.
|
||||
|
||||
config APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE
|
||||
bool
|
||||
default n
|
||||
help
|
||||
Enables/disable swapping memory buffers tracing protocol.
|
||||
config ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO
|
||||
int "Timeout for flushing last trace data to host on panic"
|
||||
depends on ESP32_APPTRACE_ENABLE
|
||||
range -1 5000
|
||||
default -1
|
||||
help
|
||||
Timeout for flushing last trace data to host in case of panic. In ms.
|
||||
Use -1 to disable timeout and wait forever.
|
||||
|
||||
config APPTRACE_ENABLE
|
||||
bool
|
||||
default n
|
||||
help
|
||||
Enables/disable application tracing module.
|
||||
config ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH
|
||||
int "Threshold for flushing last trace data to host on panic"
|
||||
depends on ESP32_APPTRACE_DEST_TRAX
|
||||
range 0 16384
|
||||
default 0
|
||||
help
|
||||
Threshold for flushing last trace data to host on panic in post-mortem mode.
|
||||
This is minimal amount of data needed to perform flush. In bytes.
|
||||
|
||||
config APPTRACE_LOCK_ENABLE
|
||||
bool
|
||||
default !APPTRACE_SV_ENABLE
|
||||
help
|
||||
Enables/disable application tracing module internal sync lock.
|
||||
config ESP32_APPTRACE_PENDING_DATA_SIZE_MAX
|
||||
int "Size of the pending data buffer"
|
||||
depends on ESP32_APPTRACE_DEST_TRAX
|
||||
default 0
|
||||
help
|
||||
Size of the buffer for events in bytes. It is useful for buffering events from
|
||||
the time critical code (scheduler, ISRs etc). If this parameter is 0 then
|
||||
events will be discarded when main HW buffer is full.
|
||||
|
||||
config APPTRACE_ONPANIC_HOST_FLUSH_TMO
|
||||
int "Timeout for flushing last trace data to host on panic"
|
||||
depends on APPTRACE_ENABLE
|
||||
range -1 5000
|
||||
default -1
|
||||
help
|
||||
Timeout for flushing last trace data to host in case of panic. In ms.
|
||||
Use -1 to disable timeout and wait forever.
|
||||
menu "FreeRTOS SystemView Tracing"
|
||||
depends on ESP32_APPTRACE_ENABLE
|
||||
config SYSVIEW_ENABLE
|
||||
bool "SystemView Tracing Enable"
|
||||
depends on ESP32_APPTRACE_ENABLE
|
||||
default n
|
||||
help
|
||||
Enables supporrt for SEGGER SystemView tracing functionality.
|
||||
|
||||
config APPTRACE_POSTMORTEM_FLUSH_THRESH
|
||||
int "Threshold for flushing last trace data to host on panic"
|
||||
depends on APPTRACE_ENABLE
|
||||
range 0 16384
|
||||
default 0
|
||||
help
|
||||
Threshold for flushing last trace data to host on panic in post-mortem mode.
|
||||
This is minimal amount of data needed to perform flush. In bytes.
|
||||
choice SYSVIEW_TS_SOURCE
|
||||
prompt "Timer to use as timestamp source"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default SYSVIEW_TS_SOURCE_CCOUNT if FREERTOS_UNICORE && !PM_ENABLE
|
||||
default SYSVIEW_TS_SOURCE_TIMER_00 if !FREERTOS_UNICORE && !PM_ENABLE
|
||||
default SYSVIEW_TS_SOURCE_ESP_TIMER if PM_ENABLE
|
||||
help
|
||||
SystemView needs to use a hardware timer as the source of timestamps
|
||||
when tracing. This option selects the timer for it.
|
||||
|
||||
config APPTRACE_BUF_SIZE
|
||||
int "Size of the apptrace buffer"
|
||||
depends on APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE && !APPTRACE_DEST_TRAX
|
||||
default 16384
|
||||
help
|
||||
Size of the memory buffer for trace data in bytes.
|
||||
config SYSVIEW_TS_SOURCE_CCOUNT
|
||||
bool "CPU cycle counter (CCOUNT)"
|
||||
depends on FREERTOS_UNICORE && !PM_ENABLE
|
||||
|
||||
config APPTRACE_PENDING_DATA_SIZE_MAX
|
||||
int "Size of the pending data buffer"
|
||||
depends on APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE
|
||||
default 0
|
||||
help
|
||||
Size of the buffer for events in bytes. It is useful for buffering events from
|
||||
the time critical code (scheduler, ISRs etc). If this parameter is 0 then
|
||||
events will be discarded when main HW buffer is full.
|
||||
config SYSVIEW_TS_SOURCE_TIMER_00
|
||||
bool "Timer 0, Group 0"
|
||||
depends on !PM_ENABLE
|
||||
|
||||
menu "FreeRTOS SystemView Tracing"
|
||||
depends on APPTRACE_ENABLE
|
||||
config APPTRACE_SV_ENABLE
|
||||
bool "SystemView Tracing Enable"
|
||||
depends on APPTRACE_ENABLE
|
||||
default n
|
||||
help
|
||||
Enables supporrt for SEGGER SystemView tracing functionality.
|
||||
config SYSVIEW_TS_SOURCE_TIMER_01
|
||||
bool "Timer 1, Group 0"
|
||||
depends on !PM_ENABLE
|
||||
|
||||
choice APPTRACE_SV_TS_SOURCE
|
||||
prompt "Timer to use as timestamp source"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default APPTRACE_SV_TS_SOURCE_CCOUNT if FREERTOS_UNICORE && !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
default APPTRACE_SV_TS_SOURCE_TIMER_00 if !FREERTOS_UNICORE && !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
default APPTRACE_SV_TS_SOURCE_ESP_TIMER if PM_ENABLE || IDF_TARGET_ESP32C3
|
||||
help
|
||||
SystemView needs to use a hardware timer as the source of timestamps
|
||||
when tracing. This option selects the timer for it.
|
||||
config SYSVIEW_TS_SOURCE_TIMER_10
|
||||
bool "Timer 0, Group 1"
|
||||
depends on !PM_ENABLE
|
||||
|
||||
config APPTRACE_SV_TS_SOURCE_CCOUNT
|
||||
bool "CPU cycle counter (CCOUNT)"
|
||||
depends on FREERTOS_UNICORE && !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
config SYSVIEW_TS_SOURCE_TIMER_11
|
||||
bool "Timer 1, Group 1"
|
||||
depends on !PM_ENABLE
|
||||
|
||||
config APPTRACE_SV_TS_SOURCE_TIMER_00
|
||||
bool "Timer 0, Group 0"
|
||||
depends on !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
config SYSVIEW_TS_SOURCE_ESP_TIMER
|
||||
bool "esp_timer high resolution timer"
|
||||
|
||||
config APPTRACE_SV_TS_SOURCE_TIMER_01
|
||||
bool "Timer 1, Group 0"
|
||||
depends on !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
endchoice
|
||||
|
||||
config APPTRACE_SV_TS_SOURCE_TIMER_10
|
||||
bool "Timer 0, Group 1"
|
||||
depends on !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
config SYSVIEW_EVT_OVERFLOW_ENABLE
|
||||
bool "Trace Buffer Overflow Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Trace Buffer Overflow" event.
|
||||
|
||||
config APPTRACE_SV_TS_SOURCE_TIMER_11
|
||||
bool "Timer 1, Group 1"
|
||||
depends on !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
config SYSVIEW_EVT_ISR_ENTER_ENABLE
|
||||
bool "ISR Enter Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR Enter" event.
|
||||
|
||||
config APPTRACE_SV_TS_SOURCE_ESP_TIMER
|
||||
bool "esp_timer high resolution timer"
|
||||
config SYSVIEW_EVT_ISR_EXIT_ENABLE
|
||||
bool "ISR Exit Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR Exit" event.
|
||||
|
||||
endchoice
|
||||
config SYSVIEW_EVT_ISR_TO_SCHEDULER_ENABLE
|
||||
bool "ISR Exit to Scheduler Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR to Scheduler" event.
|
||||
|
||||
config APPTRACE_SV_MAX_TASKS
|
||||
int "Maximum supported tasks"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
range 1 64
|
||||
default 16
|
||||
help
|
||||
Configures maximum supported tasks in sysview debug
|
||||
config SYSVIEW_EVT_TASK_START_EXEC_ENABLE
|
||||
bool "Task Start Execution Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Start Execution" event.
|
||||
|
||||
config APPTRACE_SV_BUF_WAIT_TMO
|
||||
int "Trace buffer wait timeout"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default 500
|
||||
help
|
||||
Configures timeout (in us) to wait for free space in trace buffer.
|
||||
Set to -1 to wait forever and avoid lost events.
|
||||
config SYSVIEW_EVT_TASK_STOP_EXEC_ENABLE
|
||||
bool "Task Stop Execution Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Stop Execution" event.
|
||||
|
||||
config APPTRACE_SV_EVT_OVERFLOW_ENABLE
|
||||
bool "Trace Buffer Overflow Event"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Trace Buffer Overflow" event.
|
||||
config SYSVIEW_EVT_TASK_START_READY_ENABLE
|
||||
bool "Task Start Ready State Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Start Ready State" event.
|
||||
|
||||
config APPTRACE_SV_EVT_ISR_ENTER_ENABLE
|
||||
bool "ISR Enter Event"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR Enter" event.
|
||||
config SYSVIEW_EVT_TASK_STOP_READY_ENABLE
|
||||
bool "Task Stop Ready State Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Stop Ready State" event.
|
||||
|
||||
config APPTRACE_SV_EVT_ISR_EXIT_ENABLE
|
||||
bool "ISR Exit Event"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR Exit" event.
|
||||
config SYSVIEW_EVT_TASK_CREATE_ENABLE
|
||||
bool "Task Create Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Create" event.
|
||||
|
||||
config APPTRACE_SV_EVT_ISR_TO_SCHED_ENABLE
|
||||
bool "ISR Exit to Scheduler Event"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR to Scheduler" event.
|
||||
config SYSVIEW_EVT_TASK_TERMINATE_ENABLE
|
||||
bool "Task Terminate Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Terminate" event.
|
||||
|
||||
config APPTRACE_SV_EVT_TASK_START_EXEC_ENABLE
|
||||
bool "Task Start Execution Event"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Start Execution" event.
|
||||
config SYSVIEW_EVT_IDLE_ENABLE
|
||||
bool "System Idle Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "System Idle" event.
|
||||
|
||||
config APPTRACE_SV_EVT_TASK_STOP_EXEC_ENABLE
|
||||
bool "Task Stop Execution Event"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Stop Execution" event.
|
||||
config SYSVIEW_EVT_TIMER_ENTER_ENABLE
|
||||
bool "Timer Enter Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Timer Enter" event.
|
||||
|
||||
config APPTRACE_SV_EVT_TASK_START_READY_ENABLE
|
||||
bool "Task Start Ready State Event"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Start Ready State" event.
|
||||
|
||||
config APPTRACE_SV_EVT_TASK_STOP_READY_ENABLE
|
||||
bool "Task Stop Ready State Event"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Stop Ready State" event.
|
||||
|
||||
config APPTRACE_SV_EVT_TASK_CREATE_ENABLE
|
||||
bool "Task Create Event"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Create" event.
|
||||
|
||||
config APPTRACE_SV_EVT_TASK_TERMINATE_ENABLE
|
||||
bool "Task Terminate Event"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Terminate" event.
|
||||
|
||||
config APPTRACE_SV_EVT_IDLE_ENABLE
|
||||
bool "System Idle Event"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "System Idle" event.
|
||||
|
||||
config APPTRACE_SV_EVT_TIMER_ENTER_ENABLE
|
||||
bool "Timer Enter Event"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Timer Enter" event.
|
||||
|
||||
config APPTRACE_SV_EVT_TIMER_EXIT_ENABLE
|
||||
bool "Timer Exit Event"
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Timer Exit" event.
|
||||
|
||||
endmenu
|
||||
|
||||
config APPTRACE_GCOV_ENABLE
|
||||
bool "GCOV to Host Enable"
|
||||
depends on APPTRACE_ENABLE && !APPTRACE_SV_ENABLE
|
||||
select ESP_DEBUG_STUBS_ENABLE
|
||||
default n
|
||||
help
|
||||
Enables support for GCOV data transfer to host.
|
||||
config SYSVIEW_EVT_TIMER_EXIT_ENABLE
|
||||
bool "Timer Exit Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Timer Exit" event.
|
||||
|
||||
endmenu
|
||||
|
||||
config ESP32_GCOV_ENABLE
|
||||
bool "GCOV to Host Enable"
|
||||
depends on ESP32_DEBUG_STUBS_ENABLE && ESP32_APPTRACE_ENABLE && !SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables support for GCOV data transfer to host.
|
||||
|
||||
endmenu
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,364 +0,0 @@
|
||||
#include <sys/param.h>
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_app_trace_membufs_proto.h"
|
||||
|
||||
/** Trace data header. Every user data chunk is prepended with this header.
|
||||
* User allocates block with esp_apptrace_buffer_get and then fills it with data,
|
||||
* in multithreading environment it can happen that tasks gets buffer and then gets interrupted,
|
||||
* so it is possible that user data are incomplete when memory block is exposed to the host.
|
||||
* In this case host SW will see that wr_sz < block_sz and will report error.
|
||||
*/
|
||||
typedef struct {
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
uint8_t block_sz; // size of allocated block for user data
|
||||
uint8_t wr_sz; // size of actually written data
|
||||
#else
|
||||
uint16_t block_sz; // size of allocated block for user data
|
||||
uint16_t wr_sz; // size of actually written data
|
||||
#endif
|
||||
} esp_tracedata_hdr_t;
|
||||
|
||||
/** TODO: docs
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t block_sz; // size of allocated block for user data
|
||||
} esp_hostdata_hdr_t;
|
||||
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
#define ESP_APPTRACE_USR_BLOCK_CORE(_cid_) (0)
|
||||
#define ESP_APPTRACE_USR_BLOCK_LEN(_v_) (_v_)
|
||||
#define ESP_APPTRACE_USR_DATA_LEN_MAX(_hw_data_) 255UL
|
||||
#else
|
||||
#define ESP_APPTRACE_USR_BLOCK_CORE(_cid_) ((_cid_) << 15)
|
||||
#define ESP_APPTRACE_USR_BLOCK_LEN(_v_) (~(1 << 15) & (_v_))
|
||||
#define ESP_APPTRACE_USR_DATA_LEN_MAX(_hw_data_) (ESP_APPTRACE_INBLOCK(_hw_data_)->sz - sizeof(esp_tracedata_hdr_t))
|
||||
#endif
|
||||
#define ESP_APPTRACE_USR_BLOCK_RAW_SZ(_s_) ((_s_) + sizeof(esp_tracedata_hdr_t))
|
||||
|
||||
#define ESP_APPTRACE_INBLOCK_MARKER(_hw_data_) ((_hw_data_)->state.markers[(_hw_data_)->state.in_block % 2])
|
||||
#define ESP_APPTRACE_INBLOCK_MARKER_UPD(_hw_data_, _v_) do {(_hw_data_)->state.markers[(_hw_data_)->state.in_block % 2] += (_v_);}while(0)
|
||||
#define ESP_APPTRACE_INBLOCK(_hw_data_) (&(_hw_data_)->blocks[(_hw_data_)->state.in_block % 2])
|
||||
|
||||
const static char *TAG = "esp_apptrace";
|
||||
|
||||
static uint32_t esp_apptrace_membufs_down_buffer_write_nolock(esp_apptrace_membufs_proto_data_t *proto, uint8_t *data, uint32_t size);
|
||||
|
||||
|
||||
esp_err_t esp_apptrace_membufs_init(esp_apptrace_membufs_proto_data_t *proto, const esp_apptrace_mem_block_t blocks_cfg[2])
|
||||
{
|
||||
// disabled by default
|
||||
esp_apptrace_rb_init(&proto->rb_down, NULL, 0);
|
||||
// membufs proto init
|
||||
for (unsigned i = 0; i < 2; i++) {
|
||||
proto->blocks[i].start = blocks_cfg[i].start;
|
||||
proto->blocks[i].sz = blocks_cfg[i].sz;
|
||||
proto->state.markers[i] = 0;
|
||||
}
|
||||
proto->state.in_block = 0;
|
||||
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0
|
||||
esp_apptrace_rb_init(&proto->rb_pend, proto->pending_data,
|
||||
sizeof(proto->pending_data));
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_apptrace_membufs_down_buffer_config(esp_apptrace_membufs_proto_data_t *data, uint8_t *buf, uint32_t size)
|
||||
{
|
||||
esp_apptrace_rb_init(&data->rb_down, buf, size);
|
||||
}
|
||||
|
||||
// assumed to be protected by caller from multi-core/thread access
|
||||
static esp_err_t esp_apptrace_membufs_swap(esp_apptrace_membufs_proto_data_t *proto)
|
||||
{
|
||||
int prev_block_num = proto->state.in_block % 2;
|
||||
int new_block_num = prev_block_num ? (0) : (1);
|
||||
esp_err_t res = ESP_OK;
|
||||
|
||||
res = proto->hw->swap_start(proto->state.in_block);
|
||||
if (res != ESP_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
proto->state.markers[new_block_num] = 0;
|
||||
// switch to new block
|
||||
proto->state.in_block++;
|
||||
|
||||
proto->hw->swap(new_block_num);
|
||||
|
||||
// handle data from host
|
||||
esp_hostdata_hdr_t *hdr = (esp_hostdata_hdr_t *)proto->blocks[new_block_num].start;
|
||||
// ESP_APPTRACE_LOGV("Host data %d, sz %d @ %p", proto->hw->host_data_pending(), hdr->block_sz, hdr);
|
||||
if (proto->hw->host_data_pending() && hdr->block_sz > 0) {
|
||||
// TODO: add support for multiple blocks from host, currently there is no need for that
|
||||
uint8_t *p = proto->blocks[new_block_num].start + proto->blocks[new_block_num].sz;
|
||||
ESP_APPTRACE_LOGD("Recvd %d bytes from host [%x %x %x %x %x %x %x %x .. %x %x %x %x %x %x %x %x]", hdr->block_sz,
|
||||
*(proto->blocks[new_block_num].start+0), *(proto->blocks[new_block_num].start+1),
|
||||
*(proto->blocks[new_block_num].start+2), *(proto->blocks[new_block_num].start+3),
|
||||
*(proto->blocks[new_block_num].start+4), *(proto->blocks[new_block_num].start+5),
|
||||
*(proto->blocks[new_block_num].start+6), *(proto->blocks[new_block_num].start+7),
|
||||
*(p-8), *(p-7), *(p-6), *(p-5), *(p-4), *(p-3), *(p-2), *(p-1));
|
||||
uint32_t sz = esp_apptrace_membufs_down_buffer_write_nolock(proto, (uint8_t *)(hdr+1), hdr->block_sz);
|
||||
if (sz != hdr->block_sz) {
|
||||
ESP_APPTRACE_LOGE("Failed to write %d bytes to down buffer (%d %d)!", hdr->block_sz - sz, hdr->block_sz, sz);
|
||||
}
|
||||
hdr->block_sz = 0;
|
||||
}
|
||||
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0
|
||||
// copy pending data to block if any
|
||||
while (proto->state.markers[new_block_num] < proto->blocks[new_block_num].sz) {
|
||||
uint32_t read_sz = esp_apptrace_rb_read_size_get(&proto->rb_pend);
|
||||
if (read_sz == 0) {
|
||||
break; // no more data in pending buffer
|
||||
}
|
||||
if (read_sz > proto->blocks[new_block_num].sz - proto->state.markers[new_block_num]) {
|
||||
read_sz = proto->blocks[new_block_num].sz - proto->state.markers[new_block_num];
|
||||
}
|
||||
uint8_t *ptr = esp_apptrace_rb_consume(&proto->rb_pend, read_sz);
|
||||
if (!ptr) {
|
||||
assert(false && "Failed to consume pended bytes!!");
|
||||
break;
|
||||
}
|
||||
ESP_APPTRACE_LOGD("Pump %d pend bytes [%x %x %x %x : %x %x %x %x : %x %x %x %x : %x %x...%x %x]",
|
||||
read_sz, *(ptr+0), *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
|
||||
*(ptr+5), *(ptr+6), *(ptr+7), *(ptr+8), *(ptr+9), *(ptr+10), *(ptr+11), *(ptr+12), *(ptr+13), *(ptr+read_sz-2), *(ptr+read_sz-1));
|
||||
memcpy(proto->blocks[new_block_num].start + proto->state.markers[new_block_num], ptr, read_sz);
|
||||
proto->state.markers[new_block_num] += read_sz;
|
||||
}
|
||||
#endif
|
||||
proto->hw->swap_end(proto->state.in_block, proto->state.markers[prev_block_num]);
|
||||
return res;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_membufs_swap_waitus(esp_apptrace_membufs_proto_data_t *proto, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
int res;
|
||||
|
||||
while ((res = esp_apptrace_membufs_swap(proto)) != ESP_OK) {
|
||||
res = esp_apptrace_tmo_check(tmo);
|
||||
if (res != ESP_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t *esp_apptrace_membufs_down_buffer_get(esp_apptrace_membufs_proto_data_t *proto, uint32_t *size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
uint8_t *ptr = NULL;
|
||||
|
||||
while (1) {
|
||||
uint32_t sz = esp_apptrace_rb_read_size_get(&proto->rb_down);
|
||||
if (sz != 0) {
|
||||
*size = MIN(*size, sz);
|
||||
ptr = esp_apptrace_rb_consume(&proto->rb_down, *size);
|
||||
if (!ptr) {
|
||||
assert(false && "Failed to consume bytes from down buffer!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
// may need to flush
|
||||
if (proto->hw->host_data_pending()) {
|
||||
ESP_APPTRACE_LOGD("force flush");
|
||||
int res = esp_apptrace_membufs_swap_waitus(proto, tmo);
|
||||
if (res != ESP_OK) {
|
||||
ESP_APPTRACE_LOGE("Failed to switch to another block to recv data from host!");
|
||||
/*do not return error because data can be in down buffer already*/
|
||||
}
|
||||
} else {
|
||||
// check tmo only if there is no data from host
|
||||
int res = esp_apptrace_tmo_check(tmo);
|
||||
if (res != ESP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_membufs_down_buffer_put(esp_apptrace_membufs_proto_data_t *proto, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
/* nothing todo */
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static uint32_t esp_apptrace_membufs_down_buffer_write_nolock(esp_apptrace_membufs_proto_data_t *proto, uint8_t *data, uint32_t size)
|
||||
{
|
||||
uint32_t total_sz = 0;
|
||||
|
||||
while (total_sz < size) {
|
||||
ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock WRS %d-%d-%d %d", proto->rb_down.wr, proto->rb_down.rd,
|
||||
proto->rb_down.cur_size, size);
|
||||
uint32_t wr_sz = esp_apptrace_rb_write_size_get(&proto->rb_down);
|
||||
if (wr_sz == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (wr_sz > size - total_sz) {
|
||||
wr_sz = size - total_sz;
|
||||
}
|
||||
ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d", wr_sz);
|
||||
uint8_t *ptr = esp_apptrace_rb_produce(&proto->rb_down, wr_sz);
|
||||
if (!ptr) {
|
||||
assert(false && "Failed to produce bytes to down buffer!");
|
||||
}
|
||||
ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d to 0x%x from 0x%x", wr_sz, ptr, data + total_sz + wr_sz);
|
||||
memcpy(ptr, data + total_sz, wr_sz);
|
||||
total_sz += wr_sz;
|
||||
ESP_APPTRACE_LOGD("esp_apptrace_trax_down_buffer_write_nolock wr %d/%d", wr_sz, total_sz);
|
||||
}
|
||||
return total_sz;
|
||||
}
|
||||
|
||||
static inline uint8_t *esp_apptrace_membufs_wait4buf(esp_apptrace_membufs_proto_data_t *proto, uint16_t size, esp_apptrace_tmo_t *tmo, int *pended)
|
||||
{
|
||||
uint8_t *ptr = NULL;
|
||||
|
||||
int res = esp_apptrace_membufs_swap_waitus(proto, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0
|
||||
// check if we still have pending data
|
||||
if (esp_apptrace_rb_read_size_get(&proto->rb_pend) > 0) {
|
||||
// if after block switch we still have pending data (not all pending data have been pumped to block)
|
||||
// alloc new pending buffer
|
||||
*pended = 1;
|
||||
ptr = esp_apptrace_rb_produce(&proto->rb_pend, size);
|
||||
if (!ptr) {
|
||||
ESP_APPTRACE_LOGE("Failed to alloc pend buf 1: w-r-s %d-%d-%d!", proto->rb_pend.wr, proto->rb_pend.rd, proto->rb_pend.cur_size);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// update block pointers
|
||||
if (ESP_APPTRACE_INBLOCK_MARKER(proto) + size > ESP_APPTRACE_INBLOCK(proto)->sz) {
|
||||
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0
|
||||
*pended = 1;
|
||||
ptr = esp_apptrace_rb_produce(&proto->rb_pend, size);
|
||||
if (ptr == NULL) {
|
||||
ESP_APPTRACE_LOGE("Failed to alloc pend buf 2: w-r-s %d-%d-%d!", proto->rb_pend.wr, proto->rb_pend.rd, proto->rb_pend.cur_size);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
*pended = 0;
|
||||
ptr = ESP_APPTRACE_INBLOCK(proto)->start + ESP_APPTRACE_INBLOCK_MARKER(proto);
|
||||
}
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static inline uint8_t *esp_apptrace_membufs_pkt_start(uint8_t *ptr, uint16_t size)
|
||||
{
|
||||
// it is safe to use cpu_hal_get_core_id() in macro call because arg is used only once inside it
|
||||
((esp_tracedata_hdr_t *)ptr)->block_sz = ESP_APPTRACE_USR_BLOCK_CORE(cpu_hal_get_core_id()) | size;
|
||||
((esp_tracedata_hdr_t *)ptr)->wr_sz = 0;
|
||||
return ptr + sizeof(esp_tracedata_hdr_t);
|
||||
}
|
||||
|
||||
static inline void esp_apptrace_membufs_pkt_end(uint8_t *ptr)
|
||||
{
|
||||
esp_tracedata_hdr_t *hdr = (esp_tracedata_hdr_t *)(ptr - sizeof(esp_tracedata_hdr_t));
|
||||
// update written size
|
||||
hdr->wr_sz = hdr->block_sz;
|
||||
}
|
||||
|
||||
uint8_t *esp_apptrace_membufs_up_buffer_get(esp_apptrace_membufs_proto_data_t *proto, uint32_t size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
uint8_t *buf_ptr = NULL;
|
||||
|
||||
if (size > ESP_APPTRACE_USR_DATA_LEN_MAX(proto)) {
|
||||
ESP_APPTRACE_LOGE("Too large user data size %d!", size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// check for data in the pending buffer
|
||||
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0
|
||||
if (esp_apptrace_rb_read_size_get(&proto->rb_pend) > 0) {
|
||||
// if we have buffered data try to switch block
|
||||
esp_apptrace_membufs_swap(proto);
|
||||
// if switch was successful, part or all pended data have been copied to block
|
||||
}
|
||||
if (esp_apptrace_rb_read_size_get(&proto->rb_pend) > 0) {
|
||||
// if we have buffered data alloc new pending buffer
|
||||
ESP_APPTRACE_LOGD("Get %d bytes from PEND buffer", size);
|
||||
buf_ptr = esp_apptrace_rb_produce(&proto->rb_pend, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size));
|
||||
if (buf_ptr == NULL) {
|
||||
int pended_buf;
|
||||
buf_ptr = esp_apptrace_membufs_wait4buf(proto, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size), tmo, &pended_buf);
|
||||
if (buf_ptr && !pended_buf) {
|
||||
ESP_APPTRACE_LOGD("Get %d bytes from block", size);
|
||||
// update cur block marker
|
||||
ESP_APPTRACE_INBLOCK_MARKER_UPD(proto, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#else
|
||||
if (1) {
|
||||
#endif
|
||||
if (ESP_APPTRACE_INBLOCK_MARKER(proto) + ESP_APPTRACE_USR_BLOCK_RAW_SZ(size) > ESP_APPTRACE_INBLOCK(proto)->sz) {
|
||||
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0
|
||||
ESP_APPTRACE_LOGD("Block full. Get %d bytes from PEND buffer", size);
|
||||
buf_ptr = esp_apptrace_rb_produce(&proto->rb_pend, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size));
|
||||
#endif
|
||||
if (buf_ptr == NULL) {
|
||||
int pended_buf;
|
||||
ESP_APPTRACE_LOGD(" full. Get %d bytes from pend buffer", size);
|
||||
buf_ptr = esp_apptrace_membufs_wait4buf(proto, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size), tmo, &pended_buf);
|
||||
if (buf_ptr && !pended_buf) {
|
||||
ESP_APPTRACE_LOGD("Got %d bytes from block", size);
|
||||
// update cur block marker
|
||||
ESP_APPTRACE_INBLOCK_MARKER_UPD(proto, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ESP_APPTRACE_LOGD("Get %d bytes from buffer", size);
|
||||
// fit to curr nlock
|
||||
buf_ptr = ESP_APPTRACE_INBLOCK(proto)->start + ESP_APPTRACE_INBLOCK_MARKER(proto);
|
||||
// update cur block marker
|
||||
ESP_APPTRACE_INBLOCK_MARKER_UPD(proto, ESP_APPTRACE_USR_BLOCK_RAW_SZ(size));
|
||||
}
|
||||
}
|
||||
if (buf_ptr) {
|
||||
buf_ptr = esp_apptrace_membufs_pkt_start(buf_ptr, size);
|
||||
}
|
||||
|
||||
return buf_ptr;
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_membufs_up_buffer_put(esp_apptrace_membufs_proto_data_t *proto, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
esp_apptrace_membufs_pkt_end(ptr);
|
||||
// TODO: mark block as busy in order not to re-use it for other tracing calls until it is completely written
|
||||
// TODO: avoid potential situation when all memory is consumed by low prio tasks which can not complete writing due to
|
||||
// higher prio tasks and the latter can not allocate buffers at all
|
||||
// this is abnormal situation can be detected on host which will receive only uncompleted buffers
|
||||
// workaround: use own memcpy which will kick-off dead tracing calls
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_membufs_flush_nolock(esp_apptrace_membufs_proto_data_t *proto, uint32_t min_sz, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
int res = ESP_OK;
|
||||
|
||||
if (ESP_APPTRACE_INBLOCK_MARKER(proto) < min_sz) {
|
||||
ESP_APPTRACE_LOGI("Ignore flush request for min %d bytes. Bytes in block: %d.", min_sz, ESP_APPTRACE_INBLOCK_MARKER(proto));
|
||||
return ESP_OK;
|
||||
}
|
||||
// switch block while size of data (including that in pending buffer) is more than min size
|
||||
while (ESP_APPTRACE_INBLOCK_MARKER(proto) > min_sz) {
|
||||
ESP_APPTRACE_LOGD("Try to flush %d bytes. Wait until block switch for %lld us", ESP_APPTRACE_INBLOCK_MARKER(proto), tmo->tmo);
|
||||
res = esp_apptrace_membufs_swap_waitus(proto, tmo);
|
||||
if (res != ESP_OK) {
|
||||
if (tmo->tmo != ESP_APPTRACE_TMO_INFINITE)
|
||||
ESP_APPTRACE_LOGW("Failed to switch to another block in %lld us!", tmo->tmo);
|
||||
else
|
||||
ESP_APPTRACE_LOGE("Failed to switch to another block in %lld us!", tmo->tmo);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -1,49 +1,39 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
// Copyright 2017 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 "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_app_trace_util.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////// Locks /////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if ESP_APPTRACE_PRINT_LOCK
|
||||
static esp_apptrace_lock_t s_log_lock = {.irq_stat = 0, .portmux = portMUX_INITIALIZER_UNLOCKED};
|
||||
#endif
|
||||
|
||||
int esp_apptrace_log_lock(void)
|
||||
{
|
||||
#if ESP_APPTRACE_PRINT_LOCK
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_tmo_init(&tmo, ESP_APPTRACE_TMO_INFINITE);
|
||||
int ret = esp_apptrace_lock_take(&s_log_lock, &tmo);
|
||||
return ret;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void esp_apptrace_log_unlock(void)
|
||||
{
|
||||
#if ESP_APPTRACE_PRINT_LOCK
|
||||
esp_apptrace_lock_give(&s_log_lock);
|
||||
#endif
|
||||
}
|
||||
#include "esp_clk.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////// TIMEOUT /////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ESP_APPTRACE_CPUTICKS2US(_t_, _cpu_freq_) ((_t_)/(_cpu_freq_/1000000))
|
||||
#define ESP_APPTRACE_US2CPUTICKS(_t_, _cpu_freq_) ((_t_)*(_cpu_freq_/1000000))
|
||||
|
||||
esp_err_t esp_apptrace_tmo_check(esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (tmo->tmo != (int64_t)-1) {
|
||||
tmo->elapsed = esp_timer_get_time() - tmo->start;
|
||||
int cpu_freq = esp_clk_cpu_freq();
|
||||
if (tmo->tmo != ESP_APPTRACE_TMO_INFINITE) {
|
||||
unsigned cur = portGET_RUN_TIME_COUNTER_VALUE();
|
||||
if (tmo->start <= cur) {
|
||||
tmo->elapsed = ESP_APPTRACE_CPUTICKS2US(cur - tmo->start, cpu_freq);
|
||||
} else {
|
||||
tmo->elapsed = ESP_APPTRACE_CPUTICKS2US(0xFFFFFFFF - tmo->start + cur, cpu_freq);
|
||||
}
|
||||
if (tmo->elapsed >= tmo->tmo) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
@@ -4,21 +4,14 @@
|
||||
|
||||
COMPONENT_SRCDIRS := .
|
||||
|
||||
ifdef CONFIG_APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE
|
||||
COMPONENT_SRCDIRS += port/xtensa
|
||||
endif
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS = include
|
||||
|
||||
COMPONENT_PRIV_INCLUDEDIRS = private_include \
|
||||
port/include
|
||||
|
||||
COMPONENT_ADD_LDFLAGS = -lapp_trace
|
||||
|
||||
# do not produce gcov info for this module, it is used as transport for gcov
|
||||
CFLAGS := $(subst --coverage,,$(CFLAGS))
|
||||
|
||||
ifdef CONFIG_APPTRACE_SV_ENABLE
|
||||
ifdef CONFIG_SYSVIEW_ENABLE
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS += \
|
||||
sys_view/Config \
|
||||
@@ -30,10 +23,7 @@ COMPONENT_SRCDIRS += \
|
||||
sys_view/SEGGER \
|
||||
sys_view/Sample/OS \
|
||||
sys_view/Sample/Config \
|
||||
sys_view/esp \
|
||||
sys_view/ext
|
||||
sys_view/esp32
|
||||
else
|
||||
COMPONENT_SRCDIRS += gcov
|
||||
endif
|
||||
|
||||
COMPONENT_ADD_LDFRAGMENTS += linker.lf
|
||||
|
||||
@@ -1,150 +1,145 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
// Copyright 2017 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.
|
||||
|
||||
// This module implements runtime file I/O API for GCOV.
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_task_wdt.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/timer_periph.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_freertos_hooks.h"
|
||||
#include "esp_private/dbg_stubs.h"
|
||||
#include "esp_ipc.h"
|
||||
#include "hal/wdt_hal.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/libc_stubs.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/libc_stubs.h"
|
||||
#endif
|
||||
#include "esp_dbg_stubs.h"
|
||||
|
||||
#if CONFIG_APPTRACE_GCOV_ENABLE
|
||||
#if CONFIG_ESP32_GCOV_ENABLE
|
||||
|
||||
#define ESP_GCOV_DOWN_BUF_SIZE 4200
|
||||
|
||||
#define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "esp_gcov_rtio";
|
||||
static volatile bool s_create_gcov_task = false;
|
||||
static volatile bool s_gcov_task_running = false;
|
||||
|
||||
extern void __gcov_dump(void);
|
||||
extern void __gcov_reset(void);
|
||||
static void (*s_gcov_exit)(void);
|
||||
|
||||
void gcov_dump_task(void *pvParameter)
|
||||
/* TODO: remove code extracted from GCC when IDF toolchain will be updated */
|
||||
/*=============== GCC CODE START ====================*/
|
||||
/* Root of a program/shared-object state */
|
||||
struct gcov_root
|
||||
{
|
||||
int dump_result = 0;
|
||||
bool *running = (bool *)pvParameter;
|
||||
void *list;
|
||||
unsigned dumped : 1; /* counts have been dumped. */
|
||||
unsigned run_counted : 1; /* run has been accounted for. */
|
||||
struct gcov_root *next;
|
||||
struct gcov_root *prev;
|
||||
};
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "%s stack use in %d", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL));
|
||||
/* Per-dynamic-object gcov state. */
|
||||
extern struct gcov_root __gcov_root;
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "Alloc apptrace down buf %d bytes", ESP_GCOV_DOWN_BUF_SIZE);
|
||||
void *down_buf = malloc(ESP_GCOV_DOWN_BUF_SIZE);
|
||||
if (down_buf == NULL) {
|
||||
ESP_EARLY_LOGE(TAG, "Could not allocate memory for the buffer");
|
||||
dump_result = ESP_ERR_NO_MEM;
|
||||
goto gcov_exit;
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "Config apptrace down buf");
|
||||
esp_apptrace_down_buffer_config(down_buf, ESP_GCOV_DOWN_BUF_SIZE);
|
||||
/* we are directing the std outputs to the fake ones in order to reduce stack usage */
|
||||
FILE *old_stderr = stderr;
|
||||
FILE *old_stdout = stdout;
|
||||
stderr = (FILE *) &__sf_fake_stderr;
|
||||
stdout = (FILE *) &__sf_fake_stdout;
|
||||
ESP_EARLY_LOGV(TAG, "Dump data...");
|
||||
__gcov_dump();
|
||||
// reset dump status to allow incremental data accumulation
|
||||
__gcov_reset();
|
||||
free(down_buf);
|
||||
stderr = old_stderr;
|
||||
stdout = old_stdout;
|
||||
ESP_EARLY_LOGV(TAG, "Finish file transfer session");
|
||||
dump_result = esp_apptrace_fstop(ESP_APPTRACE_DEST_TRAX);
|
||||
if (dump_result != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", dump_result);
|
||||
}
|
||||
|
||||
gcov_exit:
|
||||
ESP_EARLY_LOGV(TAG, "dump_result %d", dump_result);
|
||||
if (running) {
|
||||
*running = false;
|
||||
}
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "%s stack use out %d", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
vTaskDelete(NULL);
|
||||
static void esp_gcov_reset_status(void)
|
||||
{
|
||||
__gcov_root.dumped = 0;
|
||||
__gcov_root.run_counted = 0;
|
||||
}
|
||||
/*=============== GCC CODE END ====================*/
|
||||
|
||||
void gcov_create_task(void *arg)
|
||||
static int esp_dbg_stub_gcov_dump_do(void)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
xTaskCreatePinnedToCore(&gcov_dump_task, "gcov_dump_task", 2048, (void *)&s_gcov_task_running, configMAX_PRIORITIES - 1, NULL, 0);
|
||||
}
|
||||
int ret = ESP_OK;
|
||||
|
||||
void gcov_create_task_tick_hook(void)
|
||||
{
|
||||
extern esp_err_t esp_ipc_start_gcov_from_isr(uint32_t cpu_id, esp_ipc_func_t func, void* arg);
|
||||
if (s_create_gcov_task) {
|
||||
if (esp_ipc_start_gcov_from_isr(xPortGetCoreID(), &gcov_create_task, NULL) == ESP_OK) {
|
||||
s_create_gcov_task = false;
|
||||
ESP_EARLY_LOGV(TAG, "Check for dump handler %p", s_gcov_exit);
|
||||
if (s_gcov_exit) {
|
||||
ESP_EARLY_LOGV(TAG, "Alloc apptrace down buf %d bytes", ESP_GCOV_DOWN_BUF_SIZE);
|
||||
void *down_buf = malloc(ESP_GCOV_DOWN_BUF_SIZE);
|
||||
if (down_buf == NULL) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", ret);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "Config apptrace down buf");
|
||||
esp_apptrace_down_buffer_config(down_buf, ESP_GCOV_DOWN_BUF_SIZE);
|
||||
ESP_EARLY_LOGV(TAG, "Dump data... %p", s_gcov_exit);
|
||||
s_gcov_exit();
|
||||
ESP_EARLY_LOGV(TAG, "Free apptrace down buf");
|
||||
free(down_buf);
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "Finish file transfer session");
|
||||
ret = esp_apptrace_fstop(ESP_APPTRACE_DEST_TRAX);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Triggers gcov info dump task
|
||||
* @brief Triggers gcov info dump.
|
||||
* This function is to be called by OpenOCD, not by normal user code.
|
||||
* TODO: what about interrupted flash access (when cache disabled)
|
||||
* TODO: what about interrupted flash access (when cache disabled)???
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
static int esp_dbg_stub_gcov_entry(void)
|
||||
{
|
||||
/* we are in isr context here */
|
||||
s_create_gcov_task = true;
|
||||
return ESP_OK;
|
||||
int ret = ESP_OK;
|
||||
|
||||
// disable IRQs on this CPU, other CPU is halted by OpenOCD
|
||||
unsigned irq_state = portENTER_CRITICAL_NESTED();
|
||||
ret = esp_dbg_stub_gcov_dump_do();
|
||||
// reset dump status to allow incremental data accumulation
|
||||
esp_gcov_reset_status();
|
||||
portEXIT_CRITICAL_NESTED(irq_state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int gcov_rtio_atexit(void (*function)(void) __attribute__ ((unused)))
|
||||
void esp_gcov_dump()
|
||||
{
|
||||
uint32_t capabilities = 0;
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_GCOV, (uint32_t)&esp_dbg_stub_gcov_entry);
|
||||
if (esp_dbg_stub_entry_get(ESP_DBG_STUB_ENTRY_CAPABILITIES, &capabilities) == ESP_OK) {
|
||||
esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_CAPABILITIES, capabilities | ESP_DBG_STUB_CAP_GCOV_TASK);
|
||||
}
|
||||
esp_register_freertos_tick_hook(gcov_create_task_tick_hook);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_gcov_dump(void)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
#if CONFIG_FREERTOS_UNICORE == 0
|
||||
int other_core = xPortGetCoreID() ? 0 : 1;
|
||||
esp_cpu_stall(other_core);
|
||||
#endif
|
||||
|
||||
while (!esp_apptrace_host_is_connected(ESP_APPTRACE_DEST_TRAX)) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
// to avoid complains that task watchdog got triggered for other tasks
|
||||
TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
|
||||
TIMERG0.wdt_feed=1;
|
||||
TIMERG0.wdt_wprotect=0;
|
||||
// to avoid reboot on INT_WDT
|
||||
TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
|
||||
TIMERG1.wdt_feed=1;
|
||||
TIMERG1.wdt_wprotect=0;
|
||||
}
|
||||
|
||||
/* We are not in isr context here. Waiting for the completion is safe */
|
||||
s_gcov_task_running = true;
|
||||
s_create_gcov_task = true;
|
||||
while (s_gcov_task_running) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
esp_dbg_stub_gcov_dump_do();
|
||||
// reset dump status to allow incremental data accumulation
|
||||
esp_gcov_reset_status();
|
||||
#if CONFIG_FREERTOS_UNICORE == 0
|
||||
esp_cpu_unstall(other_core);
|
||||
#endif
|
||||
}
|
||||
|
||||
int gcov_rtio_atexit(void (*function)(void))
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s %p", __FUNCTION__, function);
|
||||
s_gcov_exit = function;
|
||||
esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_GCOV, (uint32_t)&esp_dbg_stub_gcov_entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *gcov_rtio_fopen(const char *path, const char *mode)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s '%s' '%s'", __FUNCTION__, path, mode);
|
||||
void *f = esp_apptrace_fopen(ESP_APPTRACE_DEST_TRAX, path, mode);
|
||||
ESP_EARLY_LOGV(TAG, "%s ret %p", __FUNCTION__, f);
|
||||
return f;
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
return esp_apptrace_fopen(ESP_APPTRACE_DEST_TRAX, path, mode);
|
||||
}
|
||||
|
||||
int gcov_rtio_fclose(void *stream)
|
||||
@@ -155,10 +150,8 @@ int gcov_rtio_fclose(void *stream)
|
||||
|
||||
size_t gcov_rtio_fread(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s read %u", __FUNCTION__, size * nmemb);
|
||||
size_t sz = esp_apptrace_fread(ESP_APPTRACE_DEST_TRAX, ptr, size, nmemb, stream);
|
||||
ESP_EARLY_LOGV(TAG, "%s actually read %u", __FUNCTION__, sz);
|
||||
return sz;
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
return esp_apptrace_fread(ESP_APPTRACE_DEST_TRAX, ptr, size, nmemb, stream);
|
||||
}
|
||||
|
||||
size_t gcov_rtio_fwrite(const void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
@@ -169,15 +162,17 @@ size_t gcov_rtio_fwrite(const void *ptr, size_t size, size_t nmemb, void *stream
|
||||
|
||||
int gcov_rtio_fseek(void *stream, long offset, int whence)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
int ret = esp_apptrace_fseek(ESP_APPTRACE_DEST_TRAX, stream, offset, whence);
|
||||
ESP_EARLY_LOGV(TAG, "%s(%p %ld %d) = %d", __FUNCTION__, stream, offset, whence, ret);
|
||||
ESP_EARLY_LOGV(TAG, "%s EXIT", __FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
long gcov_rtio_ftell(void *stream)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
long ret = esp_apptrace_ftell(ESP_APPTRACE_DEST_TRAX, stream);
|
||||
ESP_EARLY_LOGV(TAG, "%s(%p) = %ld", __FUNCTION__, stream, ret);
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <sdkconfig.h>
|
||||
|
||||
#define HEAP_TRACE_SRCFILE /* don't warn on inclusion here */
|
||||
#include "esp_heap_trace.h"
|
||||
#undef HEAP_TRACE_SRCFILE
|
||||
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_sysview_trace.h"
|
||||
#endif
|
||||
|
||||
#define STACK_DEPTH CONFIG_HEAP_TRACING_STACK_DEPTH
|
||||
|
||||
#ifdef CONFIG_HEAP_TRACING_TOHOST
|
||||
|
||||
#if !CONFIG_APPTRACE_SV_ENABLE
|
||||
#error None of the heap tracing backends is enabled! You must enable SystemView compatible tracing to use this feature.
|
||||
#endif
|
||||
|
||||
static bool s_tracing;
|
||||
|
||||
esp_err_t heap_trace_init_tohost(void)
|
||||
{
|
||||
if (s_tracing) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t heap_trace_start(heap_trace_mode_t mode_param)
|
||||
{
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
esp_err_t ret = esp_sysview_heap_trace_start((uint32_t)-1);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
s_tracing = true;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t heap_trace_stop(void)
|
||||
{
|
||||
esp_err_t ret = ESP_ERR_NOT_SUPPORTED;
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
ret = esp_sysview_heap_trace_stop();
|
||||
#endif
|
||||
s_tracing = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t heap_trace_resume(void)
|
||||
{
|
||||
return heap_trace_start(HEAP_TRACE_ALL);
|
||||
}
|
||||
|
||||
size_t heap_trace_get_count(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
esp_err_t heap_trace_get(size_t index, heap_trace_record_t *record)
|
||||
{
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
void heap_trace_dump(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add a new allocation to the heap trace records */
|
||||
static IRAM_ATTR void record_allocation(const heap_trace_record_t *record)
|
||||
{
|
||||
if (!s_tracing) {
|
||||
return;
|
||||
}
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
esp_sysview_heap_trace_alloc(record->address, record->size, record->alloced_by);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* record a free event in the heap trace log
|
||||
|
||||
For HEAP_TRACE_ALL, this means filling in the freed_by pointer.
|
||||
For HEAP_TRACE_LEAKS, this means removing the record from the log.
|
||||
*/
|
||||
static IRAM_ATTR void record_free(void *p, void **callers)
|
||||
{
|
||||
if (!s_tracing) {
|
||||
return;
|
||||
}
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
esp_sysview_heap_trace_free(p, callers);
|
||||
#endif
|
||||
}
|
||||
|
||||
#include "heap_trace.inc"
|
||||
|
||||
#endif /*CONFIG_HEAP_TRACING_TOHOST*/
|
||||
@@ -1,8 +1,16 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
// Copyright 2017 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.
|
||||
//
|
||||
// Hot It Works
|
||||
// ************
|
||||
@@ -17,8 +25,9 @@
|
||||
#include <string.h>
|
||||
#include "esp_app_trace.h"
|
||||
|
||||
#if CONFIG_APPTRACE_ENABLE
|
||||
#if CONFIG_ESP32_APPTRACE_ENABLE
|
||||
|
||||
#define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "esp_host_file_io";
|
||||
|
||||
@@ -136,9 +145,6 @@ void *esp_apptrace_fopen(esp_apptrace_dest_t dest, const char *path, const char
|
||||
esp_apptrace_fopen_args_t cmd_args;
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "esp_apptrace_fopen '%s' '%s'", path, mode);
|
||||
if (path == NULL || mode == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd_args.path = path;
|
||||
cmd_args.path_len = strlen(path) + 1;
|
||||
@@ -207,10 +213,6 @@ size_t esp_apptrace_fwrite(esp_apptrace_dest_t dest, const void *ptr, size_t siz
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "esp_apptrace_fwrite f %p l %d", stream, size*nmemb);
|
||||
|
||||
if (ptr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd_args.buf = (void *)ptr;
|
||||
cmd_args.size = size * nmemb;
|
||||
cmd_args.file = stream;
|
||||
@@ -246,10 +248,6 @@ size_t esp_apptrace_fread(esp_apptrace_dest_t dest, void *ptr, size_t size, size
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "esp_apptrace_fread f %p l %d", stream, size*nmemb);
|
||||
|
||||
if (ptr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd_args.size = size * nmemb;
|
||||
cmd_args.file = stream;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FREAD, esp_apptrace_fread_args_prepare,
|
||||
@@ -281,8 +279,6 @@ static void esp_apptrace_fseek_args_prepare(uint8_t *buf, void *priv)
|
||||
esp_apptrace_fseek_args_t *args = priv;
|
||||
|
||||
memcpy(buf, &args->file, sizeof(args->file));
|
||||
memcpy(buf + sizeof(args->file), &args->offset, sizeof(args->offset));
|
||||
memcpy(buf + sizeof(args->file) + sizeof(args->offset), &args->whence, sizeof(args->whence));
|
||||
}
|
||||
|
||||
int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int whence)
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
// Copyright 2017 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.
|
||||
#ifndef ESP_APP_TRACE_H_
|
||||
#define ESP_APP_TRACE_H_
|
||||
|
||||
@@ -10,19 +18,12 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_app_trace_util.h" // ESP_APPTRACE_TMO_INFINITE
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Application trace data destinations bits.
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_APPTRACE_DEST_JTAG = 1, ///< JTAG destination
|
||||
ESP_APPTRACE_DEST_TRAX = ESP_APPTRACE_DEST_JTAG, ///< xxx_TRAX name is obsolete, use more common xxx_JTAG
|
||||
ESP_APPTRACE_DEST_UART0, ///< UART0 destination
|
||||
ESP_APPTRACE_DEST_MAX = ESP_APPTRACE_DEST_UART0,
|
||||
ESP_APPTRACE_DEST_NUM
|
||||
ESP_APPTRACE_DEST_TRAX = 0x1, ///< JTAG destination
|
||||
ESP_APPTRACE_DEST_UART0 = 0x2, ///< UART destination
|
||||
} esp_apptrace_dest_t;
|
||||
|
||||
/**
|
||||
@@ -32,7 +33,7 @@ typedef enum {
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_apptrace_init(void);
|
||||
esp_err_t esp_apptrace_init();
|
||||
|
||||
/**
|
||||
* @brief Configures down buffer.
|
||||
@@ -50,7 +51,7 @@ void esp_apptrace_down_buffer_config(uint8_t *buf, uint32_t size);
|
||||
*
|
||||
* @param dest Indicates HW interface to send data.
|
||||
* @param size Size of data to write to trace buffer.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return non-NULL on success, otherwise NULL.
|
||||
*/
|
||||
@@ -62,7 +63,7 @@ uint8_t *esp_apptrace_buffer_get(esp_apptrace_dest_t dest, uint32_t size, uint32
|
||||
*
|
||||
* @param dest Indicates HW interface to send data. Should be identical to the same parameter in call to esp_apptrace_buffer_get.
|
||||
* @param ptr Address of trace buffer to release. Should be the value returned by call to esp_apptrace_buffer_get.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@@ -74,7 +75,7 @@ esp_err_t esp_apptrace_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32
|
||||
* @param dest Indicates HW interface to send data.
|
||||
* @param data Address of data to write to trace buffer.
|
||||
* @param size Size of data to write to trace buffer.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@@ -84,7 +85,7 @@ esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_
|
||||
* @brief vprintf-like function to sent log messages to host via specified HW interface.
|
||||
*
|
||||
* @param dest Indicates HW interface to send data.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
* @param fmt Address of format string.
|
||||
* @param ap List of arguments.
|
||||
*
|
||||
@@ -106,7 +107,7 @@ int esp_apptrace_vprintf(const char *fmt, va_list ap);
|
||||
* @brief Flushes remaining data in trace buffer to host.
|
||||
*
|
||||
* @param dest Indicates HW interface to flush data on.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@@ -118,7 +119,7 @@ esp_err_t esp_apptrace_flush(esp_apptrace_dest_t dest, uint32_t tmo);
|
||||
*
|
||||
* @param dest Indicates HW interface to flush data on.
|
||||
* @param min_sz Threshold for flushing data. If current filling level is above this value, data will be flushed. TRAX destinations only.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@@ -130,31 +131,31 @@ esp_err_t esp_apptrace_flush_nolock(esp_apptrace_dest_t dest, uint32_t min_sz, u
|
||||
* @param dest Indicates HW interface to read the data on.
|
||||
* @param data Address of buffer to put data from trace buffer.
|
||||
* @param size Pointer to store size of read data. Before call to this function pointed memory must hold requested size of data
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *data, uint32_t *size, uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Retrieves incoming data buffer if any.
|
||||
* @brief Rertrieves incoming data buffer if any.
|
||||
* After data in buffer are processed esp_apptrace_down_buffer_put must be called to indicate it.
|
||||
*
|
||||
* @param dest Indicates HW interface to receive data.
|
||||
* @param size Address to store size of available data in down buffer. Must be initialized with requested value.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param size Address to store size of available data in down buffer. Must be initializaed with requested value.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return non-NULL on success, otherwise NULL.
|
||||
*/
|
||||
uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size, uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Indicates that the data in down buffer are processed.
|
||||
* @brief Indicates that the data in down buffer are processesd.
|
||||
* This function is a counterpart of and must be preceeded by esp_apptrace_down_buffer_get.
|
||||
*
|
||||
* @param dest Indicates HW interface to receive data. Should be identical to the same parameter in call to esp_apptrace_down_buffer_get.
|
||||
* @param ptr Address of trace buffer to release. Should be the value returned by call to esp_apptrace_down_buffer_get.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@@ -246,7 +247,7 @@ int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream);
|
||||
|
||||
/**
|
||||
* @brief Indicates to the host that all file operations are completed.
|
||||
* This function should be called after all file operations are finished and
|
||||
* This function should be called after all file operations are finished and
|
||||
* indicate to the host that it can perform cleanup operations (close open files etc.).
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
@@ -261,8 +262,4 @@ int esp_apptrace_fstop(esp_apptrace_dest_t dest);
|
||||
*/
|
||||
void esp_gcov_dump(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,31 +1,34 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
// Copyright 2017 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.
|
||||
#ifndef ESP_APP_TRACE_UTIL_H_
|
||||
#define ESP_APP_TRACE_UTIL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_timer.h"
|
||||
|
||||
/** Infinite waiting timeout */
|
||||
#define ESP_APPTRACE_TMO_INFINITE ((uint32_t)-1)
|
||||
|
||||
/** Structure which holds data necessary for measuring time intervals.
|
||||
/** Structure which holds data necessary for measuring time intervals.
|
||||
*
|
||||
* After initialization via esp_apptrace_tmo_init() user needs to call esp_apptrace_tmo_check()
|
||||
* periodically to check timeout for expiration.
|
||||
*/
|
||||
typedef struct {
|
||||
int64_t start; ///< time interval start (in us)
|
||||
int64_t tmo; ///< timeout value (in us)
|
||||
int64_t elapsed; ///< elapsed time (in us)
|
||||
uint32_t start; ///< time interval start (in CPU ticks)
|
||||
uint32_t tmo; ///< timeout value (in us)
|
||||
uint32_t elapsed; ///< elapsed time (in us)
|
||||
} esp_apptrace_tmo_t;
|
||||
|
||||
/**
|
||||
@@ -36,23 +39,22 @@ typedef struct {
|
||||
*/
|
||||
static inline void esp_apptrace_tmo_init(esp_apptrace_tmo_t *tmo, uint32_t user_tmo)
|
||||
{
|
||||
tmo->start = esp_timer_get_time();
|
||||
tmo->tmo = user_tmo == ESP_APPTRACE_TMO_INFINITE ? (int64_t)-1 : (int64_t)user_tmo;
|
||||
tmo->elapsed = 0;
|
||||
tmo->start = portGET_RUN_TIME_COUNTER_VALUE();
|
||||
tmo->tmo = user_tmo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks timeout for expiration.
|
||||
*
|
||||
* @param tmo Pointer to timeout structure.
|
||||
* @param tmo Pointer to timeout structure to be initialized.
|
||||
*
|
||||
* @return number of remaining us till tmo.
|
||||
* @return ESP_OK on success, otherwise \see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_apptrace_tmo_check(esp_apptrace_tmo_t *tmo);
|
||||
|
||||
static inline uint32_t esp_apptrace_tmo_remaining_us(esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
return tmo->tmo != (int64_t)-1 ? (tmo->elapsed - tmo->tmo) : ESP_APPTRACE_TMO_INFINITE;
|
||||
return tmo->tmo != ESP_APPTRACE_TMO_INFINITE ? (tmo->elapsed - tmo->tmo) : ESP_APPTRACE_TMO_INFINITE;
|
||||
}
|
||||
|
||||
/** Tracing module synchronization lock */
|
||||
@@ -93,7 +95,7 @@ esp_err_t esp_apptrace_lock_give(esp_apptrace_lock_t *lock);
|
||||
|
||||
/** Ring buffer control structure.
|
||||
*
|
||||
* @note For purposes of application tracing module if there is no enough space for user data and write pointer can be wrapped
|
||||
* @note For purposes of application tracing module if there is no enough space for user data and write pointer can be wrapped
|
||||
* current ring buffer size can be temporarily shrinked in order to provide buffer with requested size.
|
||||
*/
|
||||
typedef struct {
|
||||
@@ -161,32 +163,4 @@ uint32_t esp_apptrace_rb_read_size_get(esp_apptrace_rb_t *rb);
|
||||
*/
|
||||
uint32_t esp_apptrace_rb_write_size_get(esp_apptrace_rb_t *rb);
|
||||
|
||||
int esp_apptrace_log_lock(void);
|
||||
void esp_apptrace_log_unlock(void);
|
||||
|
||||
#define ESP_APPTRACE_LOG( format, ... ) \
|
||||
do { \
|
||||
esp_apptrace_log_lock(); \
|
||||
esp_rom_printf(format, ##__VA_ARGS__); \
|
||||
esp_apptrace_log_unlock(); \
|
||||
} while(0)
|
||||
|
||||
#define ESP_APPTRACE_LOG_LEV( _L_, level, format, ... ) \
|
||||
do { \
|
||||
if (LOG_LOCAL_LEVEL >= level) { \
|
||||
ESP_APPTRACE_LOG(LOG_FORMAT(_L_, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define ESP_APPTRACE_LOGE( format, ... ) ESP_APPTRACE_LOG_LEV(E, ESP_LOG_ERROR, format, ##__VA_ARGS__)
|
||||
#define ESP_APPTRACE_LOGW( format, ... ) ESP_APPTRACE_LOG_LEV(W, ESP_LOG_WARN, format, ##__VA_ARGS__)
|
||||
#define ESP_APPTRACE_LOGI( format, ... ) ESP_APPTRACE_LOG_LEV(I, ESP_LOG_INFO, format, ##__VA_ARGS__)
|
||||
#define ESP_APPTRACE_LOGD( format, ... ) ESP_APPTRACE_LOG_LEV(D, ESP_LOG_DEBUG, format, ##__VA_ARGS__)
|
||||
#define ESP_APPTRACE_LOGV( format, ... ) ESP_APPTRACE_LOG_LEV(V, ESP_LOG_VERBOSE, format, ##__VA_ARGS__)
|
||||
#define ESP_APPTRACE_LOGO( format, ... ) ESP_APPTRACE_LOG_LEV(E, ESP_LOG_NONE, format, ##__VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //ESP_APP_TRACE_UTIL_H_
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef ESP_SYSVIEW_TRACE_H_
|
||||
#define ESP_SYSVIEW_TRACE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "esp_err.h"
|
||||
#include "SEGGER_RTT.h" // SEGGER_RTT_ESP_Flush
|
||||
#include "esp_app_trace_util.h" // ESP_APPTRACE_TMO_INFINITE
|
||||
|
||||
/**
|
||||
* @brief Flushes remaining data in SystemView trace buffer to host.
|
||||
*
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return ESP_OK.
|
||||
*/
|
||||
static inline esp_err_t esp_sysview_flush(uint32_t tmo)
|
||||
{
|
||||
SEGGER_RTT_ESP_Flush(0, tmo);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief vprintf-like function to sent log messages to the host.
|
||||
*
|
||||
* @param format Address of format string.
|
||||
* @param args List of arguments.
|
||||
*
|
||||
* @return Number of bytes written.
|
||||
*/
|
||||
int esp_sysview_vprintf(const char * format, va_list args);
|
||||
|
||||
/**
|
||||
* @brief Starts SystemView heap tracing.
|
||||
*
|
||||
* @param tmo Timeout (in us) to wait for the host to be connected. Use -1 to wait forever.
|
||||
*
|
||||
* @return ESP_OK on success, ESP_ERR_TIMEOUT if operation has been timed out.
|
||||
*/
|
||||
esp_err_t esp_sysview_heap_trace_start(uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Stops SystemView heap tracing.
|
||||
*
|
||||
* @return ESP_OK.
|
||||
*/
|
||||
esp_err_t esp_sysview_heap_trace_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Sends heap allocation event to the host.
|
||||
*
|
||||
* @param addr Address of allocated block.
|
||||
* @param size Size of allocated block.
|
||||
* @param callers Pointer to array with callstack addresses.
|
||||
* Array size must be CONFIG_HEAP_TRACING_STACK_DEPTH.
|
||||
*/
|
||||
void esp_sysview_heap_trace_alloc(void *addr, uint32_t size, const void *callers);
|
||||
|
||||
/**
|
||||
* @brief Sends heap de-allocation event to the host.
|
||||
*
|
||||
* @param addr Address of de-allocated block.
|
||||
* @param callers Pointer to array with callstack addresses.
|
||||
* Array size must be CONFIG_HEAP_TRACING_STACK_DEPTH.
|
||||
*/
|
||||
void esp_sysview_heap_trace_free(void *addr, const void *callers);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //ESP_SYSVIEW_TRACE_H_
|
||||
@@ -1,19 +0,0 @@
|
||||
[mapping:app_trace]
|
||||
archive: libapp_trace.a
|
||||
entries:
|
||||
app_trace (noflash)
|
||||
app_trace_util (noflash)
|
||||
if APPTRACE_SV_ENABLE = y:
|
||||
SEGGER_SYSVIEW (noflash)
|
||||
SEGGER_RTT_esp (noflash)
|
||||
SEGGER_SYSVIEW_Config_FreeRTOS (noflash)
|
||||
SEGGER_SYSVIEW_FreeRTOS (noflash)
|
||||
|
||||
[mapping:app_trace_driver]
|
||||
archive: libdriver.a
|
||||
entries:
|
||||
if APPTRACE_SV_TS_SOURCE_TIMER_00 = y || APPTRACE_SV_TS_SOURCE_TIMER_01 = y
|
||||
|| APPTRACE_SV_TS_SOURCE_TIMER_10 = y || APPTRACE_SV_TS_SOURCE_TIMER_11 = y:
|
||||
timer (noflash)
|
||||
else:
|
||||
* (default)
|
||||
@@ -1,43 +0,0 @@
|
||||
// Copyright 2020 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.
|
||||
#ifndef ESP_APP_TRACE_PORT_H_
|
||||
#define ESP_APP_TRACE_PORT_H_
|
||||
|
||||
#include "esp_app_trace_util.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Apptrace HW interface. */
|
||||
typedef struct {
|
||||
esp_err_t (*init)(void *hw_data);
|
||||
uint8_t *(*get_up_buffer)(void *hw_data, uint32_t, esp_apptrace_tmo_t *);
|
||||
esp_err_t (*put_up_buffer)(void *hw_data, uint8_t *, esp_apptrace_tmo_t *);
|
||||
esp_err_t (*flush_up_buffer_nolock)(void *hw_data, uint32_t, esp_apptrace_tmo_t *);
|
||||
esp_err_t (*flush_up_buffer)(void *hw_data, esp_apptrace_tmo_t *);
|
||||
void (*down_buffer_config)(void *hw_data, uint8_t *buf, uint32_t size);
|
||||
uint8_t *(*get_down_buffer)(void *hw_data, uint32_t *, esp_apptrace_tmo_t *);
|
||||
esp_err_t (*put_down_buffer)(void *hw_data, uint8_t *, esp_apptrace_tmo_t *);
|
||||
bool (*host_is_connected)(void *hw_data);
|
||||
} esp_apptrace_hw_t;
|
||||
|
||||
esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data);
|
||||
esp_apptrace_hw_t *esp_apptrace_uart_hw_get(int num, void **data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,374 +0,0 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_app_trace_membufs_proto.h"
|
||||
#include "esp_app_trace_port.h"
|
||||
|
||||
/** RISCV HW transport data */
|
||||
typedef struct {
|
||||
uint8_t inited; // initialization state flags for every core
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
esp_apptrace_lock_t lock; // sync lock
|
||||
#endif
|
||||
esp_apptrace_membufs_proto_data_t membufs;
|
||||
} esp_apptrace_riscv_data_t;
|
||||
|
||||
/** RISCV memory host iface control block */
|
||||
typedef struct {
|
||||
uint32_t ctrl;
|
||||
// - Guard field. If this register is not zero then CPU is changing this struct and
|
||||
// this guard field holds address of the instruction which application will execute when CPU finishes with those modifications.
|
||||
uint32_t stat;
|
||||
esp_apptrace_mem_block_t * mem_blocks;
|
||||
} esp_apptrace_riscv_ctrl_block_t;
|
||||
|
||||
#define RISCV_APPTRACE_SYSNR 0x64
|
||||
|
||||
#define ESP_APPTRACE_RISCV_BLOCK_LEN_MSK 0x7FFFUL
|
||||
#define ESP_APPTRACE_RISCV_BLOCK_LEN(_l_) ((_l_) & ESP_APPTRACE_RISCV_BLOCK_LEN_MSK)
|
||||
#define ESP_APPTRACE_RISCV_BLOCK_LEN_GET(_v_) ((_v_) & ESP_APPTRACE_RISCV_BLOCK_LEN_MSK)
|
||||
#define ESP_APPTRACE_RISCV_BLOCK_ID_MSK 0x7FUL
|
||||
#define ESP_APPTRACE_RISCV_BLOCK_ID(_id_) (((_id_) & ESP_APPTRACE_RISCV_BLOCK_ID_MSK) << 15)
|
||||
#define ESP_APPTRACE_RISCV_BLOCK_ID_GET(_v_) (((_v_) >> 15) & ESP_APPTRACE_RISCV_BLOCK_ID_MSK)
|
||||
#define ESP_APPTRACE_RISCV_HOST_DATA (1 << 22)
|
||||
#define ESP_APPTRACE_RISCV_HOST_CONNECT (1 << 23)
|
||||
|
||||
#define ESP_APPTRACE_RISCV_INITED(_hw_) ((_hw_)->inited & (1 << 0/*cpu_hal_get_core_id()*/))
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_init(esp_apptrace_riscv_data_t *hw_data);
|
||||
static esp_err_t esp_apptrace_riscv_flush(esp_apptrace_riscv_data_t *hw_data, esp_apptrace_tmo_t *tmo);
|
||||
static esp_err_t esp_apptrace_riscv_flush_nolock(esp_apptrace_riscv_data_t *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo);
|
||||
static uint8_t *esp_apptrace_riscv_up_buffer_get(esp_apptrace_riscv_data_t *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo);
|
||||
static esp_err_t esp_apptrace_riscv_up_buffer_put(esp_apptrace_riscv_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo);
|
||||
static void esp_apptrace_riscv_down_buffer_config(esp_apptrace_riscv_data_t *hw_data, uint8_t *buf, uint32_t size);
|
||||
static uint8_t *esp_apptrace_riscv_down_buffer_get(esp_apptrace_riscv_data_t *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo);
|
||||
static esp_err_t esp_apptrace_riscv_down_buffer_put(esp_apptrace_riscv_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo);
|
||||
static bool esp_apptrace_riscv_host_is_connected(esp_apptrace_riscv_data_t *hw_data);
|
||||
static esp_err_t esp_apptrace_riscv_buffer_swap_start(uint32_t curr_block_id);
|
||||
static esp_err_t esp_apptrace_riscv_buffer_swap(uint32_t new_block_id);
|
||||
static esp_err_t esp_apptrace_riscv_buffer_swap_end(uint32_t new_block_id, uint32_t prev_block_len);
|
||||
static bool esp_apptrace_riscv_host_data_pending(void);
|
||||
|
||||
|
||||
const static char *TAG = "esp_apptrace";
|
||||
|
||||
static esp_apptrace_riscv_ctrl_block_t s_tracing_ctrl[portNUM_PROCESSORS];
|
||||
|
||||
esp_apptrace_hw_t *esp_apptrace_uart_hw_get(int num, void **data)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data)
|
||||
{
|
||||
#if CONFIG_APPTRACE_DEST_JTAG
|
||||
static esp_apptrace_membufs_proto_hw_t s_trace_proto_hw = {
|
||||
.swap_start = esp_apptrace_riscv_buffer_swap_start,
|
||||
.swap = esp_apptrace_riscv_buffer_swap,
|
||||
.swap_end = esp_apptrace_riscv_buffer_swap_end,
|
||||
.host_data_pending = esp_apptrace_riscv_host_data_pending,
|
||||
};
|
||||
static esp_apptrace_riscv_data_t s_trace_hw_data = {
|
||||
.membufs = {
|
||||
.hw = &s_trace_proto_hw,
|
||||
},
|
||||
};
|
||||
static esp_apptrace_hw_t s_trace_hw = {
|
||||
.init = (esp_err_t (*)(void *))esp_apptrace_riscv_init,
|
||||
.get_up_buffer = (uint8_t *(*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_riscv_up_buffer_get,
|
||||
.put_up_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_up_buffer_put,
|
||||
.flush_up_buffer_nolock = (esp_err_t (*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_riscv_flush_nolock,
|
||||
.flush_up_buffer = (esp_err_t (*)(void *, esp_apptrace_tmo_t *))esp_apptrace_riscv_flush,
|
||||
.down_buffer_config = (void (*)(void *, uint8_t *, uint32_t ))esp_apptrace_riscv_down_buffer_config,
|
||||
.get_down_buffer = (uint8_t *(*)(void *, uint32_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_down_buffer_get,
|
||||
.put_down_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_riscv_down_buffer_put,
|
||||
.host_is_connected = (bool (*)(void *))esp_apptrace_riscv_host_is_connected,
|
||||
};
|
||||
*data = &s_trace_hw_data;
|
||||
return &s_trace_hw;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Advertises apptrace control block address to host.
|
||||
This function can be overriden with custom implementation,
|
||||
e.g. OpenOCD flasher stub use own implementation of it. */
|
||||
__attribute__((weak)) int esp_apptrace_advertise_ctrl_block(void *ctrl_block_addr)
|
||||
{
|
||||
register int sys_nr = RISCV_APPTRACE_SYSNR;
|
||||
register int host_ret = 0;
|
||||
|
||||
if (!esp_cpu_in_ocd_debug_mode()) {
|
||||
return 0;
|
||||
}
|
||||
__asm__ volatile ( \
|
||||
".option push\n" \
|
||||
".option norvc\n" \
|
||||
"mv a0, %[sys_nr]\n" \
|
||||
"mv a1, %[arg1]\n" \
|
||||
"slli zero,zero,0x1f\n" \
|
||||
"ebreak\n" \
|
||||
"srai zero,zero,0x7\n" \
|
||||
"mv %[host_ret], a0\n" \
|
||||
".option pop\n" \
|
||||
:[host_ret]"=r"(host_ret)
|
||||
:[sys_nr]"r"(sys_nr),[arg1]"r"(ctrl_block_addr):"a0","a1");
|
||||
return host_ret;
|
||||
}
|
||||
|
||||
/* Returns up buffers config.
|
||||
This function can be overriden with custom implementation,
|
||||
e.g. OpenOCD flasher stub use own implementation of it. */
|
||||
__attribute__((weak)) void esp_apptrace_get_up_buffers(esp_apptrace_mem_block_t mem_blocks_cfg[2])
|
||||
{
|
||||
static uint8_t s_mem_blocks[2][CONFIG_APPTRACE_BUF_SIZE];
|
||||
|
||||
mem_blocks_cfg[0].start = s_mem_blocks[0];
|
||||
mem_blocks_cfg[0].sz = CONFIG_APPTRACE_BUF_SIZE;
|
||||
mem_blocks_cfg[1].start = s_mem_blocks[1];
|
||||
mem_blocks_cfg[1].sz = CONFIG_APPTRACE_BUF_SIZE;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_lock(esp_apptrace_riscv_data_t *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
esp_err_t ret = esp_apptrace_lock_take(&hw_data->lock, tmo);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_unlock(esp_apptrace_riscv_data_t *hw_data)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
ret = esp_apptrace_lock_give(&hw_data->lock);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************************/
|
||||
/***************************** Apptrace HW iface *****************************************/
|
||||
/*****************************************************************************************/
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_init(esp_apptrace_riscv_data_t *hw_data)
|
||||
{
|
||||
int core_id = cpu_hal_get_core_id();
|
||||
|
||||
if (hw_data->inited == 0) {
|
||||
esp_apptrace_mem_block_t mem_blocks_cfg[2];
|
||||
esp_apptrace_get_up_buffers(mem_blocks_cfg);
|
||||
esp_err_t res = esp_apptrace_membufs_init(&hw_data->membufs, mem_blocks_cfg);
|
||||
if (res != ESP_OK) {
|
||||
ESP_APPTRACE_LOGE("Failed to init membufs proto (%d)!", res);
|
||||
return res;
|
||||
}
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
esp_apptrace_lock_init(&hw_data->lock);
|
||||
#endif
|
||||
}
|
||||
hw_data->inited |= 1 << core_id;
|
||||
ESP_APPTRACE_LOGI("Apptrace initialized on CPU%d. Tracing control block @ %p.", core_id, &s_tracing_ctrl[core_id]);
|
||||
s_tracing_ctrl[core_id].mem_blocks = hw_data->membufs.blocks;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ESP_APPTRACE_LOGD("Mem buf[%d] %d bytes @ %p (%p/%p)", i,
|
||||
s_tracing_ctrl[core_id].mem_blocks[i].sz, s_tracing_ctrl[core_id].mem_blocks[i].start,
|
||||
&(s_tracing_ctrl[core_id].mem_blocks[i].start), &(s_tracing_ctrl[core_id].mem_blocks[i].sz));
|
||||
}
|
||||
// notify host about control block address
|
||||
int res = esp_apptrace_advertise_ctrl_block(&s_tracing_ctrl[core_id]);
|
||||
assert(res == 0 && "Falied to send config to host!");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static uint8_t *esp_apptrace_riscv_up_buffer_get(esp_apptrace_riscv_data_t *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
return NULL;
|
||||
}
|
||||
esp_err_t res = esp_apptrace_riscv_lock(hw_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = esp_apptrace_membufs_up_buffer_get(&hw_data->membufs, size, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
if (esp_apptrace_riscv_unlock(hw_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_up_buffer_put(esp_apptrace_riscv_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
// Can avoid locking because esp_apptrace_membufs_up_buffer_put() just modifies buffer's header
|
||||
esp_err_t res = esp_apptrace_membufs_up_buffer_put(&hw_data->membufs, ptr, tmo);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void esp_apptrace_riscv_down_buffer_config(esp_apptrace_riscv_data_t *hw_data, uint8_t *buf, uint32_t size)
|
||||
{
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
return;
|
||||
}
|
||||
esp_apptrace_membufs_down_buffer_config(&hw_data->membufs, buf, size);
|
||||
}
|
||||
|
||||
static uint8_t *esp_apptrace_riscv_down_buffer_get(esp_apptrace_riscv_data_t *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
return NULL;
|
||||
}
|
||||
esp_err_t res = esp_apptrace_riscv_lock(hw_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = esp_apptrace_membufs_down_buffer_get(&hw_data->membufs, size, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
if (esp_apptrace_riscv_unlock(hw_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_down_buffer_put(esp_apptrace_riscv_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
// Can avoid locking because esp_apptrace_membufs_down_buffer_put() does nothing
|
||||
/*esp_err_t res = esp_apptrace_riscv_lock(hw_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return res;
|
||||
}*/
|
||||
|
||||
esp_err_t res = esp_apptrace_membufs_down_buffer_put(&hw_data->membufs, ptr, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
/*if (esp_apptrace_riscv_unlock(hw_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}*/
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool esp_apptrace_riscv_host_is_connected(esp_apptrace_riscv_data_t *hw_data)
|
||||
{
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
return false;
|
||||
}
|
||||
return s_tracing_ctrl[cpu_hal_get_core_id()].ctrl & ESP_APPTRACE_RISCV_HOST_CONNECT ? true : false;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_flush_nolock(esp_apptrace_riscv_data_t *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
return esp_apptrace_membufs_flush_nolock(&hw_data->membufs, min_sz, tmo);
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_flush(esp_apptrace_riscv_data_t *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_RISCV_INITED(hw_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
esp_err_t res = esp_apptrace_riscv_lock(hw_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = esp_apptrace_membufs_flush_nolock(&hw_data->membufs, 0, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
if (esp_apptrace_riscv_unlock(hw_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*****************************************************************************************/
|
||||
/************************** Membufs proto HW iface ***************************************/
|
||||
/*****************************************************************************************/
|
||||
|
||||
static inline void esp_apptrace_riscv_buffer_swap_lock(void)
|
||||
{
|
||||
extern uint32_t __esp_apptrace_riscv_updated;
|
||||
|
||||
// indicate to host that we are about to update.
|
||||
// this is used only to place CPU into streaming mode at tracing startup
|
||||
// before starting streaming host can halt us after we read ESP_APPTRACE_RISCV_CTRL_REG and before we updated it
|
||||
// HACK: in this case host will set breakpoint just after ESP_APPTRACE_RISCV_CTRL_REG update,
|
||||
// here we set address to set bp at
|
||||
// enter ERI update critical section
|
||||
s_tracing_ctrl[cpu_hal_get_core_id()].stat = (uint32_t)&__esp_apptrace_riscv_updated;
|
||||
}
|
||||
|
||||
static __attribute__((noinline)) void esp_apptrace_riscv_buffer_swap_unlock(void)
|
||||
{
|
||||
// exit ERI update critical section
|
||||
s_tracing_ctrl[cpu_hal_get_core_id()].stat = 0;
|
||||
// TODO: currently host sets breakpoint, use break instruction to stop;
|
||||
// it will allow to use ESP_APPTRACE_RISCV_STAT_REG for other purposes
|
||||
asm volatile (
|
||||
" .global __esp_apptrace_riscv_updated\n"
|
||||
"__esp_apptrace_riscv_updated:\n"); // host will set bp here to resolve collision at streaming start
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_buffer_swap_start(uint32_t curr_block_id)
|
||||
{
|
||||
esp_err_t res = ESP_OK;
|
||||
|
||||
esp_apptrace_riscv_buffer_swap_lock();
|
||||
|
||||
uint32_t ctrl_reg = s_tracing_ctrl[cpu_hal_get_core_id()].ctrl;
|
||||
uint32_t host_connected = ESP_APPTRACE_RISCV_HOST_CONNECT & ctrl_reg;
|
||||
if (host_connected) {
|
||||
uint32_t acked_block = ESP_APPTRACE_RISCV_BLOCK_ID_GET(ctrl_reg);
|
||||
uint32_t host_to_read = ESP_APPTRACE_RISCV_BLOCK_LEN_GET(ctrl_reg);
|
||||
if (host_to_read != 0 || acked_block != (curr_block_id & ESP_APPTRACE_RISCV_BLOCK_ID_MSK)) {
|
||||
ESP_APPTRACE_LOGD("[%d]: Can not switch %x %d %x %x/%lx", cpu_hal_get_core_id(), ctrl_reg, host_to_read, acked_block,
|
||||
curr_block_id & ESP_APPTRACE_RISCV_BLOCK_ID_MSK, curr_block_id);
|
||||
res = ESP_ERR_NO_MEM;
|
||||
goto _on_err;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
_on_err:
|
||||
esp_apptrace_riscv_buffer_swap_unlock();
|
||||
return res;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_buffer_swap_end(uint32_t new_block_id, uint32_t prev_block_len)
|
||||
{
|
||||
uint32_t ctrl_reg = s_tracing_ctrl[cpu_hal_get_core_id()].ctrl;
|
||||
uint32_t host_connected = ESP_APPTRACE_RISCV_HOST_CONNECT & ctrl_reg;
|
||||
s_tracing_ctrl[cpu_hal_get_core_id()].ctrl = ESP_APPTRACE_RISCV_BLOCK_ID(new_block_id) |
|
||||
host_connected | ESP_APPTRACE_RISCV_BLOCK_LEN(prev_block_len);
|
||||
esp_apptrace_riscv_buffer_swap_unlock();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_riscv_buffer_swap(uint32_t new_block_id)
|
||||
{
|
||||
/* do nothing */
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static bool esp_apptrace_riscv_host_data_pending(void)
|
||||
{
|
||||
uint32_t ctrl_reg = s_tracing_ctrl[cpu_hal_get_core_id()].ctrl;
|
||||
// ESP_APPTRACE_LOGV("%s() 0x%x", __func__, ctrl_reg);
|
||||
return (ctrl_reg & ESP_APPTRACE_RISCV_HOST_DATA) ? true : false;
|
||||
}
|
||||
@@ -1,543 +0,0 @@
|
||||
//
|
||||
// How It Works
|
||||
// ************
|
||||
|
||||
// 1. Components Overview
|
||||
// ======================
|
||||
|
||||
// Xtensa has useful feature: TRAX debug module. It allows recording program execution flow at run-time without disturbing CPU.
|
||||
// Exectution flow data are written to configurable Trace RAM block. Besides accessing Trace RAM itself TRAX module also allows to read/write
|
||||
// trace memory via its registers by means of JTAG, APB or ERI transactions.
|
||||
// ESP32 has two Xtensa cores with separate TRAX modules on them and provides two special memory regions to be used as trace memory.
|
||||
// Chip allows muxing access to those trace memory blocks in such a way that while one block is accessed by CPUs another one can be accessed by host
|
||||
// by means of reading/writing TRAX registers via JTAG. Blocks muxing is configurable at run-time and allows switching trace memory blocks between
|
||||
// accessors in round-robin fashion so they can read/write separate memory blocks without disturbing each other.
|
||||
// This module implements application tracing feature based on above mechanisms. It allows to transfer arbitrary user data to/from
|
||||
// host via JTAG with minimal impact on system performance. This module is implied to be used in the following tracing scheme.
|
||||
|
||||
// ------>------ ----- (host components) -----
|
||||
// | | | |
|
||||
// ------------------- ----------------------- ----------------------- ---------------- ------ --------- -----------------
|
||||
// |trace data source|-->|target tracing module|<--->|TRAX_MEM0 | TRAX_MEM1|---->|TRAX_DATA_REGS|<-->|JTAG|<--->|OpenOCD|-->|trace data sink|
|
||||
// ------------------- ----------------------- ----------------------- ---------------- ------ --------- -----------------
|
||||
// | | | |
|
||||
// | ------<------ ---------------- |
|
||||
// |<------------------------------------------->|TRAX_CTRL_REGS|<---->|
|
||||
// ----------------
|
||||
|
||||
// In general tracing goes in the following way. User application requests tracing module to send some data by calling esp_apptrace_buffer_get(),
|
||||
// module allocates necessary buffer in current input trace block. Then user fills received buffer with data and calls esp_apptrace_buffer_put().
|
||||
// When current input trace block is filled with app data it is exposed to host and the second block becomes input one and buffer filling restarts.
|
||||
// While target application fills one TRAX block host reads another one via JTAG.
|
||||
// This module also allows communication in the opposite direction: from host to target. As it was said ESP32 and host can access different TRAX blocks
|
||||
// simultaneously, so while target writes trace data to one block host can write its own data (e.g. tracing commands) to another one then when
|
||||
// blocks are switched host receives trace data and target receives data written by host application. Target user application can read host data
|
||||
// by calling esp_apptrace_read() API.
|
||||
// To control buffer switching and for other communication purposes this implementation uses some TRAX registers. It is safe since HW TRAX tracing
|
||||
// can not be used along with application tracing feature so these registers are freely readable/writeable via JTAG from host and via ERI from ESP32 cores.
|
||||
// Overhead of this implementation on target CPU is produced only by allocating/managing buffers and copying of data.
|
||||
// On the host side special OpenOCD command must be used to read trace data.
|
||||
|
||||
// 2. TRAX Registers layout
|
||||
// ========================
|
||||
|
||||
// This module uses two TRAX HW registers to communicate with host SW (OpenOCD).
|
||||
// - Control register uses TRAX_DELAYCNT as storage. Only lower 24 bits of TRAX_DELAYCNT are writable. Control register has the following bitfields:
|
||||
// | 31..XXXXXX..24 | 23 .(host_connect). 23| 22..(block_id)..15 | 14..(block_len)..0 |
|
||||
// 14..0 bits - actual length of user data in trace memory block. Target updates it every time it fills memory block and exposes it to host.
|
||||
// Host writes zero to this field when it finishes reading exposed block;
|
||||
// 21..15 bits - trace memory block transfer ID. Block counter. It can overflow. Updated by target, host should not modify it. Actually can be 2 bits;
|
||||
// 22 bit - 'host data present' flag. If set to one there is data from host, otherwise - no host data;
|
||||
// 23 bit - 'host connected' flag. If zero then host is not connected and tracing module works in post-mortem mode, otherwise in streaming mode;
|
||||
// - Status register uses TRAX_TRIGGERPC as storage. If this register is not zero then current CPU is changing TRAX registers and
|
||||
// this register holds address of the instruction which application will execute when it finishes with those registers modifications.
|
||||
// See 'Targets Connection' setion for details.
|
||||
|
||||
// 3. Modes of operation
|
||||
// =====================
|
||||
|
||||
// This module supports two modes of operation:
|
||||
// - Post-mortem mode. This is the default mode. In this mode application tracing module does not check whether host has read all the data from block
|
||||
// exposed to it and switches block in any case. The mode does not need host interaction for operation and so can be useful when only the latest
|
||||
// trace data are necessary, e.g. for analyzing crashes. On panic the latest data from current input block are exposed to host and host can read them.
|
||||
// It can happen that system panic occurs when there are very small amount of data which are not exposed to host yet (e.g. crash just after the
|
||||
// TRAX block switch). In this case the previous 16KB of collected data will be dropped and host will see the latest, but very small piece of trace.
|
||||
// It can be insufficient to diagnose the problem. To avoid such situations there is menuconfig option
|
||||
// CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH
|
||||
// which controls the threshold for flushing data in case of panic.
|
||||
// - Streaming mode. Tracing module enters this mode when host connects to target and sets respective bits in control registers (per core).
|
||||
// In this mode before switching the block tracing module waits for the host to read all the data from the previously exposed block.
|
||||
// On panic tracing module also waits (timeout is configured via menuconfig via CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO) for the host to read all data.
|
||||
|
||||
// 4. Communication Protocol
|
||||
// =========================
|
||||
|
||||
// 4.1 Trace Memory Blocks
|
||||
// -----------------------
|
||||
|
||||
// Communication is controlled via special register. Host periodically polls control register on each core to find out if there are any data available.
|
||||
// When current input memory block is filled it is exposed to host and 'block_len' and 'block_id' fields are updated in the control register.
|
||||
// Host reads new register value and according to it's value starts reading data from exposed block. Meanwhile target starts filling another trace block.
|
||||
// When host finishes reading the block it clears 'block_len' field in control register indicating to the target that it is ready to accept the next one.
|
||||
// If the host has some data to transfer to the target it writes them to trace memory block before clearing 'block_len' field. Then it sets
|
||||
// 'host_data_present' bit and clears 'block_len' field in control register. Upon every block switch target checks 'host_data_present' bit and if it is set
|
||||
// reads them to down buffer before writing any trace data to switched TRAX block.
|
||||
|
||||
// 4.2 User Data Chunks Level
|
||||
// --------------------------
|
||||
|
||||
// Since trace memory block is shared between user data chunks and data copying is performed on behalf of the API user (in its normal context) in
|
||||
// multithreading environment it can happen that task/ISR which copies data is preempted by another high prio task/ISR. So it is possible situation
|
||||
// that task/ISR will fail to complete filling its data chunk before the whole trace block is exposed to the host. To handle such conditions tracing
|
||||
// module prepends all user data chunks with header which contains allocated buffer size and actual data length within it. OpenOCD command
|
||||
// which reads application traces reports error when it reads incomplete user data block.
|
||||
// Data which are transffered from host to target are also prepended with a header. Down channel data header is simple and consists of one two bytes field
|
||||
// containing length of host data following the header.
|
||||
|
||||
// 4.3 Data Buffering
|
||||
// ------------------
|
||||
|
||||
// It takes some time for the host to read TRAX memory block via JTAG. In streaming mode it can happen that target has filled its TRAX block, but host
|
||||
// has not completed reading of the previous one yet. So in this case time critical tracing calls (which can not be delayed for too long time due to
|
||||
// the lack of free memory in TRAX block) can be dropped. To avoid such scenarios tracing module implements data buffering. Buffered data will be sent
|
||||
// to the host later when TRAX block switch occurs. The maximum size of the buffered data is controlled by menuconfig option
|
||||
// CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX.
|
||||
|
||||
// 4.4 Target Connection/Disconnection
|
||||
// -----------------------------------
|
||||
|
||||
// When host is going to start tracing in streaming mode it needs to put both ESP32 cores into initial state when 'host connected' bit is set
|
||||
// on both cores. To accomplish this host halts both cores and sets this bit in TRAX registers. But target code can be halted in state when it has read control
|
||||
// register but has not updated its value. To handle such situations target code indicates to the host that it is updating control register by writing
|
||||
// non-zero value to status register. Actually it writes address of the instruction which it will execute when it finishes with
|
||||
// the registers update. When target is halted during control register update host sets breakpoint at the address from status register and resumes CPU.
|
||||
// After target code finishes with register update it is halted on breakpoint, host detects it and safely sets 'host connected' bit. When both cores
|
||||
// are set up they are resumed. Tracing starts without further intrusion into CPUs work.
|
||||
// When host is going to stop tracing in streaming mode it needs to disconnect targets. Disconnection process is done using the same algorithm
|
||||
// as for connecting, but 'host connected' bits are cleared on ESP32 cores.
|
||||
|
||||
// 5. Module Access Synchronization
|
||||
// ================================
|
||||
|
||||
// Access to internal module's data is synchronized with custom mutex. Mutex is a wrapper for portMUX_TYPE and uses almost the same sync mechanism as in
|
||||
// vPortCPUAcquireMutex/vPortCPUReleaseMutex. The mechanism uses S32C1I Xtensa instruction to implement exclusive access to module's data from tasks and
|
||||
// ISRs running on both cores. Also custom mutex allows specifying timeout for locking operation. Locking routine checks underlaying mutex in cycle until
|
||||
// it gets its ownership or timeout expires. The differences of application tracing module's mutex implementation from vPortCPUAcquireMutex/vPortCPUReleaseMutex are:
|
||||
// - Support for timeouts.
|
||||
// - Local IRQs for CPU which owns the mutex are disabled till the call to unlocking routine. This is made to avoid possible task's prio inversion.
|
||||
// When low prio task takes mutex and enables local IRQs gets preempted by high prio task which in its turn can try to acquire mutex using infinite timeout.
|
||||
// So no local task switch occurs when mutex is locked. But this does not apply to tasks on another CPU.
|
||||
// WARNING: Priority inversion can happen when low prio task works on one CPU and medium and high prio tasks work on another.
|
||||
// WARNING: Care must be taken when selecting timeout values for trace calls from ISRs. Tracing module does not care about watchdogs when waiting
|
||||
// on internal locks and for host to complete previous block reading, so if timeout value exceeds watchdog's one it can lead to the system reboot.
|
||||
|
||||
// 6. Timeouts
|
||||
// ===========
|
||||
|
||||
// Timeout mechanism is based on xthal_get_ccount() routine and supports timeout values in microseconds.
|
||||
// There are two situations when task/ISR can be delayed by tracing API call. Timeout mechanism takes into account both conditions:
|
||||
// - Trace data are locked by another task/ISR. When wating on trace data lock.
|
||||
// - Current TRAX memory input block is full when working in streaming mode (host is connected). When waiting for host to complete previous block reading.
|
||||
// When wating for any of above conditions xthal_get_ccount() is called periodically to calculate time elapsed from trace API routine entry. When elapsed
|
||||
// time exceeds specified timeout value operation is canceled and ESP_ERR_TIMEOUT code is returned.
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/dport_access.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "soc/dport_reg.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "soc/sensitive_reg.h"
|
||||
#endif
|
||||
#include "eri.h"
|
||||
#include "trax.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_app_trace_membufs_proto.h"
|
||||
#include "esp_app_trace_port.h"
|
||||
|
||||
// TODO: move these (and same definitions in trax.c to dport_reg.h)
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define TRACEMEM_MUX_PROBLK0_APPBLK1 0
|
||||
#define TRACEMEM_MUX_BLK0_ONLY 1
|
||||
#define TRACEMEM_MUX_BLK1_ONLY 2
|
||||
#define TRACEMEM_MUX_PROBLK1_APPBLK0 3
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#define TRACEMEM_MUX_BLK0_NUM 19
|
||||
#define TRACEMEM_MUX_BLK1_NUM 20
|
||||
#define TRACEMEM_BLK_NUM2ADDR(_n_) (0x3FFB8000UL + 0x4000UL*((_n_)-4))
|
||||
#endif
|
||||
|
||||
// TRAX is disabled, so we use its registers for our own purposes
|
||||
// | 31..XXXXXX..24 | 23 .(host_connect). 23 | 22 .(host_data). 22| 21..(block_id)..15 | 14..(block_len)..0 |
|
||||
#define ESP_APPTRACE_TRAX_CTRL_REG ERI_TRAX_DELAYCNT
|
||||
#define ESP_APPTRACE_TRAX_STAT_REG ERI_TRAX_TRIGGERPC
|
||||
|
||||
#define ESP_APPTRACE_TRAX_BLOCK_LEN_MSK 0x7FFFUL
|
||||
#define ESP_APPTRACE_TRAX_BLOCK_LEN(_l_) ((_l_) & ESP_APPTRACE_TRAX_BLOCK_LEN_MSK)
|
||||
#define ESP_APPTRACE_TRAX_BLOCK_LEN_GET(_v_) ((_v_) & ESP_APPTRACE_TRAX_BLOCK_LEN_MSK)
|
||||
#define ESP_APPTRACE_TRAX_BLOCK_ID_MSK 0x7FUL
|
||||
#define ESP_APPTRACE_TRAX_BLOCK_ID(_id_) (((_id_) & ESP_APPTRACE_TRAX_BLOCK_ID_MSK) << 15)
|
||||
#define ESP_APPTRACE_TRAX_BLOCK_ID_GET(_v_) (((_v_) >> 15) & ESP_APPTRACE_TRAX_BLOCK_ID_MSK)
|
||||
#define ESP_APPTRACE_TRAX_HOST_DATA (1 << 22)
|
||||
#define ESP_APPTRACE_TRAX_HOST_CONNECT (1 << 23)
|
||||
|
||||
#define ESP_APPTRACE_TRAX_INITED(_hw_) ((_hw_)->inited & (1 << cpu_hal_get_core_id()))
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
static uint8_t * const s_trax_blocks[] = {
|
||||
(uint8_t *) 0x3FFFC000,
|
||||
(uint8_t *) 0x3FFF8000
|
||||
};
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
static uint8_t * const s_trax_blocks[] = {
|
||||
(uint8_t *)TRACEMEM_BLK_NUM2ADDR(TRACEMEM_MUX_BLK0_NUM),
|
||||
(uint8_t *)TRACEMEM_BLK_NUM2ADDR(TRACEMEM_MUX_BLK1_NUM)
|
||||
};
|
||||
#endif
|
||||
|
||||
#define ESP_APPTRACE_TRAX_BLOCK_SIZE (0x4000UL)
|
||||
|
||||
/** TRAX HW transport data */
|
||||
typedef struct {
|
||||
uint8_t inited;
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
esp_apptrace_lock_t lock; // sync lock
|
||||
#endif
|
||||
esp_apptrace_membufs_proto_data_t membufs;
|
||||
} esp_apptrace_trax_data_t;
|
||||
|
||||
|
||||
static esp_err_t esp_apptrace_trax_init(esp_apptrace_trax_data_t *hw_data);
|
||||
static esp_err_t esp_apptrace_trax_flush(esp_apptrace_trax_data_t *hw_data, esp_apptrace_tmo_t *tmo);
|
||||
static esp_err_t esp_apptrace_trax_flush_nolock(esp_apptrace_trax_data_t *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo);
|
||||
static uint8_t *esp_apptrace_trax_up_buffer_get(esp_apptrace_trax_data_t *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo);
|
||||
static esp_err_t esp_apptrace_trax_up_buffer_put(esp_apptrace_trax_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo);
|
||||
static void esp_apptrace_trax_down_buffer_config(esp_apptrace_trax_data_t *hw_data, uint8_t *buf, uint32_t size);
|
||||
static uint8_t *esp_apptrace_trax_down_buffer_get(esp_apptrace_trax_data_t *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo);
|
||||
static esp_err_t esp_apptrace_trax_down_buffer_put(esp_apptrace_trax_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo);
|
||||
static bool esp_apptrace_trax_host_is_connected(esp_apptrace_trax_data_t *hw_data);
|
||||
static esp_err_t esp_apptrace_trax_buffer_swap_start(uint32_t curr_block_id);
|
||||
static esp_err_t esp_apptrace_trax_buffer_swap(uint32_t new_block_id);
|
||||
static esp_err_t esp_apptrace_trax_buffer_swap_end(uint32_t new_block_id, uint32_t prev_block_len);
|
||||
static bool esp_apptrace_trax_host_data_pending(void);
|
||||
|
||||
|
||||
const static char *TAG = "esp_apptrace";
|
||||
|
||||
esp_apptrace_hw_t *esp_apptrace_uart_hw_get(int num, void **data)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_apptrace_hw_t *esp_apptrace_jtag_hw_get(void **data)
|
||||
{
|
||||
#if CONFIG_APPTRACE_DEST_JTAG
|
||||
static esp_apptrace_membufs_proto_hw_t s_trax_proto_hw = {
|
||||
.swap_start = esp_apptrace_trax_buffer_swap_start,
|
||||
.swap = esp_apptrace_trax_buffer_swap,
|
||||
.swap_end = esp_apptrace_trax_buffer_swap_end,
|
||||
.host_data_pending = esp_apptrace_trax_host_data_pending,
|
||||
};
|
||||
static esp_apptrace_trax_data_t s_trax_hw_data = {
|
||||
.membufs = {
|
||||
.hw = &s_trax_proto_hw,
|
||||
},
|
||||
};
|
||||
static esp_apptrace_hw_t s_trax_hw = {
|
||||
.init = (esp_err_t (*)(void *))esp_apptrace_trax_init,
|
||||
.get_up_buffer = (uint8_t *(*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_trax_up_buffer_get,
|
||||
.put_up_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_up_buffer_put,
|
||||
.flush_up_buffer_nolock = (esp_err_t (*)(void *, uint32_t, esp_apptrace_tmo_t *))esp_apptrace_trax_flush_nolock,
|
||||
.flush_up_buffer = (esp_err_t (*)(void *, esp_apptrace_tmo_t *))esp_apptrace_trax_flush,
|
||||
.down_buffer_config = (void (*)(void *, uint8_t *, uint32_t ))esp_apptrace_trax_down_buffer_config,
|
||||
.get_down_buffer = (uint8_t *(*)(void *, uint32_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_down_buffer_get,
|
||||
.put_down_buffer = (esp_err_t (*)(void *, uint8_t *, esp_apptrace_tmo_t *))esp_apptrace_trax_down_buffer_put,
|
||||
.host_is_connected = (bool (*)(void *))esp_apptrace_trax_host_is_connected,
|
||||
};
|
||||
*data = &s_trax_hw_data;
|
||||
return &s_trax_hw;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_lock(esp_apptrace_trax_data_t *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
esp_err_t ret = esp_apptrace_lock_take(&hw_data->lock, tmo);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_unlock(esp_apptrace_trax_data_t *hw_data)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
ret = esp_apptrace_lock_give(&hw_data->lock);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void esp_apptrace_trax_hw_init(void)
|
||||
{
|
||||
// Stop trace, if any (on the current CPU)
|
||||
eri_write(ERI_TRAX_TRAXCTRL, TRAXCTRL_TRSTP);
|
||||
eri_write(ERI_TRAX_TRAXCTRL, TRAXCTRL_TMEN);
|
||||
eri_write(ESP_APPTRACE_TRAX_CTRL_REG, ESP_APPTRACE_TRAX_BLOCK_ID(0));
|
||||
// this is for OpenOCD to let him know where stub entries vector is resided
|
||||
// must be read by host before any transfer using TRAX
|
||||
eri_write(ESP_APPTRACE_TRAX_STAT_REG, 0);
|
||||
|
||||
ESP_APPTRACE_LOGI("Initialized TRAX on CPU%d", cpu_hal_get_core_id());
|
||||
}
|
||||
|
||||
static inline void esp_apptrace_trax_select_memory_block(int block_num)
|
||||
{
|
||||
// select memory block to be exposed to the TRAX module (accessed by host)
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, block_num ? TRACEMEM_MUX_BLK0_ONLY : TRACEMEM_MUX_BLK1_ONLY);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
WRITE_PERI_REG(DPORT_PMS_OCCUPY_3_REG, block_num ? BIT(TRACEMEM_MUX_BLK0_NUM-4) : BIT(TRACEMEM_MUX_BLK1_NUM-4));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void esp_apptrace_trax_memory_enable(void)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
/* Enable trace memory on PRO CPU */
|
||||
DPORT_WRITE_PERI_REG(DPORT_PRO_TRACEMEM_ENA_REG, DPORT_PRO_TRACEMEM_ENA_M);
|
||||
#if CONFIG_FREERTOS_UNICORE == 0
|
||||
/* Enable trace memory on APP CPU */
|
||||
DPORT_WRITE_PERI_REG(DPORT_APP_TRACEMEM_ENA_REG, DPORT_APP_TRACEMEM_ENA_M);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************************/
|
||||
/***************************** Apptrace HW iface *****************************************/
|
||||
/*****************************************************************************************/
|
||||
|
||||
static esp_err_t esp_apptrace_trax_init(esp_apptrace_trax_data_t *hw_data)
|
||||
{
|
||||
int core_id = cpu_hal_get_core_id();
|
||||
|
||||
// 'esp_apptrace_trax_init()' is called on every core, so ensure to do main initialization only once
|
||||
if (core_id == 0) {
|
||||
esp_apptrace_mem_block_t mem_blocks_cfg[2] = {
|
||||
{
|
||||
.start = s_trax_blocks[0],
|
||||
.sz = ESP_APPTRACE_TRAX_BLOCK_SIZE
|
||||
},
|
||||
{
|
||||
.start = s_trax_blocks[1],
|
||||
.sz = ESP_APPTRACE_TRAX_BLOCK_SIZE
|
||||
},
|
||||
};
|
||||
esp_err_t res = esp_apptrace_membufs_init(&hw_data->membufs, mem_blocks_cfg);
|
||||
if (res != ESP_OK) {
|
||||
ESP_APPTRACE_LOGE("Failed to init membufs proto (%d)!", res);
|
||||
return res;
|
||||
}
|
||||
#if CONFIG_APPTRACE_LOCK_ENABLE
|
||||
esp_apptrace_lock_init(&hw_data->lock);
|
||||
#endif
|
||||
esp_apptrace_trax_memory_enable();
|
||||
esp_apptrace_trax_select_memory_block(0);
|
||||
}
|
||||
// init TRAX on this CPU
|
||||
esp_apptrace_trax_hw_init();
|
||||
hw_data->inited |= 1 << core_id;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static uint8_t *esp_apptrace_trax_up_buffer_get(esp_apptrace_trax_data_t *hw_data, uint32_t size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
return NULL;
|
||||
}
|
||||
esp_err_t res = esp_apptrace_trax_lock(hw_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = esp_apptrace_membufs_up_buffer_get(&hw_data->membufs, size, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
if (esp_apptrace_trax_unlock(hw_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_up_buffer_put(esp_apptrace_trax_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
// Can avoid locking because esp_apptrace_membufs_up_buffer_put() just modifies buffer's header
|
||||
esp_err_t res = esp_apptrace_membufs_up_buffer_put(&hw_data->membufs, ptr, tmo);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void esp_apptrace_trax_down_buffer_config(esp_apptrace_trax_data_t *hw_data, uint8_t *buf, uint32_t size)
|
||||
{
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
return;
|
||||
}
|
||||
esp_apptrace_membufs_down_buffer_config(&hw_data->membufs, buf, size);
|
||||
}
|
||||
|
||||
static uint8_t *esp_apptrace_trax_down_buffer_get(esp_apptrace_trax_data_t *hw_data, uint32_t *size, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
return NULL;
|
||||
}
|
||||
esp_err_t res = esp_apptrace_trax_lock(hw_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = esp_apptrace_membufs_down_buffer_get(&hw_data->membufs, size, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
if (esp_apptrace_trax_unlock(hw_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_down_buffer_put(esp_apptrace_trax_data_t *hw_data, uint8_t *ptr, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
// Can avoid locking because esp_apptrace_membufs_down_buffer_put() does nothing
|
||||
/*esp_err_t res = esp_apptrace_trax_lock(hw_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return res;
|
||||
}*/
|
||||
|
||||
esp_err_t res = esp_apptrace_membufs_down_buffer_put(&hw_data->membufs, ptr, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
/*if (esp_apptrace_trax_unlock(hw_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}*/
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool esp_apptrace_trax_host_is_connected(esp_apptrace_trax_data_t *hw_data)
|
||||
{
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
return false;
|
||||
}
|
||||
return eri_read(ESP_APPTRACE_TRAX_CTRL_REG) & ESP_APPTRACE_TRAX_HOST_CONNECT ? true : false;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_flush_nolock(esp_apptrace_trax_data_t *hw_data, uint32_t min_sz, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
return esp_apptrace_membufs_flush_nolock(&hw_data->membufs, min_sz, tmo);
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_flush(esp_apptrace_trax_data_t *hw_data, esp_apptrace_tmo_t *tmo)
|
||||
{
|
||||
if (!ESP_APPTRACE_TRAX_INITED(hw_data)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
esp_err_t res = esp_apptrace_trax_lock(hw_data, tmo);
|
||||
if (res != ESP_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = esp_apptrace_membufs_flush_nolock(&hw_data->membufs, 0, tmo);
|
||||
|
||||
// now we can safely unlock apptrace to allow other tasks/ISRs to get other buffers and write their data
|
||||
if (esp_apptrace_trax_unlock(hw_data) != ESP_OK) {
|
||||
assert(false && "Failed to unlock apptrace data!");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*****************************************************************************************/
|
||||
/************************** Membufs proto HW iface ***************************************/
|
||||
/*****************************************************************************************/
|
||||
|
||||
static inline void esp_apptrace_trax_buffer_swap_lock(void)
|
||||
{
|
||||
extern uint32_t __esp_apptrace_trax_eri_updated;
|
||||
|
||||
// indicate to host that we are about to update.
|
||||
// this is used only to place CPU into streaming mode at tracing startup
|
||||
// before starting streaming host can halt us after we read ESP_APPTRACE_TRAX_CTRL_REG and before we updated it
|
||||
// HACK: in this case host will set breakpoint just after ESP_APPTRACE_TRAX_CTRL_REG update,
|
||||
// here we set address to set bp at
|
||||
// enter ERI update critical section
|
||||
eri_write(ESP_APPTRACE_TRAX_STAT_REG, (uint32_t)&__esp_apptrace_trax_eri_updated);
|
||||
}
|
||||
|
||||
static __attribute__((noinline)) void esp_apptrace_trax_buffer_swap_unlock(void)
|
||||
{
|
||||
// exit ERI update critical section
|
||||
eri_write(ESP_APPTRACE_TRAX_STAT_REG, 0x0);
|
||||
// TODO: currently host sets breakpoint, use break instruction to stop;
|
||||
// it will allow to use ESP_APPTRACE_TRAX_STAT_REG for other purposes
|
||||
asm volatile (
|
||||
" .global __esp_apptrace_trax_eri_updated\n"
|
||||
"__esp_apptrace_trax_eri_updated:\n"); // host will set bp here to resolve collision at streaming start
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_buffer_swap_start(uint32_t curr_block_id)
|
||||
{
|
||||
esp_err_t res = ESP_OK;
|
||||
|
||||
esp_apptrace_trax_buffer_swap_lock();
|
||||
|
||||
uint32_t ctrl_reg = eri_read(ESP_APPTRACE_TRAX_CTRL_REG);
|
||||
uint32_t host_connected = ESP_APPTRACE_TRAX_HOST_CONNECT & ctrl_reg;
|
||||
if (host_connected) {
|
||||
uint32_t acked_block = ESP_APPTRACE_TRAX_BLOCK_ID_GET(ctrl_reg);
|
||||
uint32_t host_to_read = ESP_APPTRACE_TRAX_BLOCK_LEN_GET(ctrl_reg);
|
||||
if (host_to_read != 0 || acked_block != (curr_block_id & ESP_APPTRACE_TRAX_BLOCK_ID_MSK)) {
|
||||
ESP_APPTRACE_LOGD("HC[%d]: Can not switch %x %d %x %x/%lx", cpu_hal_get_core_id(), ctrl_reg, host_to_read, acked_block,
|
||||
curr_block_id & ESP_APPTRACE_TRAX_BLOCK_ID_MSK, curr_block_id);
|
||||
res = ESP_ERR_NO_MEM;
|
||||
goto _on_err;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
_on_err:
|
||||
esp_apptrace_trax_buffer_swap_unlock();
|
||||
return res;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_buffer_swap_end(uint32_t new_block_id, uint32_t prev_block_len)
|
||||
{
|
||||
uint32_t ctrl_reg = eri_read(ESP_APPTRACE_TRAX_CTRL_REG);
|
||||
uint32_t host_connected = ESP_APPTRACE_TRAX_HOST_CONNECT & ctrl_reg;
|
||||
eri_write(ESP_APPTRACE_TRAX_CTRL_REG, ESP_APPTRACE_TRAX_BLOCK_ID(new_block_id) |
|
||||
host_connected | ESP_APPTRACE_TRAX_BLOCK_LEN(prev_block_len));
|
||||
esp_apptrace_trax_buffer_swap_unlock();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_buffer_swap(uint32_t new_block_id)
|
||||
{
|
||||
esp_apptrace_trax_select_memory_block(new_block_id);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static bool esp_apptrace_trax_host_data_pending(void)
|
||||
{
|
||||
uint32_t ctrl_reg = eri_read(ESP_APPTRACE_TRAX_CTRL_REG);
|
||||
return (ctrl_reg & ESP_APPTRACE_TRAX_HOST_DATA) ? true : false;
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
// Copyright 2020 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.
|
||||
#ifndef ESP_APP_TRACE_MEMBUFS_PROTO_H_
|
||||
#define ESP_APP_TRACE_MEMBUFS_PROTO_H_
|
||||
|
||||
#include "esp_app_trace_util.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** TRAX HW transport state */
|
||||
typedef struct {
|
||||
uint32_t in_block; // input block ID
|
||||
// TODO: change to uint16_t
|
||||
uint32_t markers[2]; // block filling level markers
|
||||
} esp_apptrace_membufs_state_t;
|
||||
|
||||
/** memory block parameters,
|
||||
* should be packed, because it is read from the host */
|
||||
typedef struct {
|
||||
uint8_t *start; // start address
|
||||
uint32_t sz; // size
|
||||
} esp_apptrace_mem_block_t;
|
||||
|
||||
typedef struct {
|
||||
esp_err_t (*swap_start)(uint32_t curr_block_id);
|
||||
esp_err_t (*swap)(uint32_t new_block_id);
|
||||
esp_err_t (*swap_end)(uint32_t new_block_id, uint32_t prev_block_len);
|
||||
bool (*host_data_pending)(void);
|
||||
} esp_apptrace_membufs_proto_hw_t;
|
||||
|
||||
typedef struct {
|
||||
esp_apptrace_membufs_proto_hw_t * hw;
|
||||
volatile esp_apptrace_membufs_state_t state; // state
|
||||
esp_apptrace_mem_block_t blocks[2]; // memory blocks
|
||||
#if CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX > 0
|
||||
// ring buffer control struct for pending user blocks
|
||||
esp_apptrace_rb_t rb_pend;
|
||||
// storage for pending user blocks
|
||||
uint8_t pending_data[CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX + 1];
|
||||
#endif
|
||||
// ring buffer control struct for data from host (down buffer)
|
||||
esp_apptrace_rb_t rb_down;
|
||||
} esp_apptrace_membufs_proto_data_t;
|
||||
|
||||
esp_err_t esp_apptrace_membufs_init(esp_apptrace_membufs_proto_data_t *proto, const esp_apptrace_mem_block_t blocks_cfg[2]);
|
||||
void esp_apptrace_membufs_down_buffer_config(esp_apptrace_membufs_proto_data_t *data, uint8_t *buf, uint32_t size);
|
||||
uint8_t *esp_apptrace_membufs_down_buffer_get(esp_apptrace_membufs_proto_data_t *proto, uint32_t *size, esp_apptrace_tmo_t *tmo);
|
||||
esp_err_t esp_apptrace_membufs_down_buffer_put(esp_apptrace_membufs_proto_data_t *proto, uint8_t *ptr, esp_apptrace_tmo_t *tmo);
|
||||
uint8_t *esp_apptrace_membufs_up_buffer_get(esp_apptrace_membufs_proto_data_t *proto, uint32_t size, esp_apptrace_tmo_t *tmo);
|
||||
esp_err_t esp_apptrace_membufs_up_buffer_put(esp_apptrace_membufs_proto_data_t *proto, uint8_t *ptr, esp_apptrace_tmo_t *tmo);
|
||||
esp_err_t esp_apptrace_membufs_flush_nolock(esp_apptrace_membufs_proto_data_t *proto, uint32_t min_sz, esp_apptrace_tmo_t *tmo);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,35 +0,0 @@
|
||||
# idf_create_lcov_report
|
||||
#
|
||||
# Create coverage report.
|
||||
function(idf_create_coverage_report report_dir)
|
||||
set(gcov_tool ${CONFIG_SDK_TOOLPREFIX}gcov)
|
||||
idf_build_get_property(project_name PROJECT_NAME)
|
||||
|
||||
add_custom_target(pre-cov-report
|
||||
COMMENT "Generating coverage report in: ${report_dir}"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Using gcov: ${gcov_tool}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${report_dir}/html
|
||||
)
|
||||
|
||||
add_custom_target(lcov-report
|
||||
COMMENT "WARNING: lcov-report is deprecated. Please use gcovr-report instead."
|
||||
COMMAND lcov --gcov-tool ${gcov_tool} -c -d ${CMAKE_CURRENT_BINARY_DIR} -o ${report_dir}/${project_name}.info
|
||||
COMMAND genhtml -o ${report_dir}/html ${report_dir}/${project_name}.info
|
||||
DEPENDS pre-cov-report
|
||||
)
|
||||
|
||||
add_custom_target(gcovr-report
|
||||
COMMAND gcovr -r ${project_dir} --gcov-executable ${gcov_tool} -s --html-details ${report_dir}/html/index.html
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS pre-cov-report
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# idf_clean_coverage_report
|
||||
#
|
||||
# Clean coverage report.
|
||||
function(idf_clean_coverage_report report_dir)
|
||||
add_custom_target(cov-data-clean
|
||||
COMMENT "Clean coverage report in: ${report_dir}"
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${report_dir})
|
||||
endfunction()
|
||||
@@ -1,36 +0,0 @@
|
||||
# sdkconfig replacement configurations for deprecated options formatted as
|
||||
# CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION
|
||||
|
||||
CONFIG_ESP32_APPTRACE_DESTINATION CONFIG_APPTRACE_DESTINATION
|
||||
CONFIG_ESP32_APPTRACE_DEST_NONE CONFIG_APPTRACE_DEST_NONE
|
||||
CONFIG_ESP32_APPTRACE_DEST_TRAX CONFIG_APPTRACE_DEST_JTAG
|
||||
CONFIG_ESP32_APPTRACE_ENABLE CONFIG_APPTRACE_ENABLE
|
||||
CONFIG_ESP32_APPTRACE_LOCK_ENABLE CONFIG_APPTRACE_LOCK_ENABLE
|
||||
CONFIG_ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO
|
||||
CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH
|
||||
CONFIG_ESP32_APPTRACE_PENDING_DATA_SIZE_MAX CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX
|
||||
CONFIG_ESP32_GCOV_ENABLE CONFIG_APPTRACE_GCOV_ENABLE
|
||||
|
||||
CONFIG_SYSVIEW_ENABLE CONFIG_APPTRACE_SV_ENABLE
|
||||
CONFIG_SYSVIEW_TS_SOURCE CONFIG_APPTRACE_SV_TS_SOURCE
|
||||
CONFIG_SYSVIEW_TS_SOURCE_CCOUNT CONFIG_APPTRACE_SV_TS_SOURCE_CCOUNT
|
||||
CONFIG_SYSVIEW_TS_SOURCE_TIMER_00 CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00
|
||||
CONFIG_SYSVIEW_TS_SOURCE_TIMER_01 CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_01
|
||||
CONFIG_SYSVIEW_TS_SOURCE_TIMER_10 CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_10
|
||||
CONFIG_SYSVIEW_TS_SOURCE_TIMER_11 CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_11
|
||||
CONFIG_SYSVIEW_TS_SOURCE_ESP_TIMER CONFIG_APPTRACE_SV_TS_SOURCE_ESP_TIMER
|
||||
CONFIG_SYSVIEW_MAX_TASKS CONFIG_APPTRACE_SV_MAX_TASKS
|
||||
CONFIG_SYSVIEW_BUF_WAIT_TMO CONFIG_APPTRACE_SV_BUF_WAIT_TMO
|
||||
CONFIG_SYSVIEW_EVT_OVERFLOW_ENABLE CONFIG_APPTRACE_SV_EVT_OVERFLOW_ENABLE
|
||||
CONFIG_SYSVIEW_EVT_ISR_ENTER_ENABLE CONFIG_APPTRACE_SV_EVT_ISR_ENTER_ENABLE
|
||||
CONFIG_SYSVIEW_EVT_ISR_EXIT_ENABLE CONFIG_APPTRACE_SV_EVT_ISR_EXIT_ENABLE
|
||||
CONFIG_SYSVIEW_EVT_ISR_TO_SCHEDULER_ENABLE CONFIG_APPTRACE_SV_EVT_ISR_TO_SCHED_ENABLE
|
||||
CONFIG_SYSVIEW_EVT_TASK_START_EXEC_ENABLE CONFIG_APPTRACE_SV_EVT_TASK_START_EXEC_ENABLE
|
||||
CONFIG_SYSVIEW_EVT_TASK_STOP_EXEC_ENABLE CONFIG_APPTRACE_SV_EVT_TASK_STOP_EXEC_ENABLE
|
||||
CONFIG_SYSVIEW_EVT_TASK_START_READY_ENABLE CONFIG_APPTRACE_SV_EVT_TASK_START_READY_ENABLE
|
||||
CONFIG_SYSVIEW_EVT_TASK_STOP_READY_ENABLE CONFIG_APPTRACE_SV_EVT_TASK_STOP_READY_ENABLE
|
||||
CONFIG_SYSVIEW_EVT_TASK_CREATE_ENABLE CONFIG_APPTRACE_SV_EVT_TASK_CREATE_ENABLE
|
||||
CONFIG_SYSVIEW_EVT_TASK_TERMINATE_ENABLE CONFIG_APPTRACE_SV_EVT_TASK_TERMINATE_ENABLE
|
||||
CONFIG_SYSVIEW_EVT_IDLE_ENABLE CONFIG_APPTRACE_SV_EVT_IDLE_ENABLE
|
||||
CONFIG_SYSVIEW_EVT_TIMER_ENTER_ENABLE CONFIG_APPTRACE_SV_EVT_TIMER_ENTER_ENABLE
|
||||
CONFIG_SYSVIEW_EVT_TIMER_EXIT_ENABLE CONFIG_APPTRACE_SV_EVT_TIMER_EXIT_ENABLE
|
||||
@@ -1,102 +1,102 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
----------------------------------------------------------------------
|
||||
File : Global.h
|
||||
Purpose : Global types
|
||||
In case your application already has a Global.h, you should
|
||||
merge the files. In order to use Segger code, the types
|
||||
U8, U16, U32, I8, I16, I32 need to be defined in Global.h;
|
||||
additional definitions do not hurt.
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GLOBAL_H // Guard against multiple inclusion
|
||||
#define GLOBAL_H
|
||||
|
||||
#define U8 unsigned char
|
||||
#define U16 unsigned short
|
||||
#define U32 unsigned long
|
||||
#define I8 signed char
|
||||
#define I16 signed short
|
||||
#define I32 signed long
|
||||
|
||||
#ifdef _WIN32
|
||||
//
|
||||
// Microsoft VC6 compiler related
|
||||
//
|
||||
#define U64 unsigned __int64
|
||||
#define U128 unsigned __int128
|
||||
#define I64 __int64
|
||||
#define I128 __int128
|
||||
#if _MSC_VER <= 1200
|
||||
#define U64_C(x) x##UI64
|
||||
#else
|
||||
#define U64_C(x) x##ULL
|
||||
#endif
|
||||
#else
|
||||
//
|
||||
// C99 compliant compiler
|
||||
//
|
||||
#define U64 unsigned long long
|
||||
#define I64 signed long long
|
||||
#define U64_C(x) x##ULL
|
||||
#endif
|
||||
|
||||
#endif // Avoid multiple inclusion
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
----------------------------------------------------------------------
|
||||
File : Global.h
|
||||
Purpose : Global types
|
||||
In case your application already has a Global.h, you should
|
||||
merge the files. In order to use Segger code, the types
|
||||
U8, U16, U32, I8, I16, I32 need to be defined in Global.h;
|
||||
additional definitions do not hurt.
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GLOBAL_H // Guard against multiple inclusion
|
||||
#define GLOBAL_H
|
||||
|
||||
#define U8 unsigned char
|
||||
#define U16 unsigned short
|
||||
#define U32 unsigned long
|
||||
#define I8 signed char
|
||||
#define I16 signed short
|
||||
#define I32 signed long
|
||||
|
||||
#ifdef _WIN32
|
||||
//
|
||||
// Microsoft VC6 compiler related
|
||||
//
|
||||
#define U64 unsigned __int64
|
||||
#define U128 unsigned __int128
|
||||
#define I64 __int64
|
||||
#define I128 __int128
|
||||
#if _MSC_VER <= 1200
|
||||
#define U64_C(x) x##UI64
|
||||
#else
|
||||
#define U64_C(x) x##ULL
|
||||
#endif
|
||||
#else
|
||||
//
|
||||
// C99 compliant compiler
|
||||
//
|
||||
#define U64 unsigned long long
|
||||
#define I64 signed long long
|
||||
#define U64_C(x) x##ULL
|
||||
#endif
|
||||
|
||||
#endif // Avoid multiple inclusion
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -1,298 +1,298 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
File : SEGGER_RTT_Conf.h
|
||||
Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
allows real-time communication on targets which support
|
||||
debugger memory accesses while the CPU is running.
|
||||
Revision: $Rev: 5626 $
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_RTT_CONF_H
|
||||
#define SEGGER_RTT_CONF_H
|
||||
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
#include <intrinsics.h>
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, configurable
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3)
|
||||
#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3)
|
||||
|
||||
#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k)
|
||||
#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
|
||||
|
||||
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64)
|
||||
|
||||
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
|
||||
|
||||
//
|
||||
// Target is not allowed to perform other RTT operations while string still has not been stored completely.
|
||||
// Otherwise we would probably end up with a mixed string in the buffer.
|
||||
// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
|
||||
//
|
||||
// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
|
||||
// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
|
||||
// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
|
||||
// (Higher priority = lower priority number)
|
||||
// Default value for embOS: 128u
|
||||
// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
|
||||
// or define SEGGER_RTT_LOCK() to completely disable interrupts.
|
||||
//
|
||||
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for SEGGER Embedded Studio,
|
||||
* Rowley CrossStudio and GCC
|
||||
*/
|
||||
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
|
||||
#ifdef __ARM_ARCH_6M__
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs %0, primask \n\t" \
|
||||
"mov r1, $1 \n\t" \
|
||||
"msr primask, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: \
|
||||
); \
|
||||
}
|
||||
|
||||
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs %0, basepri \n\t" \
|
||||
"mov r1, %1 \n\t" \
|
||||
"msr basepri, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: \
|
||||
); \
|
||||
}
|
||||
|
||||
#elif defined(__ARM_ARCH_7A__)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs r1, CPSR \n\t" \
|
||||
"mov %0, r1 \n\t" \
|
||||
"orr r1, r1, #0xC0 \n\t" \
|
||||
"msr CPSR_c, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
|
||||
"mrs r1, CPSR \n\t" \
|
||||
"bic r1, r1, #0xC0 \n\t" \
|
||||
"and r0, r0, #0xC0 \n\t" \
|
||||
"orr r1, r1, r0 \n\t" \
|
||||
"msr CPSR_c, r1 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: "r0", "r1" \
|
||||
); \
|
||||
}
|
||||
#else
|
||||
#define SEGGER_RTT_LOCK()
|
||||
#define SEGGER_RTT_UNLOCK()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for IAR EWARM
|
||||
*/
|
||||
#ifdef __ICCARM__
|
||||
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_PRIMASK(); \
|
||||
__set_PRIMASK(1);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
|
||||
}
|
||||
#elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__)))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_BASEPRI(); \
|
||||
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for IAR RX
|
||||
*/
|
||||
#ifdef __ICCRX__
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned long LockState; \
|
||||
LockState = __get_interrupt_state(); \
|
||||
__disable_interrupt();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for KEIL ARM
|
||||
*/
|
||||
#ifdef __CC_ARM
|
||||
#if (defined __TARGET_ARCH_6S_M)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
register unsigned char PRIMASK __asm( "primask"); \
|
||||
LockState = PRIMASK; \
|
||||
PRIMASK = 1u; \
|
||||
__schedule_barrier();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \
|
||||
__schedule_barrier(); \
|
||||
}
|
||||
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
register unsigned char BASEPRI __asm( "basepri"); \
|
||||
LockState = BASEPRI; \
|
||||
BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \
|
||||
__schedule_barrier();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \
|
||||
__schedule_barrier(); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for TI ARM
|
||||
*/
|
||||
#ifdef __TI_ARM__
|
||||
#if defined (__TI_ARM_V6M0__)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_PRIMASK(); \
|
||||
__set_PRIMASK(1);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
|
||||
}
|
||||
#elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = OS_GetBASEPRI(); \
|
||||
OS_SetBASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() OS_SetBASEPRI(LockState); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration fallback
|
||||
*/
|
||||
#ifndef SEGGER_RTT_LOCK
|
||||
void SEGGER_SYSVIEW_X_RTT_Lock(void);
|
||||
#define SEGGER_RTT_LOCK() SEGGER_SYSVIEW_X_RTT_Lock() // Lock RTT (nestable) (i.e. disable interrupts)
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_UNLOCK
|
||||
void SEGGER_SYSVIEW_X_RTT_Unlock(void);
|
||||
#define SEGGER_RTT_UNLOCK() SEGGER_SYSVIEW_X_RTT_Unlock() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
File : SEGGER_RTT_Conf.h
|
||||
Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
allows real-time communication on targets which support
|
||||
debugger memory accesses while the CPU is running.
|
||||
Revision: $Rev: 5626 $
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_RTT_CONF_H
|
||||
#define SEGGER_RTT_CONF_H
|
||||
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
#include <intrinsics.h>
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, configurable
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3)
|
||||
#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3)
|
||||
|
||||
#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k)
|
||||
#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
|
||||
|
||||
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64)
|
||||
|
||||
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
|
||||
|
||||
//
|
||||
// Target is not allowed to perform other RTT operations while string still has not been stored completely.
|
||||
// Otherwise we would probably end up with a mixed string in the buffer.
|
||||
// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
|
||||
//
|
||||
// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
|
||||
// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
|
||||
// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
|
||||
// (Higher priority = lower priority number)
|
||||
// Default value for embOS: 128u
|
||||
// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
|
||||
// or define SEGGER_RTT_LOCK() to completely disable interrupts.
|
||||
//
|
||||
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for SEGGER Embedded Studio,
|
||||
* Rowley CrossStudio and GCC
|
||||
*/
|
||||
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
|
||||
#ifdef __ARM_ARCH_6M__
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs %0, primask \n\t" \
|
||||
"mov r1, $1 \n\t" \
|
||||
"msr primask, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: \
|
||||
); \
|
||||
}
|
||||
|
||||
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs %0, basepri \n\t" \
|
||||
"mov r1, %1 \n\t" \
|
||||
"msr basepri, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: \
|
||||
); \
|
||||
}
|
||||
|
||||
#elif defined(__ARM_ARCH_7A__)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs r1, CPSR \n\t" \
|
||||
"mov %0, r1 \n\t" \
|
||||
"orr r1, r1, #0xC0 \n\t" \
|
||||
"msr CPSR_c, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
|
||||
"mrs r1, CPSR \n\t" \
|
||||
"bic r1, r1, #0xC0 \n\t" \
|
||||
"and r0, r0, #0xC0 \n\t" \
|
||||
"orr r1, r1, r0 \n\t" \
|
||||
"msr CPSR_c, r1 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: "r0", "r1" \
|
||||
); \
|
||||
}
|
||||
#else
|
||||
#define SEGGER_RTT_LOCK()
|
||||
#define SEGGER_RTT_UNLOCK()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for IAR EWARM
|
||||
*/
|
||||
#ifdef __ICCARM__
|
||||
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_PRIMASK(); \
|
||||
__set_PRIMASK(1);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
|
||||
}
|
||||
#elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__)))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_BASEPRI(); \
|
||||
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for IAR RX
|
||||
*/
|
||||
#ifdef __ICCRX__
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned long LockState; \
|
||||
LockState = __get_interrupt_state(); \
|
||||
__disable_interrupt();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for KEIL ARM
|
||||
*/
|
||||
#ifdef __CC_ARM
|
||||
#if (defined __TARGET_ARCH_6S_M)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
register unsigned char PRIMASK __asm( "primask"); \
|
||||
LockState = PRIMASK; \
|
||||
PRIMASK = 1u; \
|
||||
__schedule_barrier();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \
|
||||
__schedule_barrier(); \
|
||||
}
|
||||
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
register unsigned char BASEPRI __asm( "basepri"); \
|
||||
LockState = BASEPRI; \
|
||||
BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \
|
||||
__schedule_barrier();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \
|
||||
__schedule_barrier(); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for TI ARM
|
||||
*/
|
||||
#ifdef __TI_ARM__
|
||||
#if defined (__TI_ARM_V6M0__)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_PRIMASK(); \
|
||||
__set_PRIMASK(1);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
|
||||
}
|
||||
#elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = OS_GetBASEPRI(); \
|
||||
OS_SetBASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() OS_SetBASEPRI(LockState); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration fallback
|
||||
*/
|
||||
#ifndef SEGGER_RTT_LOCK
|
||||
void SEGGER_SYSVIEW_X_RTT_Lock();
|
||||
#define SEGGER_RTT_LOCK() SEGGER_SYSVIEW_X_RTT_Lock() // Lock RTT (nestable) (i.e. disable interrupts)
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_UNLOCK
|
||||
void SEGGER_SYSVIEW_X_RTT_Unlock();
|
||||
#define SEGGER_RTT_UNLOCK() SEGGER_SYSVIEW_X_RTT_Unlock() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -1,179 +1,176 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
|
||||
File : SEGGER_SYSVIEW_Conf.h
|
||||
Purpose : SEGGER SystemView configuration.
|
||||
Revision: $Rev: 5927 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_CONF_H
|
||||
#define SEGGER_SYSVIEW_CONF_H
|
||||
|
||||
#include "soc/soc.h"
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, fixed
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
//
|
||||
// Constants for known core configuration
|
||||
//
|
||||
#define SEGGER_SYSVIEW_CORE_OTHER 0
|
||||
#define SEGGER_SYSVIEW_CORE_CM0 1 // Cortex-M0/M0+/M1
|
||||
#define SEGGER_SYSVIEW_CORE_CM3 2 // Cortex-M3/M4/M7
|
||||
#define SEGGER_SYSVIEW_CORE_RX 3 // Renesas RX
|
||||
|
||||
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
|
||||
#ifdef __ARM_ARCH_6M__
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__ICCARM__)
|
||||
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif ((defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__CC_ARM)
|
||||
#if (defined(__TARGET_ARCH_6S_M))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__TI_ARM__)
|
||||
#ifdef __TI_ARM_V6M0__
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif (defined(__TI_ARM_V7M3__) || defined(__TI_ARM_V7M4__))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__ICCRX__)
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
|
||||
#elif defined(__RX)
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_CORE
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_OTHER
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, configurable
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView buffer configuration
|
||||
*/
|
||||
#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024 // Number of bytes that SystemView uses for the buffer.
|
||||
#define SEGGER_SYSVIEW_RTT_CHANNEL 1 // The RTT channel that SystemView will use. 0: Auto selection
|
||||
|
||||
#define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1 // Use a static buffer to generate events instead of a buffer on the stack
|
||||
|
||||
#define SEGGER_SYSVIEW_POST_MORTEM_MODE 0 // 1: Enable post mortem analysis mode
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView timestamp configuration
|
||||
*/
|
||||
#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
|
||||
#define SEGGER_SYSVIEW_GET_TIMESTAMP() (*(U32 *)(0xE0001004)) // Retrieve a system timestamp. Cortex-M cycle counter.
|
||||
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by clock source
|
||||
#else
|
||||
#define SEGGER_SYSVIEW_GET_TIMESTAMP() SEGGER_SYSVIEW_X_GetTimestamp() // Retrieve a system timestamp via user-defined function
|
||||
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by SEGGER_SYSVIEW_X_GetTimestamp()
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView Id configuration
|
||||
*/
|
||||
//TODO: optimise it
|
||||
#define SEGGER_SYSVIEW_ID_BASE SOC_DROM_LOW // Default value for the lowest Id reported by the application. Can be overridden by the application via SEGGER_SYSVIEW_SetRAMBase(). (i.e. 0x20000000 when all Ids are an address in this RAM)
|
||||
#define SEGGER_SYSVIEW_ID_SHIFT 0 // Number of bits to shift the Id to save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView interrupt configuration
|
||||
*/
|
||||
#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x1FF) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[8:0] = active vector)
|
||||
#elif SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM0
|
||||
#if defined(__ICCARM__)
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() (__get_IPSR()) // Workaround for IAR, which might do a byte-access to 0xE000ED04. Read IPSR instead.
|
||||
#else
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x3F) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[5:0] = active vector)
|
||||
#endif
|
||||
#else
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() SEGGER_SYSVIEW_X_GetInterruptId() // Get the currently active interrupt Id from the user-provided function.
|
||||
#endif
|
||||
|
||||
unsigned SEGGER_SYSVIEW_X_SysView_Lock(void);
|
||||
void SEGGER_SYSVIEW_X_SysView_Unlock(unsigned int_state);
|
||||
// to be recursive save IRQ status on the stack of the caller
|
||||
#define SEGGER_SYSVIEW_LOCK() unsigned _SYSVIEW_int_state = SEGGER_SYSVIEW_X_SysView_Lock()
|
||||
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_SYSVIEW_X_SysView_Unlock(_SYSVIEW_int_state)
|
||||
|
||||
#endif // SEGGER_SYSVIEW_CONF_H
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
|
||||
File : SEGGER_SYSVIEW_Conf.h
|
||||
Purpose : SEGGER SystemView configuration.
|
||||
Revision: $Rev: 5927 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_CONF_H
|
||||
#define SEGGER_SYSVIEW_CONF_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, fixed
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
//
|
||||
// Constants for known core configuration
|
||||
//
|
||||
#define SEGGER_SYSVIEW_CORE_OTHER 0
|
||||
#define SEGGER_SYSVIEW_CORE_CM0 1 // Cortex-M0/M0+/M1
|
||||
#define SEGGER_SYSVIEW_CORE_CM3 2 // Cortex-M3/M4/M7
|
||||
#define SEGGER_SYSVIEW_CORE_RX 3 // Renesas RX
|
||||
|
||||
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
|
||||
#ifdef __ARM_ARCH_6M__
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__ICCARM__)
|
||||
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif ((defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__CC_ARM)
|
||||
#if (defined(__TARGET_ARCH_6S_M))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__TI_ARM__)
|
||||
#ifdef __TI_ARM_V6M0__
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif (defined(__TI_ARM_V7M3__) || defined(__TI_ARM_V7M4__))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__ICCRX__)
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
|
||||
#elif defined(__RX)
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_CORE
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_OTHER
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, configurable
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView buffer configuration
|
||||
*/
|
||||
#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024 // Number of bytes that SystemView uses for the buffer.
|
||||
#define SEGGER_SYSVIEW_RTT_CHANNEL 1 // The RTT channel that SystemView will use. 0: Auto selection
|
||||
|
||||
#define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1 // Use a static buffer to generate events instead of a buffer on the stack
|
||||
|
||||
#define SEGGER_SYSVIEW_POST_MORTEM_MODE 0 // 1: Enable post mortem analysis mode
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView timestamp configuration
|
||||
*/
|
||||
#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
|
||||
#define SEGGER_SYSVIEW_GET_TIMESTAMP() (*(U32 *)(0xE0001004)) // Retrieve a system timestamp. Cortex-M cycle counter.
|
||||
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by clock source
|
||||
#else
|
||||
#define SEGGER_SYSVIEW_GET_TIMESTAMP() SEGGER_SYSVIEW_X_GetTimestamp() // Retrieve a system timestamp via user-defined function
|
||||
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by SEGGER_SYSVIEW_X_GetTimestamp()
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView Id configuration
|
||||
*/
|
||||
//TODO: optimise it
|
||||
#define SEGGER_SYSVIEW_ID_BASE 0x3F400000 // Default value for the lowest Id reported by the application. Can be overridden by the application via SEGGER_SYSVIEW_SetRAMBase(). (i.e. 0x20000000 when all Ids are an address in this RAM)
|
||||
#define SEGGER_SYSVIEW_ID_SHIFT 0 // Number of bits to shift the Id to save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView interrupt configuration
|
||||
*/
|
||||
#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x1FF) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[8:0] = active vector)
|
||||
#elif SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM0
|
||||
#if defined(__ICCARM__)
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() (__get_IPSR()) // Workaround for IAR, which might do a byte-access to 0xE000ED04. Read IPSR instead.
|
||||
#else
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x3F) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[5:0] = active vector)
|
||||
#endif
|
||||
#else
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() SEGGER_SYSVIEW_X_GetInterruptId() // Get the currently active interrupt Id from the user-provided function.
|
||||
#endif
|
||||
|
||||
void SEGGER_SYSVIEW_X_SysView_Lock();
|
||||
void SEGGER_SYSVIEW_X_SysView_Unlock();
|
||||
#define SEGGER_SYSVIEW_LOCK() SEGGER_SYSVIEW_X_SysView_Lock()
|
||||
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_SYSVIEW_X_SysView_Unlock()
|
||||
|
||||
#endif // SEGGER_SYSVIEW_CONF_H
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -1,155 +1,155 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
----------------------------------------------------------------------
|
||||
File : SEGGER.h
|
||||
Purpose : Global types etc & general purpose utility functions
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_H // Guard against multiple inclusion
|
||||
#define SEGGER_H
|
||||
|
||||
#include "Global.h" // Type definitions: U8, U16, U32, I8, I16, I32
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" { /* Make sure we have C-declarations in C++ programs */
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Keywords/specifiers
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef INLINE
|
||||
#ifdef _WIN32
|
||||
//
|
||||
// Microsoft VC6 and newer.
|
||||
// Force inlining without cost checking.
|
||||
//
|
||||
#define INLINE __forceinline
|
||||
#else
|
||||
#if (defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) || defined(__RX) || defined(__ICCRX__))
|
||||
//
|
||||
// Other known compilers.
|
||||
//
|
||||
#define INLINE inline
|
||||
#else
|
||||
//
|
||||
// Unknown compilers.
|
||||
//
|
||||
#define INLINE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Function-like macros
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#define SEGGER_COUNTOF(a) (sizeof((a))/sizeof((a)[0]))
|
||||
#define SEGGER_MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#define SEGGER_MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Types
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char *pBuffer;
|
||||
int BufferSize;
|
||||
int Cnt;
|
||||
} SEGGER_BUFFER_DESC;
|
||||
|
||||
typedef struct {
|
||||
int CacheLineSize; // 0: No Cache. Most Systems such as ARM9 use a 32 bytes cache line size.
|
||||
void (*pfDMB) (void); // Optional DMB function for Data Memory Barrier to make sure all memory operations are completed.
|
||||
void (*pfClean) (void *p, unsigned NumBytes); // Optional clean function for cached memory.
|
||||
void (*pfInvalidate)(void *p, unsigned NumBytes); // Optional invalidate function for cached memory.
|
||||
} SEGGER_CACHE_CONFIG;
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Utility functions
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
void SEGGER_ARM_memcpy (void *pDest, const void *pSrc, int NumBytes);
|
||||
void SEGGER_memcpy (void *pDest, const void *pSrc, int NumBytes);
|
||||
void SEGGER_memxor (void *pDest, const void *pSrc, unsigned NumBytes);
|
||||
void SEGGER_StoreChar (SEGGER_BUFFER_DESC *p, char c);
|
||||
void SEGGER_PrintUnsigned(SEGGER_BUFFER_DESC *pBufferDesc, U32 v, unsigned Base, int NumDigits);
|
||||
void SEGGER_PrintInt (SEGGER_BUFFER_DESC *pBufferDesc, I32 v, unsigned Base, unsigned NumDigits);
|
||||
int SEGGER_snprintf (char *pBuffer, int BufferSize, const char *sFormat, ...);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* Make sure we have C-declarations in C++ programs */
|
||||
#endif
|
||||
|
||||
#endif // Avoid multiple inclusion
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
----------------------------------------------------------------------
|
||||
File : SEGGER.h
|
||||
Purpose : Global types etc & general purpose utility functions
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_H // Guard against multiple inclusion
|
||||
#define SEGGER_H
|
||||
|
||||
#include "Global.h" // Type definitions: U8, U16, U32, I8, I16, I32
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" { /* Make sure we have C-declarations in C++ programs */
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Keywords/specifiers
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef INLINE
|
||||
#ifdef _WIN32
|
||||
//
|
||||
// Microsoft VC6 and newer.
|
||||
// Force inlining without cost checking.
|
||||
//
|
||||
#define INLINE __forceinline
|
||||
#else
|
||||
#if (defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) || defined(__RX) || defined(__ICCRX__))
|
||||
//
|
||||
// Other known compilers.
|
||||
//
|
||||
#define INLINE inline
|
||||
#else
|
||||
//
|
||||
// Unknown compilers.
|
||||
//
|
||||
#define INLINE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Function-like macros
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#define SEGGER_COUNTOF(a) (sizeof((a))/sizeof((a)[0]))
|
||||
#define SEGGER_MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#define SEGGER_MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Types
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char *pBuffer;
|
||||
int BufferSize;
|
||||
int Cnt;
|
||||
} SEGGER_BUFFER_DESC;
|
||||
|
||||
typedef struct {
|
||||
int CacheLineSize; // 0: No Cache. Most Systems such as ARM9 use a 32 bytes cache line size.
|
||||
void (*pfDMB) (void); // Optional DMB function for Data Memory Barrier to make sure all memory operations are completed.
|
||||
void (*pfClean) (void *p, unsigned NumBytes); // Optional clean function for cached memory.
|
||||
void (*pfInvalidate)(void *p, unsigned NumBytes); // Optional invalidate function for cached memory.
|
||||
} SEGGER_CACHE_CONFIG;
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Utility functions
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
void SEGGER_ARM_memcpy (void *pDest, const void *pSrc, int NumBytes);
|
||||
void SEGGER_memcpy (void *pDest, const void *pSrc, int NumBytes);
|
||||
void SEGGER_memxor (void *pDest, const void *pSrc, unsigned NumBytes);
|
||||
void SEGGER_StoreChar (SEGGER_BUFFER_DESC *p, char c);
|
||||
void SEGGER_PrintUnsigned(SEGGER_BUFFER_DESC *pBufferDesc, U32 v, unsigned Base, int NumDigits);
|
||||
void SEGGER_PrintInt (SEGGER_BUFFER_DESC *pBufferDesc, I32 v, unsigned Base, unsigned NumDigits);
|
||||
int SEGGER_snprintf (char *pBuffer, int BufferSize, const char *sFormat, ...);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* Make sure we have C-declarations in C++ programs */
|
||||
#endif
|
||||
|
||||
#endif // Avoid multiple inclusion
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
File : SEGGER_RTT.h
|
||||
Purpose : Implementation of SEGGER real-time transfer which allows
|
||||
real-time communication on targets which support debugger
|
||||
real-time communication on targets which support debugger
|
||||
memory accesses while the CPU is running.
|
||||
Revision: $Rev: 5626 $
|
||||
----------------------------------------------------------------------
|
||||
@@ -159,8 +159,7 @@ unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const voi
|
||||
unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s);
|
||||
void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes);
|
||||
void SEGGER_RTT_ESP_FlushNoLock (unsigned long min_sz, unsigned long tmo);
|
||||
void SEGGER_RTT_ESP_Flush (unsigned long min_sz, unsigned long tmo);
|
||||
void SEGGER_RTT_ESP32_FlushNoLock (unsigned long min_sz, unsigned long tmo);
|
||||
//
|
||||
// Function macro for performance optimization
|
||||
//
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,336 +1,334 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
File : SEGGER_SYSVIEW.h
|
||||
Purpose : System visualization API.
|
||||
Revision: $Rev: 5626 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_H
|
||||
#define SEGGER_SYSVIEW_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* #include Section
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "SEGGER.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, fixed
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#define SEGGER_SYSVIEW_VERSION 21000
|
||||
|
||||
#define SEGGER_SYSVIEW_INFO_SIZE 9 // Minimum size, which has to be reserved for a packet. 1-2 byte of message type, 0-2 byte of payload length, 1-5 bytes of timestamp.
|
||||
#define SEGGER_SYSVIEW_QUANTA_U32 5 // Maximum number of bytes to encode a U32, should be reserved for each 32-bit value in a packet.
|
||||
|
||||
#define SEGGER_SYSVIEW_LOG (0u)
|
||||
#define SEGGER_SYSVIEW_WARNING (1u)
|
||||
#define SEGGER_SYSVIEW_ERROR (2u)
|
||||
#define SEGGER_SYSVIEW_FLAG_APPEND (1u << 6)
|
||||
|
||||
#define SEGGER_SYSVIEW_PREPARE_PACKET(p) (p) + 4
|
||||
//
|
||||
// SystemView events. First 32 IDs from 0 .. 31 are reserved for these
|
||||
//
|
||||
#define SYSVIEW_EVTID_NOP 0 // Dummy packet.
|
||||
#define SYSVIEW_EVTID_OVERFLOW 1
|
||||
#define SYSVIEW_EVTID_ISR_ENTER 2
|
||||
#define SYSVIEW_EVTID_ISR_EXIT 3
|
||||
#define SYSVIEW_EVTID_TASK_START_EXEC 4
|
||||
#define SYSVIEW_EVTID_TASK_STOP_EXEC 5
|
||||
#define SYSVIEW_EVTID_TASK_START_READY 6
|
||||
#define SYSVIEW_EVTID_TASK_STOP_READY 7
|
||||
#define SYSVIEW_EVTID_TASK_CREATE 8
|
||||
#define SYSVIEW_EVTID_TASK_INFO 9
|
||||
#define SYSVIEW_EVTID_TRACE_START 10
|
||||
#define SYSVIEW_EVTID_TRACE_STOP 11
|
||||
#define SYSVIEW_EVTID_SYSTIME_CYCLES 12
|
||||
#define SYSVIEW_EVTID_SYSTIME_US 13
|
||||
#define SYSVIEW_EVTID_SYSDESC 14
|
||||
#define SYSVIEW_EVTID_USER_START 15
|
||||
#define SYSVIEW_EVTID_USER_STOP 16
|
||||
#define SYSVIEW_EVTID_IDLE 17
|
||||
#define SYSVIEW_EVTID_ISR_TO_SCHEDULER 18
|
||||
#define SYSVIEW_EVTID_TIMER_ENTER 19
|
||||
#define SYSVIEW_EVTID_TIMER_EXIT 20
|
||||
#define SYSVIEW_EVTID_STACK_INFO 21
|
||||
#define SYSVIEW_EVTID_MODULEDESC 22
|
||||
|
||||
#define SYSVIEW_EVTID_INIT 24
|
||||
#define SYSVIEW_EVTID_NAME_RESOURCE 25
|
||||
#define SYSVIEW_EVTID_PRINT_FORMATTED 26
|
||||
#define SYSVIEW_EVTID_NUMMODULES 27
|
||||
#define SYSVIEW_EVTID_END_CALL 28
|
||||
#define SYSVIEW_EVTID_TASK_TERMINATE 29
|
||||
|
||||
#define SYSVIEW_EVTID_EX 31
|
||||
//
|
||||
// Event masks to disable/enable events
|
||||
//
|
||||
#define SYSVIEW_EVTMASK_NOP (1 << SYSVIEW_EVTID_NOP)
|
||||
#define SYSVIEW_EVTMASK_OVERFLOW (1 << SYSVIEW_EVTID_OVERFLOW)
|
||||
#define SYSVIEW_EVTMASK_ISR_ENTER (1 << SYSVIEW_EVTID_ISR_ENTER)
|
||||
#define SYSVIEW_EVTMASK_ISR_EXIT (1 << SYSVIEW_EVTID_ISR_EXIT)
|
||||
#define SYSVIEW_EVTMASK_TASK_START_EXEC (1 << SYSVIEW_EVTID_TASK_START_EXEC)
|
||||
#define SYSVIEW_EVTMASK_TASK_STOP_EXEC (1 << SYSVIEW_EVTID_TASK_STOP_EXEC)
|
||||
#define SYSVIEW_EVTMASK_TASK_START_READY (1 << SYSVIEW_EVTID_TASK_START_READY)
|
||||
#define SYSVIEW_EVTMASK_TASK_STOP_READY (1 << SYSVIEW_EVTID_TASK_STOP_READY)
|
||||
#define SYSVIEW_EVTMASK_TASK_CREATE (1 << SYSVIEW_EVTID_TASK_CREATE)
|
||||
#define SYSVIEW_EVTMASK_TASK_INFO (1 << SYSVIEW_EVTID_TASK_INFO)
|
||||
#define SYSVIEW_EVTMASK_TRACE_START (1 << SYSVIEW_EVTID_TRACE_START)
|
||||
#define SYSVIEW_EVTMASK_TRACE_STOP (1 << SYSVIEW_EVTID_TRACE_STOP)
|
||||
#define SYSVIEW_EVTMASK_SYSTIME_CYCLES (1 << SYSVIEW_EVTID_SYSTIME_CYCLES)
|
||||
#define SYSVIEW_EVTMASK_SYSTIME_US (1 << SYSVIEW_EVTID_SYSTIME_US)
|
||||
#define SYSVIEW_EVTMASK_SYSDESC (1 << SYSVIEW_EVTID_SYSDESC)
|
||||
#define SYSVIEW_EVTMASK_USER_START (1 << SYSVIEW_EVTID_USER_START)
|
||||
#define SYSVIEW_EVTMASK_USER_STOP (1 << SYSVIEW_EVTID_USER_STOP)
|
||||
#define SYSVIEW_EVTMASK_IDLE (1 << SYSVIEW_EVTID_IDLE)
|
||||
#define SYSVIEW_EVTMASK_ISR_TO_SCHEDULER (1 << SYSVIEW_EVTID_ISR_TO_SCHEDULER)
|
||||
#define SYSVIEW_EVTMASK_TIMER_ENTER (1 << SYSVIEW_EVTID_TIMER_ENTER)
|
||||
#define SYSVIEW_EVTMASK_TIMER_EXIT (1 << SYSVIEW_EVTID_TIMER_EXIT)
|
||||
#define SYSVIEW_EVTMASK_STACK_INFO (1 << SYSVIEW_EVTID_STACK_INFO)
|
||||
#define SYSVIEW_EVTMASK_MODULEDESC (1 << SYSVIEW_EVTID_MODULEDESC)
|
||||
|
||||
#define SYSVIEW_EVTMASK_INIT (1 << SYSVIEW_EVTID_INIT)
|
||||
#define SYSVIEW_EVTMASK_NAME_RESOURCE (1 << SYSVIEW_EVTID_NAME_RESOURCE)
|
||||
#define SYSVIEW_EVTMASK_PRINT_FORMATTED (1 << SYSVIEW_EVTID_PRINT_FORMATTED)
|
||||
#define SYSVIEW_EVTMASK_NUMMODULES (1 << SYSVIEW_EVTID_NUMMODULES)
|
||||
#define SYSVIEW_EVTMASK_END_CALL (1 << SYSVIEW_EVTID_END_CALL)
|
||||
#define SYSVIEW_EVTMASK_TASK_TERMINATE (1 << SYSVIEW_EVTID_TASK_TERMINATE)
|
||||
|
||||
#define SYSVIEW_EVTMASK_EX (1 << SYSVIEW_EVTID_EX)
|
||||
|
||||
#define SYSVIEW_EVTMASK_ALL_INTERRUPTS ( SYSVIEW_EVTMASK_ISR_ENTER \
|
||||
| SYSVIEW_EVTMASK_ISR_EXIT \
|
||||
| SYSVIEW_EVTMASK_ISR_TO_SCHEDULER)
|
||||
#define SYSVIEW_EVTMASK_ALL_TASKS ( SYSVIEW_EVTMASK_TASK_START_EXEC \
|
||||
| SYSVIEW_EVTMASK_TASK_STOP_EXEC \
|
||||
| SYSVIEW_EVTMASK_TASK_START_READY \
|
||||
| SYSVIEW_EVTMASK_TASK_STOP_READY \
|
||||
| SYSVIEW_EVTMASK_TASK_CREATE \
|
||||
| SYSVIEW_EVTMASK_TASK_INFO \
|
||||
| SYSVIEW_EVTMASK_STACK_INFO \
|
||||
| SYSVIEW_EVTMASK_TASK_TERMINATE)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Structures
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
U32 TaskID;
|
||||
const char* sName;
|
||||
U32 Prio;
|
||||
U32 StackBase;
|
||||
U32 StackSize;
|
||||
} SEGGER_SYSVIEW_TASKINFO;
|
||||
|
||||
typedef struct SEGGER_SYSVIEW_MODULE_STRUCT SEGGER_SYSVIEW_MODULE;
|
||||
|
||||
struct SEGGER_SYSVIEW_MODULE_STRUCT {
|
||||
const char* sModule;
|
||||
U32 NumEvents;
|
||||
U32 EventOffset;
|
||||
void (*pfSendModuleDesc)(void);
|
||||
SEGGER_SYSVIEW_MODULE* pNext;
|
||||
};
|
||||
|
||||
typedef void (SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC)(void);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* API functions
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
U64 (*pfGetTime) (void);
|
||||
void (*pfSendTaskList) (void);
|
||||
} SEGGER_SYSVIEW_OS_API;
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Control and initialization functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_Init (U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API *pOSAPI, SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc);
|
||||
void SEGGER_SYSVIEW_SetRAMBase (U32 RAMBaseAddress);
|
||||
void SEGGER_SYSVIEW_Start (void);
|
||||
void SEGGER_SYSVIEW_Stop (void);
|
||||
void SEGGER_SYSVIEW_GetSysDesc (void);
|
||||
void SEGGER_SYSVIEW_SendTaskList (void);
|
||||
void SEGGER_SYSVIEW_SendTaskInfo (const SEGGER_SYSVIEW_TASKINFO* pInfo);
|
||||
void SEGGER_SYSVIEW_SendSysDesc (const char* sSysDesc);
|
||||
// Checks whether tracing has been started
|
||||
U8 SEGGER_SYSVIEW_Started(void);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Event recording functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_RecordVoid (unsigned int EventId);
|
||||
void SEGGER_SYSVIEW_RecordU32 (unsigned int EventId, U32 Para0);
|
||||
void SEGGER_SYSVIEW_RecordU32x2 (unsigned int EventId, U32 Para0, U32 Para1);
|
||||
void SEGGER_SYSVIEW_RecordU32x3 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2);
|
||||
void SEGGER_SYSVIEW_RecordU32x4 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3);
|
||||
void SEGGER_SYSVIEW_RecordU32x5 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4);
|
||||
void SEGGER_SYSVIEW_RecordU32x6 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5);
|
||||
void SEGGER_SYSVIEW_RecordU32x7 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6);
|
||||
void SEGGER_SYSVIEW_RecordU32x8 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7);
|
||||
void SEGGER_SYSVIEW_RecordU32x9 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8);
|
||||
void SEGGER_SYSVIEW_RecordU32x10 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8, U32 Para9);
|
||||
void SEGGER_SYSVIEW_RecordString (unsigned int EventId, const char* pString);
|
||||
void SEGGER_SYSVIEW_RecordSystime (void);
|
||||
void SEGGER_SYSVIEW_RecordEnterISR (U32 IrqId);
|
||||
void SEGGER_SYSVIEW_RecordExitISR (void);
|
||||
void SEGGER_SYSVIEW_RecordExitISRToScheduler (void);
|
||||
void SEGGER_SYSVIEW_RecordEnterTimer (U32 TimerId);
|
||||
void SEGGER_SYSVIEW_RecordExitTimer (void);
|
||||
void SEGGER_SYSVIEW_RecordEndCall (unsigned int EventID);
|
||||
void SEGGER_SYSVIEW_RecordEndCallU32 (unsigned int EventID, U32 Para0);
|
||||
|
||||
void SEGGER_SYSVIEW_OnIdle (void);
|
||||
void SEGGER_SYSVIEW_OnTaskCreate (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskTerminate (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskStartExec (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskStopExec (void);
|
||||
void SEGGER_SYSVIEW_OnTaskStartReady (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskStopReady (U32 TaskId, unsigned int Cause);
|
||||
void SEGGER_SYSVIEW_OnUserStart (unsigned int UserId); // Start of user defined event (such as a subroutine to profile)
|
||||
void SEGGER_SYSVIEW_OnUserStop (unsigned int UserId); // Start of user defined event
|
||||
|
||||
void SEGGER_SYSVIEW_NameResource (U32 ResourceId, const char* sName);
|
||||
|
||||
int SEGGER_SYSVIEW_SendPacket (U8* pPacket, U8* pPayloadEnd, unsigned int EventId);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Event parameter encoding functions
|
||||
*/
|
||||
U8* SEGGER_SYSVIEW_EncodeU32 (U8* pPayload, U32 Value);
|
||||
U8* SEGGER_SYSVIEW_EncodeData (U8* pPayload, const char* pSrc, unsigned int Len);
|
||||
U8* SEGGER_SYSVIEW_EncodeString (U8* pPayload, const char* s, unsigned int MaxLen);
|
||||
U8* SEGGER_SYSVIEW_EncodeId (U8* pPayload, U32 Id);
|
||||
U32 SEGGER_SYSVIEW_ShrinkId (U32 Id);
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Middleware module registration
|
||||
*/
|
||||
void SEGGER_SYSVIEW_RegisterModule (SEGGER_SYSVIEW_MODULE* pModule);
|
||||
void SEGGER_SYSVIEW_RecordModuleDescription (const SEGGER_SYSVIEW_MODULE* pModule, const char* sDescription);
|
||||
void SEGGER_SYSVIEW_SendModule (U8 ModuleId);
|
||||
void SEGGER_SYSVIEW_SendModuleDescription (void);
|
||||
void SEGGER_SYSVIEW_SendNumModules (void);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* printf-Style functions
|
||||
*/
|
||||
#ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
|
||||
void SEGGER_SYSVIEW_PrintfHostEx (const char* s, U32 Options, ...);
|
||||
void SEGGER_SYSVIEW_PrintfTargetEx (const char* s, U32 Options, ...);
|
||||
void SEGGER_SYSVIEW_PrintfHost (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_PrintfTarget (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_WarnfHost (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_WarnfTarget (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_ErrorfHost (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_ErrorfTarget (const char* s, ...);
|
||||
#endif
|
||||
|
||||
void SEGGER_SYSVIEW_Print (const char* s);
|
||||
void SEGGER_SYSVIEW_Warn (const char* s);
|
||||
void SEGGER_SYSVIEW_Error (const char* s);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Run-time configuration functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_EnableEvents (U32 EnableMask);
|
||||
void SEGGER_SYSVIEW_DisableEvents (U32 DisableMask);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Application-provided functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_Conf (void);
|
||||
U32 SEGGER_SYSVIEW_X_GetTimestamp (void);
|
||||
U32 SEGGER_SYSVIEW_X_GetInterruptId (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
File : SEGGER_SYSVIEW.h
|
||||
Purpose : System visualization API.
|
||||
Revision: $Rev: 5626 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_H
|
||||
#define SEGGER_SYSVIEW_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* #include Section
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "SEGGER.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, fixed
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#define SEGGER_SYSVIEW_VERSION 21000
|
||||
|
||||
#define SEGGER_SYSVIEW_INFO_SIZE 9 // Minimum size, which has to be reserved for a packet. 1-2 byte of message type, 0-2 byte of payload length, 1-5 bytes of timestamp.
|
||||
#define SEGGER_SYSVIEW_QUANTA_U32 5 // Maximum number of bytes to encode a U32, should be reserved for each 32-bit value in a packet.
|
||||
|
||||
#define SEGGER_SYSVIEW_LOG (0u)
|
||||
#define SEGGER_SYSVIEW_WARNING (1u)
|
||||
#define SEGGER_SYSVIEW_ERROR (2u)
|
||||
#define SEGGER_SYSVIEW_FLAG_APPEND (1u << 6)
|
||||
|
||||
#define SEGGER_SYSVIEW_PREPARE_PACKET(p) (p) + 4
|
||||
//
|
||||
// SystemView events. First 32 IDs from 0 .. 31 are reserved for these
|
||||
//
|
||||
#define SYSVIEW_EVTID_NOP 0 // Dummy packet.
|
||||
#define SYSVIEW_EVTID_OVERFLOW 1
|
||||
#define SYSVIEW_EVTID_ISR_ENTER 2
|
||||
#define SYSVIEW_EVTID_ISR_EXIT 3
|
||||
#define SYSVIEW_EVTID_TASK_START_EXEC 4
|
||||
#define SYSVIEW_EVTID_TASK_STOP_EXEC 5
|
||||
#define SYSVIEW_EVTID_TASK_START_READY 6
|
||||
#define SYSVIEW_EVTID_TASK_STOP_READY 7
|
||||
#define SYSVIEW_EVTID_TASK_CREATE 8
|
||||
#define SYSVIEW_EVTID_TASK_INFO 9
|
||||
#define SYSVIEW_EVTID_TRACE_START 10
|
||||
#define SYSVIEW_EVTID_TRACE_STOP 11
|
||||
#define SYSVIEW_EVTID_SYSTIME_CYCLES 12
|
||||
#define SYSVIEW_EVTID_SYSTIME_US 13
|
||||
#define SYSVIEW_EVTID_SYSDESC 14
|
||||
#define SYSVIEW_EVTID_USER_START 15
|
||||
#define SYSVIEW_EVTID_USER_STOP 16
|
||||
#define SYSVIEW_EVTID_IDLE 17
|
||||
#define SYSVIEW_EVTID_ISR_TO_SCHEDULER 18
|
||||
#define SYSVIEW_EVTID_TIMER_ENTER 19
|
||||
#define SYSVIEW_EVTID_TIMER_EXIT 20
|
||||
#define SYSVIEW_EVTID_STACK_INFO 21
|
||||
#define SYSVIEW_EVTID_MODULEDESC 22
|
||||
|
||||
#define SYSVIEW_EVTID_INIT 24
|
||||
#define SYSVIEW_EVTID_NAME_RESOURCE 25
|
||||
#define SYSVIEW_EVTID_PRINT_FORMATTED 26
|
||||
#define SYSVIEW_EVTID_NUMMODULES 27
|
||||
#define SYSVIEW_EVTID_END_CALL 28
|
||||
#define SYSVIEW_EVTID_TASK_TERMINATE 29
|
||||
|
||||
#define SYSVIEW_EVTID_EX 31
|
||||
//
|
||||
// Event masks to disable/enable events
|
||||
//
|
||||
#define SYSVIEW_EVTMASK_NOP (1 << SYSVIEW_EVTID_NOP)
|
||||
#define SYSVIEW_EVTMASK_OVERFLOW (1 << SYSVIEW_EVTID_OVERFLOW)
|
||||
#define SYSVIEW_EVTMASK_ISR_ENTER (1 << SYSVIEW_EVTID_ISR_ENTER)
|
||||
#define SYSVIEW_EVTMASK_ISR_EXIT (1 << SYSVIEW_EVTID_ISR_EXIT)
|
||||
#define SYSVIEW_EVTMASK_TASK_START_EXEC (1 << SYSVIEW_EVTID_TASK_START_EXEC)
|
||||
#define SYSVIEW_EVTMASK_TASK_STOP_EXEC (1 << SYSVIEW_EVTID_TASK_STOP_EXEC)
|
||||
#define SYSVIEW_EVTMASK_TASK_START_READY (1 << SYSVIEW_EVTID_TASK_START_READY)
|
||||
#define SYSVIEW_EVTMASK_TASK_STOP_READY (1 << SYSVIEW_EVTID_TASK_STOP_READY)
|
||||
#define SYSVIEW_EVTMASK_TASK_CREATE (1 << SYSVIEW_EVTID_TASK_CREATE)
|
||||
#define SYSVIEW_EVTMASK_TASK_INFO (1 << SYSVIEW_EVTID_TASK_INFO)
|
||||
#define SYSVIEW_EVTMASK_TRACE_START (1 << SYSVIEW_EVTID_TRACE_START)
|
||||
#define SYSVIEW_EVTMASK_TRACE_STOP (1 << SYSVIEW_EVTID_TRACE_STOP)
|
||||
#define SYSVIEW_EVTMASK_SYSTIME_CYCLES (1 << SYSVIEW_EVTID_SYSTIME_CYCLES)
|
||||
#define SYSVIEW_EVTMASK_SYSTIME_US (1 << SYSVIEW_EVTID_SYSTIME_US)
|
||||
#define SYSVIEW_EVTMASK_SYSDESC (1 << SYSVIEW_EVTID_SYSDESC)
|
||||
#define SYSVIEW_EVTMASK_USER_START (1 << SYSVIEW_EVTID_USER_START)
|
||||
#define SYSVIEW_EVTMASK_USER_STOP (1 << SYSVIEW_EVTID_USER_STOP)
|
||||
#define SYSVIEW_EVTMASK_IDLE (1 << SYSVIEW_EVTID_IDLE)
|
||||
#define SYSVIEW_EVTMASK_ISR_TO_SCHEDULER (1 << SYSVIEW_EVTID_ISR_TO_SCHEDULER)
|
||||
#define SYSVIEW_EVTMASK_TIMER_ENTER (1 << SYSVIEW_EVTID_TIMER_ENTER)
|
||||
#define SYSVIEW_EVTMASK_TIMER_EXIT (1 << SYSVIEW_EVTID_TIMER_EXIT)
|
||||
#define SYSVIEW_EVTMASK_STACK_INFO (1 << SYSVIEW_EVTID_STACK_INFO)
|
||||
#define SYSVIEW_EVTMASK_MODULEDESC (1 << SYSVIEW_EVTID_MODULEDESC)
|
||||
|
||||
#define SYSVIEW_EVTMASK_INIT (1 << SYSVIEW_EVTID_INIT)
|
||||
#define SYSVIEW_EVTMASK_NAME_RESOURCE (1 << SYSVIEW_EVTID_NAME_RESOURCE)
|
||||
#define SYSVIEW_EVTMASK_PRINT_FORMATTED (1 << SYSVIEW_EVTID_PRINT_FORMATTED)
|
||||
#define SYSVIEW_EVTMASK_NUMMODULES (1 << SYSVIEW_EVTID_NUMMODULES)
|
||||
#define SYSVIEW_EVTMASK_END_CALL (1 << SYSVIEW_EVTID_END_CALL)
|
||||
#define SYSVIEW_EVTMASK_TASK_TERMINATE (1 << SYSVIEW_EVTID_TASK_TERMINATE)
|
||||
|
||||
#define SYSVIEW_EVTMASK_EX (1 << SYSVIEW_EVTID_EX)
|
||||
|
||||
#define SYSVIEW_EVTMASK_ALL_INTERRUPTS ( SYSVIEW_EVTMASK_ISR_ENTER \
|
||||
| SYSVIEW_EVTMASK_ISR_EXIT \
|
||||
| SYSVIEW_EVTMASK_ISR_TO_SCHEDULER)
|
||||
#define SYSVIEW_EVTMASK_ALL_TASKS ( SYSVIEW_EVTMASK_TASK_START_EXEC \
|
||||
| SYSVIEW_EVTMASK_TASK_STOP_EXEC \
|
||||
| SYSVIEW_EVTMASK_TASK_START_READY \
|
||||
| SYSVIEW_EVTMASK_TASK_STOP_READY \
|
||||
| SYSVIEW_EVTMASK_TASK_CREATE \
|
||||
| SYSVIEW_EVTMASK_TASK_INFO \
|
||||
| SYSVIEW_EVTMASK_STACK_INFO \
|
||||
| SYSVIEW_EVTMASK_TASK_TERMINATE)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Structures
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
U32 TaskID;
|
||||
const char* sName;
|
||||
U32 Prio;
|
||||
U32 StackBase;
|
||||
U32 StackSize;
|
||||
} SEGGER_SYSVIEW_TASKINFO;
|
||||
|
||||
typedef struct SEGGER_SYSVIEW_MODULE_STRUCT SEGGER_SYSVIEW_MODULE;
|
||||
|
||||
struct SEGGER_SYSVIEW_MODULE_STRUCT {
|
||||
const char* sModule;
|
||||
U32 NumEvents;
|
||||
U32 EventOffset;
|
||||
void (*pfSendModuleDesc)(void);
|
||||
SEGGER_SYSVIEW_MODULE* pNext;
|
||||
};
|
||||
|
||||
typedef void (SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC)(void);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* API functions
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
U64 (*pfGetTime) (void);
|
||||
void (*pfSendTaskList) (void);
|
||||
} SEGGER_SYSVIEW_OS_API;
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Control and initialization functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_Init (U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API *pOSAPI, SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc);
|
||||
void SEGGER_SYSVIEW_SetRAMBase (U32 RAMBaseAddress);
|
||||
void SEGGER_SYSVIEW_Start (void);
|
||||
void SEGGER_SYSVIEW_Stop (void);
|
||||
void SEGGER_SYSVIEW_GetSysDesc (void);
|
||||
void SEGGER_SYSVIEW_SendTaskList (void);
|
||||
void SEGGER_SYSVIEW_SendTaskInfo (const SEGGER_SYSVIEW_TASKINFO* pInfo);
|
||||
void SEGGER_SYSVIEW_SendSysDesc (const char* sSysDesc);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Event recording functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_RecordVoid (unsigned int EventId);
|
||||
void SEGGER_SYSVIEW_RecordU32 (unsigned int EventId, U32 Para0);
|
||||
void SEGGER_SYSVIEW_RecordU32x2 (unsigned int EventId, U32 Para0, U32 Para1);
|
||||
void SEGGER_SYSVIEW_RecordU32x3 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2);
|
||||
void SEGGER_SYSVIEW_RecordU32x4 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3);
|
||||
void SEGGER_SYSVIEW_RecordU32x5 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4);
|
||||
void SEGGER_SYSVIEW_RecordU32x6 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5);
|
||||
void SEGGER_SYSVIEW_RecordU32x7 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6);
|
||||
void SEGGER_SYSVIEW_RecordU32x8 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7);
|
||||
void SEGGER_SYSVIEW_RecordU32x9 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8);
|
||||
void SEGGER_SYSVIEW_RecordU32x10 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8, U32 Para9);
|
||||
void SEGGER_SYSVIEW_RecordString (unsigned int EventId, const char* pString);
|
||||
void SEGGER_SYSVIEW_RecordSystime (void);
|
||||
void SEGGER_SYSVIEW_RecordEnterISR (U32 IrqId);
|
||||
void SEGGER_SYSVIEW_RecordExitISR (void);
|
||||
void SEGGER_SYSVIEW_RecordExitISRToScheduler (void);
|
||||
void SEGGER_SYSVIEW_RecordEnterTimer (U32 TimerId);
|
||||
void SEGGER_SYSVIEW_RecordExitTimer (void);
|
||||
void SEGGER_SYSVIEW_RecordEndCall (unsigned int EventID);
|
||||
void SEGGER_SYSVIEW_RecordEndCallU32 (unsigned int EventID, U32 Para0);
|
||||
|
||||
void SEGGER_SYSVIEW_OnIdle (void);
|
||||
void SEGGER_SYSVIEW_OnTaskCreate (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskTerminate (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskStartExec (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskStopExec (void);
|
||||
void SEGGER_SYSVIEW_OnTaskStartReady (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskStopReady (U32 TaskId, unsigned int Cause);
|
||||
void SEGGER_SYSVIEW_OnUserStart (unsigned int UserId); // Start of user defined event (such as a subroutine to profile)
|
||||
void SEGGER_SYSVIEW_OnUserStop (unsigned int UserId); // Start of user defined event
|
||||
|
||||
void SEGGER_SYSVIEW_NameResource (U32 ResourceId, const char* sName);
|
||||
|
||||
int SEGGER_SYSVIEW_SendPacket (U8* pPacket, U8* pPayloadEnd, unsigned int EventId);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Event parameter encoding functions
|
||||
*/
|
||||
U8* SEGGER_SYSVIEW_EncodeU32 (U8* pPayload, U32 Value);
|
||||
U8* SEGGER_SYSVIEW_EncodeData (U8* pPayload, const char* pSrc, unsigned int Len);
|
||||
U8* SEGGER_SYSVIEW_EncodeString (U8* pPayload, const char* s, unsigned int MaxLen);
|
||||
U8* SEGGER_SYSVIEW_EncodeId (U8* pPayload, U32 Id);
|
||||
U32 SEGGER_SYSVIEW_ShrinkId (U32 Id);
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Middleware module registration
|
||||
*/
|
||||
void SEGGER_SYSVIEW_RegisterModule (SEGGER_SYSVIEW_MODULE* pModule);
|
||||
void SEGGER_SYSVIEW_RecordModuleDescription (const SEGGER_SYSVIEW_MODULE* pModule, const char* sDescription);
|
||||
void SEGGER_SYSVIEW_SendModule (U8 ModuleId);
|
||||
void SEGGER_SYSVIEW_SendModuleDescription (void);
|
||||
void SEGGER_SYSVIEW_SendNumModules (void);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* printf-Style functions
|
||||
*/
|
||||
#ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
|
||||
void SEGGER_SYSVIEW_PrintfHostEx (const char* s, U32 Options, ...);
|
||||
void SEGGER_SYSVIEW_PrintfTargetEx (const char* s, U32 Options, ...);
|
||||
void SEGGER_SYSVIEW_PrintfHost (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_PrintfTarget (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_WarnfHost (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_WarnfTarget (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_ErrorfHost (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_ErrorfTarget (const char* s, ...);
|
||||
#endif
|
||||
|
||||
void SEGGER_SYSVIEW_Print (const char* s);
|
||||
void SEGGER_SYSVIEW_Warn (const char* s);
|
||||
void SEGGER_SYSVIEW_Error (const char* s);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Run-time configuration functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_EnableEvents (U32 EnableMask);
|
||||
void SEGGER_SYSVIEW_DisableEvents (U32 DisableMask);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Application-provided functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_Conf (void);
|
||||
U32 SEGGER_SYSVIEW_X_GetTimestamp (void);
|
||||
U32 SEGGER_SYSVIEW_X_GetInterruptId (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -1,178 +1,178 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
File : SEGGER_SYSVIEW_ConfDefaults.h
|
||||
Purpose : Defines defaults for configurable defines used in
|
||||
SEGGER SystemView.
|
||||
Revision: $Rev: 3734 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_CONFDEFAULTS_H
|
||||
#define SEGGER_SYSVIEW_CONFDEFAULTS_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* #include Section
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "SEGGER_SYSVIEW_Conf.h"
|
||||
#include "SEGGER_RTT_Conf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Configuration defaults
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
// Number of bytes that SystemView uses for a buffer.
|
||||
#ifndef SEGGER_SYSVIEW_RTT_BUFFER_SIZE
|
||||
#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024
|
||||
#endif
|
||||
|
||||
// The RTT channel that SystemView will use.
|
||||
#ifndef SEGGER_SYSVIEW_RTT_CHANNEL
|
||||
#define SEGGER_SYSVIEW_RTT_CHANNEL 0
|
||||
#endif
|
||||
// Sanity check of RTT channel
|
||||
#if (SEGGER_SYSVIEW_RTT_CHANNEL == 0) && (SEGGER_RTT_MAX_NUM_UP_BUFFERS < 2)
|
||||
#error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > 1!"
|
||||
#elif (SEGGER_SYSVIEW_RTT_CHANNEL >= SEGGER_RTT_MAX_NUM_UP_BUFFERS)
|
||||
#error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > SEGGER_SYSVIEW_RTT_CHANNEL!"
|
||||
#endif
|
||||
|
||||
// Place the SystemView buffer into its own/the RTT section
|
||||
#if !(defined SEGGER_SYSVIEW_BUFFER_SECTION) && (defined SEGGER_RTT_SECTION)
|
||||
#define SEGGER_SYSVIEW_BUFFER_SECTION SEGGER_RTT_SECTION
|
||||
#endif
|
||||
|
||||
// Retrieve a system timestamp. This gets the Cortex-M cycle counter.
|
||||
#ifndef SEGGER_SYSVIEW_GET_TIMESTAMP
|
||||
#error "SEGGER_SYSVIEW_GET_TIMESTAMP has to be defined in SEGGER_SYSVIEW_Conf.h!"
|
||||
#endif
|
||||
|
||||
// Define number of valid bits low-order delivered by clock source.
|
||||
#ifndef SEGGER_SYSVIEW_TIMESTAMP_BITS
|
||||
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32
|
||||
#endif
|
||||
|
||||
// Lowest Id reported by the Application.
|
||||
#ifndef SEGGER_SYSVIEW_ID_BASE
|
||||
#define SEGGER_SYSVIEW_ID_BASE 0
|
||||
#endif
|
||||
|
||||
// Number of bits to shift Ids to save bandwidth
|
||||
#ifndef SEGGER_SYSVIEW_ID_SHIFT
|
||||
#define SEGGER_SYSVIEW_ID_SHIFT 0
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_GET_INTERRUPT_ID
|
||||
#error "SEGGER_SYSVIEW_GET_INTERRUPT_ID has to be defined in SEGGER_SYSVIEW_Conf.h!"
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_MAX_ARGUMENTS
|
||||
#define SEGGER_SYSVIEW_MAX_ARGUMENTS 16
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_MAX_STRING_LEN
|
||||
#define SEGGER_SYSVIEW_MAX_STRING_LEN 128
|
||||
#endif
|
||||
|
||||
// Use a static buffer instead of a buffer on the stack for packets
|
||||
#ifndef SEGGER_SYSVIEW_USE_STATIC_BUFFER
|
||||
#define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1
|
||||
#endif
|
||||
|
||||
// Maximum packet size used by SystemView for the static buffer
|
||||
#ifndef SEGGER_SYSVIEW_MAX_PACKET_SIZE
|
||||
#define SEGGER_SYSVIEW_MAX_PACKET_SIZE SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_ARGUMENTS * SEGGER_SYSVIEW_QUANTA_U32
|
||||
#endif
|
||||
|
||||
// Use post-mortem analysis instead of real-time analysis
|
||||
#ifndef SEGGER_SYSVIEW_POST_MORTEM_MODE
|
||||
#define SEGGER_SYSVIEW_POST_MORTEM_MODE 0
|
||||
#endif
|
||||
|
||||
// Configure how frequently syncronization is sent
|
||||
#ifndef SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT
|
||||
#define SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT 8
|
||||
#endif
|
||||
|
||||
// Lock SystemView (nestable)
|
||||
#ifndef SEGGER_SYSVIEW_LOCK
|
||||
#define SEGGER_SYSVIEW_LOCK() SEGGER_RTT_LOCK()
|
||||
#endif
|
||||
|
||||
// Unlock SystemView (nestable)
|
||||
#ifndef SEGGER_SYSVIEW_UNLOCK
|
||||
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_RTT_UNLOCK()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
File : SEGGER_SYSVIEW_ConfDefaults.h
|
||||
Purpose : Defines defaults for configurable defines used in
|
||||
SEGGER SystemView.
|
||||
Revision: $Rev: 3734 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_CONFDEFAULTS_H
|
||||
#define SEGGER_SYSVIEW_CONFDEFAULTS_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* #include Section
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "SEGGER_SYSVIEW_Conf.h"
|
||||
#include "SEGGER_RTT_Conf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Configuration defaults
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
// Number of bytes that SystemView uses for a buffer.
|
||||
#ifndef SEGGER_SYSVIEW_RTT_BUFFER_SIZE
|
||||
#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024
|
||||
#endif
|
||||
|
||||
// The RTT channel that SystemView will use.
|
||||
#ifndef SEGGER_SYSVIEW_RTT_CHANNEL
|
||||
#define SEGGER_SYSVIEW_RTT_CHANNEL 0
|
||||
#endif
|
||||
// Sanity check of RTT channel
|
||||
#if (SEGGER_SYSVIEW_RTT_CHANNEL == 0) && (SEGGER_RTT_MAX_NUM_UP_BUFFERS < 2)
|
||||
#error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > 1!"
|
||||
#elif (SEGGER_SYSVIEW_RTT_CHANNEL >= SEGGER_RTT_MAX_NUM_UP_BUFFERS)
|
||||
#error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > SEGGER_SYSVIEW_RTT_CHANNEL!"
|
||||
#endif
|
||||
|
||||
// Place the SystemView buffer into its own/the RTT section
|
||||
#if !(defined SEGGER_SYSVIEW_BUFFER_SECTION) && (defined SEGGER_RTT_SECTION)
|
||||
#define SEGGER_SYSVIEW_BUFFER_SECTION SEGGER_RTT_SECTION
|
||||
#endif
|
||||
|
||||
// Retrieve a system timestamp. This gets the Cortex-M cycle counter.
|
||||
#ifndef SEGGER_SYSVIEW_GET_TIMESTAMP
|
||||
#error "SEGGER_SYSVIEW_GET_TIMESTAMP has to be defined in SEGGER_SYSVIEW_Conf.h!"
|
||||
#endif
|
||||
|
||||
// Define number of valid bits low-order delivered by clock source.
|
||||
#ifndef SEGGER_SYSVIEW_TIMESTAMP_BITS
|
||||
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32
|
||||
#endif
|
||||
|
||||
// Lowest Id reported by the Application.
|
||||
#ifndef SEGGER_SYSVIEW_ID_BASE
|
||||
#define SEGGER_SYSVIEW_ID_BASE 0
|
||||
#endif
|
||||
|
||||
// Number of bits to shift Ids to save bandwidth
|
||||
#ifndef SEGGER_SYSVIEW_ID_SHIFT
|
||||
#define SEGGER_SYSVIEW_ID_SHIFT 0
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_GET_INTERRUPT_ID
|
||||
#error "SEGGER_SYSVIEW_GET_INTERRUPT_ID has to be defined in SEGGER_SYSVIEW_Conf.h!"
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_MAX_ARGUMENTS
|
||||
#define SEGGER_SYSVIEW_MAX_ARGUMENTS 16
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_MAX_STRING_LEN
|
||||
#define SEGGER_SYSVIEW_MAX_STRING_LEN 128
|
||||
#endif
|
||||
|
||||
// Use a static buffer instead of a buffer on the stack for packets
|
||||
#ifndef SEGGER_SYSVIEW_USE_STATIC_BUFFER
|
||||
#define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1
|
||||
#endif
|
||||
|
||||
// Maximum packet size used by SystemView for the static buffer
|
||||
#ifndef SEGGER_SYSVIEW_MAX_PACKET_SIZE
|
||||
#define SEGGER_SYSVIEW_MAX_PACKET_SIZE SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_ARGUMENTS * SEGGER_SYSVIEW_QUANTA_U32
|
||||
#endif
|
||||
|
||||
// Use post-mortem analysis instead of real-time analysis
|
||||
#ifndef SEGGER_SYSVIEW_POST_MORTEM_MODE
|
||||
#define SEGGER_SYSVIEW_POST_MORTEM_MODE 0
|
||||
#endif
|
||||
|
||||
// Configure how frequently syncronization is sent
|
||||
#ifndef SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT
|
||||
#define SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT 8
|
||||
#endif
|
||||
|
||||
// Lock SystemView (nestable)
|
||||
#ifndef SEGGER_SYSVIEW_LOCK
|
||||
#define SEGGER_SYSVIEW_LOCK() SEGGER_RTT_LOCK()
|
||||
#endif
|
||||
|
||||
// Unlock SystemView (nestable)
|
||||
#ifndef SEGGER_SYSVIEW_UNLOCK
|
||||
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_RTT_UNLOCK()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -1,110 +1,110 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
File : SEGGER_SYSVIEW_Int.h
|
||||
Purpose : SEGGER SystemView internal header.
|
||||
Revision: $Rev: 5626 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_INT_H
|
||||
#define SEGGER_SYSVIEW_INT_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* #include Section
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "SEGGER_SYSVIEW.h"
|
||||
#include "SEGGER_SYSVIEW_Conf.h"
|
||||
#include "SEGGER_SYSVIEW_ConfDefaults.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Private data types
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
//
|
||||
// Commands that Host can send to target
|
||||
//
|
||||
typedef enum {
|
||||
SEGGER_SYSVIEW_COMMAND_ID_START = 1,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_STOP,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_SYSTIME,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_TASKLIST,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_SYSDESC,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_NUMMODULES,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_MODULEDESC,
|
||||
// Extended commands: Commands >= 128 have a second parameter
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_MODULE = 128
|
||||
} SEGGER_SYSVIEW_COMMAND_ID;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
File : SEGGER_SYSVIEW_Int.h
|
||||
Purpose : SEGGER SystemView internal header.
|
||||
Revision: $Rev: 5626 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_INT_H
|
||||
#define SEGGER_SYSVIEW_INT_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* #include Section
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "SEGGER_SYSVIEW.h"
|
||||
#include "SEGGER_SYSVIEW_Conf.h"
|
||||
#include "SEGGER_SYSVIEW_ConfDefaults.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Private data types
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
//
|
||||
// Commands that Host can send to target
|
||||
//
|
||||
typedef enum {
|
||||
SEGGER_SYSVIEW_COMMAND_ID_START = 1,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_STOP,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_SYSTIME,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_TASKLIST,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_SYSDESC,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_NUMMODULES,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_MODULEDESC,
|
||||
// Extended commands: Commands >= 128 have a second parameter
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_MODULE = 128
|
||||
} SEGGER_SYSVIEW_COMMAND_ID;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -61,22 +61,13 @@ File : SEGGER_SYSVIEW_Config_FreeRTOS.c
|
||||
Purpose : Sample setup configuration of SystemView with FreeRTOS.
|
||||
Revision: $Rev: 3734 $
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "SEGGER_SYSVIEW.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_app_trace_util.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/interrupts.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/clk.h"
|
||||
#endif
|
||||
|
||||
#include "esp_clk.h"
|
||||
|
||||
extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
|
||||
|
||||
@@ -90,18 +81,12 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
|
||||
#define SYSVIEW_APP_NAME "FreeRTOS Application"
|
||||
|
||||
// The target device name
|
||||
#define SYSVIEW_DEVICE_NAME CONFIG_IDF_TARGET
|
||||
// The target core name
|
||||
#if CONFIG_IDF_TARGET_ARCH_XTENSA
|
||||
#define SYSVIEW_CORE_NAME "xtensa"
|
||||
#elif CONFIG_IDF_TARGET_ARCH_RISCV
|
||||
#define SYSVIEW_CORE_NAME "riscv"
|
||||
#endif
|
||||
#define SYSVIEW_DEVICE_NAME "ESP32"
|
||||
|
||||
// Determine which timer to use as timestamp source
|
||||
#if CONFIG_APPTRACE_SV_TS_SOURCE_CCOUNT
|
||||
#if CONFIG_SYSVIEW_TS_SOURCE_CCOUNT
|
||||
#define TS_USE_CCOUNT 1
|
||||
#elif CONFIG_APPTRACE_SV_TS_SOURCE_ESP_TIMER
|
||||
#elif CONFIG_SYSVIEW_TS_SOURCE_ESP_TIMER
|
||||
#define TS_USE_ESP_TIMER 1
|
||||
#else
|
||||
#define TS_USE_TIMERGROUP 1
|
||||
@@ -117,13 +102,13 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
|
||||
#define SYSVIEW_TIMESTAMP_FREQ (esp_clk_apb_freq() / SYSVIEW_TIMER_DIV)
|
||||
|
||||
// Timer ID and group ID
|
||||
#if defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00) || defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_10)
|
||||
#if defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_00) || defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_01)
|
||||
#define TS_TIMER_ID 0
|
||||
#else
|
||||
#define TS_TIMER_ID 1
|
||||
#endif // TIMER_00 || TIMER_01
|
||||
|
||||
#if defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00) || defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_01)
|
||||
#if defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_00) || defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_10)
|
||||
#define TS_TIMER_GROUP 0
|
||||
#else
|
||||
#define TS_TIMER_GROUP 1
|
||||
@@ -138,20 +123,15 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
|
||||
|
||||
#if TS_USE_CCOUNT
|
||||
// CCOUNT is incremented at CPU frequency
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define SYSVIEW_TIMESTAMP_FREQ (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000)
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#define SYSVIEW_TIMESTAMP_FREQ (CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ * 1000000)
|
||||
#endif
|
||||
#endif // TS_USE_CCOUNT
|
||||
|
||||
// System Frequency.
|
||||
#define SYSVIEW_CPU_FREQ (esp_clk_cpu_freq())
|
||||
|
||||
// The lowest RAM address used for IDs (pointers)
|
||||
#define SYSVIEW_RAM_BASE (SOC_DROM_LOW)
|
||||
#define SYSVIEW_RAM_BASE (0x3F400000)
|
||||
|
||||
#ifdef CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER
|
||||
#if CONFIG_FREERTOS_CORETIMER_0
|
||||
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER0_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
||||
#endif
|
||||
@@ -159,10 +139,6 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
|
||||
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER1_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
||||
#endif
|
||||
|
||||
#elif CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER
|
||||
#define SYSTICK_INTR_ID (ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE)
|
||||
#endif // CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER
|
||||
|
||||
// SystemView is single core specific: it implies that SEGGER_SYSVIEW_LOCK()
|
||||
// disables IRQs (disables rescheduling globally). So we can not use finite timeouts for locks and return error
|
||||
// in case of expiration, because error will not be handled and SEGGER's code will go further implying that
|
||||
@@ -171,6 +147,78 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
|
||||
|
||||
static esp_apptrace_lock_t s_sys_view_lock = {.mux = portMUX_INITIALIZER_UNLOCKED, .int_state = 0};
|
||||
|
||||
static const char * const s_isr_names[] = {
|
||||
[0] = "WIFI_MAC",
|
||||
[1] = "WIFI_NMI",
|
||||
[2] = "WIFI_BB",
|
||||
[3] = "BT_MAC",
|
||||
[4] = "BT_BB",
|
||||
[5] = "BT_BB_NMI",
|
||||
[6] = "RWBT",
|
||||
[7] = "RWBLE",
|
||||
[8] = "RWBT_NMI",
|
||||
[9] = "RWBLE_NMI",
|
||||
[10] = "SLC0",
|
||||
[11] = "SLC1",
|
||||
[12] = "UHCI0",
|
||||
[13] = "UHCI1",
|
||||
[14] = "TG0_T0_LEVEL",
|
||||
[15] = "TG0_T1_LEVEL",
|
||||
[16] = "TG0_WDT_LEVEL",
|
||||
[17] = "TG0_LACT_LEVEL",
|
||||
[18] = "TG1_T0_LEVEL",
|
||||
[19] = "TG1_T1_LEVEL",
|
||||
[20] = "TG1_WDT_LEVEL",
|
||||
[21] = "TG1_LACT_LEVEL",
|
||||
[22] = "GPIO",
|
||||
[23] = "GPIO_NMI",
|
||||
[24] = "FROM_CPU0",
|
||||
[25] = "FROM_CPU1",
|
||||
[26] = "FROM_CPU2",
|
||||
[27] = "FROM_CPU3",
|
||||
[28] = "SPI0",
|
||||
[29] = "SPI1",
|
||||
[30] = "SPI2",
|
||||
[31] = "SPI3",
|
||||
[32] = "I2S0",
|
||||
[33] = "I2S1",
|
||||
[34] = "UART0",
|
||||
[35] = "UART1",
|
||||
[36] = "UART2",
|
||||
[37] = "SDIO_HOST",
|
||||
[38] = "ETH_MAC",
|
||||
[39] = "PWM0",
|
||||
[40] = "PWM1",
|
||||
[41] = "PWM2",
|
||||
[42] = "PWM3",
|
||||
[43] = "LEDC",
|
||||
[44] = "EFUSE",
|
||||
[45] = "CAN",
|
||||
[46] = "RTC_CORE",
|
||||
[47] = "RMT",
|
||||
[48] = "PCNT",
|
||||
[49] = "I2C_EXT0",
|
||||
[50] = "I2C_EXT1",
|
||||
[51] = "RSA",
|
||||
[52] = "SPI1_DMA",
|
||||
[53] = "SPI2_DMA",
|
||||
[54] = "SPI3_DMA",
|
||||
[55] = "WDT",
|
||||
[56] = "TIMER1",
|
||||
[57] = "TIMER2",
|
||||
[58] = "TG0_T0_EDGE",
|
||||
[59] = "TG0_T1_EDGE",
|
||||
[60] = "TG0_WDT_EDGE",
|
||||
[61] = "TG0_LACT_EDGE",
|
||||
[62] = "TG1_T0_EDGE",
|
||||
[63] = "TG1_T1_EDGE",
|
||||
[64] = "TG1_WDT_EDGE",
|
||||
[65] = "TG1_LACT_EDGE",
|
||||
[66] = "MMU_IA",
|
||||
[67] = "MPU_IA",
|
||||
[68] = "CACHE_IA",
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* _cbSendSystemDesc()
|
||||
@@ -180,14 +228,12 @@ static esp_apptrace_lock_t s_sys_view_lock = {.mux = portMUX_INITIALIZER_UNLOCKE
|
||||
*/
|
||||
static void _cbSendSystemDesc(void) {
|
||||
char irq_str[32];
|
||||
SEGGER_SYSVIEW_SendSysDesc("N="SYSVIEW_APP_NAME",D="SYSVIEW_DEVICE_NAME",C="SYSVIEW_CORE_NAME",O=FreeRTOS");
|
||||
SEGGER_SYSVIEW_SendSysDesc("N="SYSVIEW_APP_NAME",D="SYSVIEW_DEVICE_NAME",C=Xtensa,O=FreeRTOS");
|
||||
snprintf(irq_str, sizeof(irq_str), "I#%d=SysTick", SYSTICK_INTR_ID);
|
||||
SEGGER_SYSVIEW_SendSysDesc(irq_str);
|
||||
size_t isr_count = sizeof(esp_isr_names)/sizeof(esp_isr_names[0]);
|
||||
size_t isr_count = sizeof(s_isr_names)/sizeof(s_isr_names[0]);
|
||||
for (size_t i = 0; i < isr_count; ++i) {
|
||||
if (esp_isr_names[i] == NULL || (ETS_INTERNAL_INTR_SOURCE_OFF + i) == SYSTICK_INTR_ID)
|
||||
continue;
|
||||
snprintf(irq_str, sizeof(irq_str), "I#%d=%s", ETS_INTERNAL_INTR_SOURCE_OFF + i, esp_isr_names[i]);
|
||||
snprintf(irq_str, sizeof(irq_str), "I#%d=%s", ETS_INTERNAL_INTR_SOURCE_OFF + i, s_isr_names[i]);
|
||||
SEGGER_SYSVIEW_SendSysDesc(irq_str);
|
||||
}
|
||||
}
|
||||
@@ -198,7 +244,7 @@ static void _cbSendSystemDesc(void) {
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
static void SEGGER_SYSVIEW_TS_Init(void)
|
||||
static void SEGGER_SYSVIEW_TS_Init()
|
||||
{
|
||||
/* We only need to initialize something if we use Timer Group.
|
||||
* esp_timer and ccount can be used as is.
|
||||
@@ -228,49 +274,49 @@ void SEGGER_SYSVIEW_Conf(void) {
|
||||
&SYSVIEW_X_OS_TraceAPI, _cbSendSystemDesc);
|
||||
SEGGER_SYSVIEW_SetRAMBase(SYSVIEW_RAM_BASE);
|
||||
|
||||
#if !CONFIG_APPTRACE_SV_EVT_OVERFLOW_ENABLE
|
||||
#if !CONFIG_SYSVIEW_EVT_OVERFLOW_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_OVERFLOW;
|
||||
#endif
|
||||
#if !CONFIG_APPTRACE_SV_EVT_ISR_ENTER_ENABLE
|
||||
#if !CONFIG_SYSVIEW_EVT_ISR_ENTER_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_ISR_ENTER;
|
||||
#endif
|
||||
#if !CONFIG_APPTRACE_SV_EVT_ISR_EXIT_ENABLE
|
||||
#if !CONFIG_SYSVIEW_EVT_ISR_EXIT_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_ISR_EXIT;
|
||||
#endif
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TASK_START_EXEC_ENABLE
|
||||
#if !CONFIG_SYSVIEW_EVT_TASK_START_EXEC_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TASK_START_EXEC;
|
||||
#endif
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TASK_STOP_EXEC_ENABLE
|
||||
#if !CONFIG_SYSVIEW_EVT_TASK_STOP_EXEC_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TASK_STOP_EXEC;
|
||||
#endif
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TASK_START_READY_ENABLE
|
||||
#if !CONFIG_SYSVIEW_EVT_TASK_START_READY_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TASK_START_READY;
|
||||
#endif
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TASK_STOP_READY_ENABLE
|
||||
#if !CONFIG_SYSVIEW_EVT_TASK_STOP_READY_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TASK_STOP_READY;
|
||||
#endif
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TASK_CREATE_ENABLE
|
||||
#if !CONFIG_SYSVIEW_EVT_TASK_CREATE_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TASK_CREATE;
|
||||
#endif
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TASK_TERMINATE_ENABLE
|
||||
#if !CONFIG_SYSVIEW_EVT_TASK_TERMINATE_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TASK_TERMINATE;
|
||||
#endif
|
||||
#if !CONFIG_APPTRACE_SV_EVT_IDLE_ENABLE
|
||||
#if !CONFIG_SYSVIEW_EVT_IDLE_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_IDLE;
|
||||
#endif
|
||||
#if !CONFIG_APPTRACE_SV_EVT_ISR_TO_SCHED_ENABLE
|
||||
#if !CONFIG_SYSVIEW_EVT_ISR_TO_SCHEDULER_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_ISR_TO_SCHEDULER;
|
||||
#endif
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TIMER_ENTER_ENABLE
|
||||
#if !CONFIG_SYSVIEW_EVT_TIMER_ENTER_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TIMER_ENTER;
|
||||
#endif
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TIMER_EXIT_ENABLE
|
||||
#if !CONFIG_SYSVIEW_EVT_TIMER_EXIT_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TIMER_EXIT;
|
||||
#endif
|
||||
SEGGER_SYSVIEW_DisableEvents(disable_evts);
|
||||
}
|
||||
|
||||
U32 SEGGER_SYSVIEW_X_GetTimestamp(void)
|
||||
U32 SEGGER_SYSVIEW_X_GetTimestamp()
|
||||
{
|
||||
#if TS_USE_TIMERGROUP
|
||||
uint64_t ts = 0;
|
||||
@@ -283,26 +329,23 @@ U32 SEGGER_SYSVIEW_X_GetTimestamp(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void SEGGER_SYSVIEW_X_RTT_Lock(void)
|
||||
void SEGGER_SYSVIEW_X_RTT_Lock()
|
||||
{
|
||||
}
|
||||
|
||||
void SEGGER_SYSVIEW_X_RTT_Unlock(void)
|
||||
void SEGGER_SYSVIEW_X_RTT_Unlock()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned SEGGER_SYSVIEW_X_SysView_Lock(void)
|
||||
void SEGGER_SYSVIEW_X_SysView_Lock()
|
||||
{
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_tmo_init(&tmo, SEGGER_LOCK_WAIT_TMO);
|
||||
esp_apptrace_lock_take(&s_sys_view_lock, &tmo);
|
||||
// to be recursive save IRQ status on the stack of the caller to keep it from overwriting
|
||||
return s_sys_view_lock.int_state;
|
||||
}
|
||||
|
||||
void SEGGER_SYSVIEW_X_SysView_Unlock(unsigned int_state)
|
||||
void SEGGER_SYSVIEW_X_SysView_Unlock()
|
||||
{
|
||||
s_sys_view_lock.int_state = int_state;
|
||||
esp_apptrace_lock_give(&s_sys_view_lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,290 +1,290 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
|
||||
File : SEGGER_SYSVIEW_FreeRTOS.c
|
||||
Purpose : Interface between FreeRTOS and SystemView.
|
||||
Revision: $Rev: 3734 $
|
||||
*/
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "SEGGER_SYSVIEW.h"
|
||||
#include "SEGGER_SYSVIEW_FreeRTOS.h"
|
||||
#include "string.h" // Required for memset
|
||||
|
||||
|
||||
|
||||
typedef struct SYSVIEW_FREERTOS_TASK_STATUS SYSVIEW_FREERTOS_TASK_STATUS;
|
||||
|
||||
struct SYSVIEW_FREERTOS_TASK_STATUS {
|
||||
U32 xHandle;
|
||||
const char* pcTaskName;
|
||||
unsigned uxCurrentPriority;
|
||||
U32 pxStack;
|
||||
unsigned uStackHighWaterMark;
|
||||
};
|
||||
|
||||
static SYSVIEW_FREERTOS_TASK_STATUS _aTasks[SYSVIEW_FREERTOS_MAX_NOF_TASKS];
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* _cbSendTaskList()
|
||||
*
|
||||
* Function description
|
||||
* This function is part of the link between FreeRTOS and SYSVIEW.
|
||||
* Called from SystemView when asked by the host, it uses SYSVIEW
|
||||
* functions to send the entire task list to the host.
|
||||
*/
|
||||
static void _cbSendTaskList(void) {
|
||||
unsigned n;
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle) {
|
||||
#if INCLUDE_uxTaskGetStackHighWaterMark // Report Task Stack High Watermark
|
||||
_aTasks[n].uStackHighWaterMark = uxTaskGetStackHighWaterMark((TaskHandle_t)_aTasks[n].xHandle);
|
||||
#endif
|
||||
SYSVIEW_SendTaskInfo((U32)_aTasks[n].xHandle, _aTasks[n].pcTaskName, (unsigned)_aTasks[n].uxCurrentPriority, (U32)_aTasks[n].pxStack, (unsigned)_aTasks[n].uStackHighWaterMark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* _cbGetTime()
|
||||
*
|
||||
* Function description
|
||||
* This function is part of the link between FreeRTOS and SYSVIEW.
|
||||
* Called from SystemView when asked by the host, returns the
|
||||
* current system time in micro seconds.
|
||||
*/
|
||||
static U64 _cbGetTime(void) {
|
||||
U64 Time;
|
||||
|
||||
Time = xTaskGetTickCountFromISR();
|
||||
Time *= portTICK_PERIOD_MS;
|
||||
Time *= 1000;
|
||||
return Time;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Global functions
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_AddTask()
|
||||
*
|
||||
* Function description
|
||||
* Add a task to the internal list and record its information.
|
||||
*/
|
||||
void SYSVIEW_AddTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
|
||||
unsigned n;
|
||||
|
||||
if (memcmp(pcTaskName, "IDLE", 5) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
|
||||
SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not record task information. Maximum number of tasks reached.");
|
||||
return;
|
||||
}
|
||||
|
||||
_aTasks[n].xHandle = xHandle;
|
||||
_aTasks[n].pcTaskName = pcTaskName;
|
||||
_aTasks[n].uxCurrentPriority = uxCurrentPriority;
|
||||
_aTasks[n].pxStack = pxStack;
|
||||
_aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
|
||||
|
||||
SYSVIEW_SendTaskInfo(xHandle, pcTaskName,uxCurrentPriority, pxStack, uStackHighWaterMark);
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_UpdateTask()
|
||||
*
|
||||
* Function description
|
||||
* Update a task in the internal list and record its information.
|
||||
*/
|
||||
void SYSVIEW_UpdateTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
|
||||
unsigned n;
|
||||
|
||||
if (memcmp(pcTaskName, "IDLE", 5) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle == xHandle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n < SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
|
||||
_aTasks[n].pcTaskName = pcTaskName;
|
||||
_aTasks[n].uxCurrentPriority = uxCurrentPriority;
|
||||
_aTasks[n].pxStack = pxStack;
|
||||
_aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
|
||||
|
||||
SYSVIEW_SendTaskInfo(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
|
||||
} else {
|
||||
SYSVIEW_AddTask(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_DeleteTask()
|
||||
*
|
||||
* Function description
|
||||
* Delete a task from the internal list.
|
||||
*/
|
||||
void SYSVIEW_DeleteTask(U32 xHandle) {
|
||||
unsigned n;
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle == xHandle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
|
||||
SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not find task information. Cannot delete task.");
|
||||
return;
|
||||
}
|
||||
|
||||
_aTasks[n].xHandle = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_SendTaskInfo()
|
||||
*
|
||||
* Function description
|
||||
* Record task information.
|
||||
*/
|
||||
void SYSVIEW_SendTaskInfo(U32 TaskID, const char* sName, unsigned Prio, U32 StackBase, unsigned StackSize) {
|
||||
SEGGER_SYSVIEW_TASKINFO TaskInfo;
|
||||
|
||||
memset(&TaskInfo, 0, sizeof(TaskInfo)); // Fill all elements with 0 to allow extending the structure in future version without breaking the code
|
||||
TaskInfo.TaskID = TaskID;
|
||||
TaskInfo.sName = sName;
|
||||
TaskInfo.Prio = Prio;
|
||||
TaskInfo.StackBase = StackBase;
|
||||
TaskInfo.StackSize = StackSize;
|
||||
SEGGER_SYSVIEW_SendTaskInfo(&TaskInfo);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_RecordU32x4()
|
||||
*
|
||||
* Function description
|
||||
* Record an event with 4 parameters
|
||||
*/
|
||||
void SYSVIEW_RecordU32x4(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3) {
|
||||
U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32];
|
||||
U8* pPayload;
|
||||
//
|
||||
pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
|
||||
//
|
||||
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_RecordU32x5()
|
||||
*
|
||||
* Function description
|
||||
* Record an event with 5 parameters
|
||||
*/
|
||||
void SYSVIEW_RecordU32x5(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4) {
|
||||
U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32];
|
||||
U8* pPayload;
|
||||
//
|
||||
pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para4); // Add the fifth parameter to the packet
|
||||
//
|
||||
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Public API structures
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
// Callbacks provided to SYSTEMVIEW by FreeRTOS
|
||||
const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = {
|
||||
_cbGetTime,
|
||||
_cbSendTaskList,
|
||||
};
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
|
||||
File : SEGGER_SYSVIEW_FreeRTOS.c
|
||||
Purpose : Interface between FreeRTOS and SystemView.
|
||||
Revision: $Rev: 3734 $
|
||||
*/
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "SEGGER_SYSVIEW.h"
|
||||
#include "SEGGER_SYSVIEW_FreeRTOS.h"
|
||||
#include "string.h" // Required for memset
|
||||
|
||||
|
||||
|
||||
typedef struct SYSVIEW_FREERTOS_TASK_STATUS SYSVIEW_FREERTOS_TASK_STATUS;
|
||||
|
||||
struct SYSVIEW_FREERTOS_TASK_STATUS {
|
||||
U32 xHandle;
|
||||
const char* pcTaskName;
|
||||
unsigned uxCurrentPriority;
|
||||
U32 pxStack;
|
||||
unsigned uStackHighWaterMark;
|
||||
};
|
||||
|
||||
static SYSVIEW_FREERTOS_TASK_STATUS _aTasks[SYSVIEW_FREERTOS_MAX_NOF_TASKS];
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* _cbSendTaskList()
|
||||
*
|
||||
* Function description
|
||||
* This function is part of the link between FreeRTOS and SYSVIEW.
|
||||
* Called from SystemView when asked by the host, it uses SYSVIEW
|
||||
* functions to send the entire task list to the host.
|
||||
*/
|
||||
static void _cbSendTaskList(void) {
|
||||
unsigned n;
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle) {
|
||||
#if INCLUDE_uxTaskGetStackHighWaterMark // Report Task Stack High Watermark
|
||||
_aTasks[n].uStackHighWaterMark = uxTaskGetStackHighWaterMark((TaskHandle_t)_aTasks[n].xHandle);
|
||||
#endif
|
||||
SYSVIEW_SendTaskInfo((U32)_aTasks[n].xHandle, _aTasks[n].pcTaskName, (unsigned)_aTasks[n].uxCurrentPriority, (U32)_aTasks[n].pxStack, (unsigned)_aTasks[n].uStackHighWaterMark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* _cbGetTime()
|
||||
*
|
||||
* Function description
|
||||
* This function is part of the link between FreeRTOS and SYSVIEW.
|
||||
* Called from SystemView when asked by the host, returns the
|
||||
* current system time in micro seconds.
|
||||
*/
|
||||
static U64 _cbGetTime(void) {
|
||||
U64 Time;
|
||||
|
||||
Time = xTaskGetTickCountFromISR();
|
||||
Time *= portTICK_PERIOD_MS;
|
||||
Time *= 1000;
|
||||
return Time;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Global functions
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_AddTask()
|
||||
*
|
||||
* Function description
|
||||
* Add a task to the internal list and record its information.
|
||||
*/
|
||||
void SYSVIEW_AddTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
|
||||
unsigned n;
|
||||
|
||||
if (memcmp(pcTaskName, "IDLE", 5) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
|
||||
SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not record task information. Maximum number of tasks reached.");
|
||||
return;
|
||||
}
|
||||
|
||||
_aTasks[n].xHandle = xHandle;
|
||||
_aTasks[n].pcTaskName = pcTaskName;
|
||||
_aTasks[n].uxCurrentPriority = uxCurrentPriority;
|
||||
_aTasks[n].pxStack = pxStack;
|
||||
_aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
|
||||
|
||||
SYSVIEW_SendTaskInfo(xHandle, pcTaskName,uxCurrentPriority, pxStack, uStackHighWaterMark);
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_UpdateTask()
|
||||
*
|
||||
* Function description
|
||||
* Update a task in the internal list and record its information.
|
||||
*/
|
||||
void SYSVIEW_UpdateTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
|
||||
unsigned n;
|
||||
|
||||
if (memcmp(pcTaskName, "IDLE", 5) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle == xHandle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n < SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
|
||||
_aTasks[n].pcTaskName = pcTaskName;
|
||||
_aTasks[n].uxCurrentPriority = uxCurrentPriority;
|
||||
_aTasks[n].pxStack = pxStack;
|
||||
_aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
|
||||
|
||||
SYSVIEW_SendTaskInfo(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
|
||||
} else {
|
||||
SYSVIEW_AddTask(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_DeleteTask()
|
||||
*
|
||||
* Function description
|
||||
* Delete a task from the internal list.
|
||||
*/
|
||||
void SYSVIEW_DeleteTask(U32 xHandle) {
|
||||
unsigned n;
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle == xHandle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
|
||||
SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not find task information. Cannot delete task.");
|
||||
return;
|
||||
}
|
||||
|
||||
_aTasks[n].xHandle = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_SendTaskInfo()
|
||||
*
|
||||
* Function description
|
||||
* Record task information.
|
||||
*/
|
||||
void SYSVIEW_SendTaskInfo(U32 TaskID, const char* sName, unsigned Prio, U32 StackBase, unsigned StackSize) {
|
||||
SEGGER_SYSVIEW_TASKINFO TaskInfo;
|
||||
|
||||
memset(&TaskInfo, 0, sizeof(TaskInfo)); // Fill all elements with 0 to allow extending the structure in future version without breaking the code
|
||||
TaskInfo.TaskID = TaskID;
|
||||
TaskInfo.sName = sName;
|
||||
TaskInfo.Prio = Prio;
|
||||
TaskInfo.StackBase = StackBase;
|
||||
TaskInfo.StackSize = StackSize;
|
||||
SEGGER_SYSVIEW_SendTaskInfo(&TaskInfo);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_RecordU32x4()
|
||||
*
|
||||
* Function description
|
||||
* Record an event with 4 parameters
|
||||
*/
|
||||
void SYSVIEW_RecordU32x4(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3) {
|
||||
U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32];
|
||||
U8* pPayload;
|
||||
//
|
||||
pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
|
||||
//
|
||||
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_RecordU32x5()
|
||||
*
|
||||
* Function description
|
||||
* Record an event with 5 parameters
|
||||
*/
|
||||
void SYSVIEW_RecordU32x5(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4) {
|
||||
U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32];
|
||||
U8* pPayload;
|
||||
//
|
||||
pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para4); // Add the fifth parameter to the packet
|
||||
//
|
||||
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Public API structures
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
// Callbacks provided to SYSTEMVIEW by FreeRTOS
|
||||
const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = {
|
||||
_cbGetTime,
|
||||
_cbSendTaskList,
|
||||
};
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -80,7 +80,7 @@ Notes:
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#endif
|
||||
|
||||
#define SYSVIEW_FREERTOS_MAX_NOF_TASKS CONFIG_APPTRACE_SV_MAX_TASKS
|
||||
#define SYSVIEW_FREERTOS_MAX_NOF_TASKS 16
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
@@ -209,7 +209,7 @@ Notes:
|
||||
#define apiID_VEVENTGROUPDELETE (72u)
|
||||
#define apiID_UXEVENTGROUPGETNUMBER (73u)
|
||||
|
||||
#define traceTASK_NOTIFY_TAKE( uxIndexToWait ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_ULTASKNOTIFYTAKE, xClearCountOnExit, xTicksToWait)
|
||||
#define traceTASK_NOTIFY_TAKE() SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_ULTASKNOTIFYTAKE, xClearCountOnExit, xTicksToWait)
|
||||
#define traceTASK_DELAY() SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKDELAY, xTicksToDelay)
|
||||
#define traceTASK_DELAY_UNTIL() SEGGER_SYSVIEW_RecordVoid(apiFastID_OFFSET + apiID_VTASKDELAYUNTIL)
|
||||
#define traceTASK_DELETE( pxTCB ) if (pxTCB != NULL) { \
|
||||
@@ -217,25 +217,24 @@ Notes:
|
||||
SEGGER_SYSVIEW_ShrinkId((U32)pxTCB)); \
|
||||
SYSVIEW_DeleteTask((U32)pxTCB); \
|
||||
}
|
||||
#define traceTASK_NOTIFY_GIVE_FROM_ISR( uxIndexToNotify ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_VTASKNOTIFYGIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceTASK_NOTIFY_GIVE_FROM_ISR() SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_VTASKNOTIFYGIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceTASK_PRIORITY_INHERIT( pxTCB, uxPriority ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKPRIORITYINHERIT, (U32)pxMutexHolder)
|
||||
#define traceTASK_RESUME( pxTCB ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKRESUME, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB))
|
||||
#define traceINCREASE_TICK_COUNT( xTicksToJump ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKSTEPTICK, xTicksToJump)
|
||||
#define traceTASK_SUSPEND( pxTCB ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VTASKSUSPEND, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB))
|
||||
#define traceTASK_PRIORITY_DISINHERIT( pxTCB, uxBasePriority ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_XTASKPRIORITYDISINHERIT, (U32)pxMutexHolder)
|
||||
#define traceTASK_RESUME_FROM_ISR( pxTCB ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_XTASKRESUMEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB))
|
||||
#define traceTASK_NOTIFY( uxIndexToNotify ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XTASKGENERICNOTIFY, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), ulValue, eAction, (U32)pulPreviousNotificationValue)
|
||||
#define traceTASK_NOTIFY_FROM_ISR( uxIndexToNotify ) SYSVIEW_RecordU32x5(apiFastID_OFFSET + apiID_XTASKGENERICNOTIFYFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), ulValue, eAction, (U32)pulPreviousNotificationValue, (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceTASK_NOTIFY_WAIT( uxIndexToWait ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XTASKNOTIFYWAIT, ulBitsToClearOnEntry, ulBitsToClearOnExit, (U32)pulNotificationValue, xTicksToWait)
|
||||
#define traceTASK_NOTIFY() SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XTASKGENERICNOTIFY, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), ulValue, eAction, (U32)pulPreviousNotificationValue)
|
||||
#define traceTASK_NOTIFY_FROM_ISR() SYSVIEW_RecordU32x5(apiFastID_OFFSET + apiID_XTASKGENERICNOTIFYFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxTCB), ulValue, eAction, (U32)pulPreviousNotificationValue, (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceTASK_NOTIFY_WAIT() SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XTASKNOTIFYWAIT, ulBitsToClearOnEntry, ulBitsToClearOnExit, (U32)pulNotificationValue, xTicksToWait)
|
||||
|
||||
#define traceQUEUE_CREATE( pxNewQueue ) SEGGER_SYSVIEW_RecordU32x3(apiFastID_OFFSET + apiID_XQUEUEGENERICCREATE, uxQueueLength, uxItemSize, ucQueueType)
|
||||
#define traceQUEUE_DELETE( pxQueue ) SEGGER_SYSVIEW_RecordU32(apiFastID_OFFSET + apiID_VQUEUEDELETE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue))
|
||||
#define traceQUEUE_PEEK( pxQueue ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), xTicksToWait, 0)
|
||||
#define traceQUEUE_PEEK( pxQueue ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), xTicksToWait, xJustPeeking)
|
||||
#define traceQUEUE_PEEK_FROM_ISR( pxQueue ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_XQUEUEPEEKFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer))
|
||||
#define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_XQUEUEPEEKFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer))
|
||||
#define traceQUEUE_RECEIVE( pxQueue ) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)0), xTicksToWait, 1)
|
||||
#define traceQUEUE_RECEIVE_FAILED( pxQueue ) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)0), xTicksToWait, 1)
|
||||
#define traceQUEUE_SEMAPHORE_RECEIVE( pxQueue ) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)0), xTicksToWait, 0)
|
||||
#define traceQUEUE_RECEIVE( pxQueue ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), xTicksToWait, xJustPeeking)
|
||||
#define traceQUEUE_RECEIVE_FAILED( pxQueue ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICRECEIVE, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), xTicksToWait, xJustPeeking)
|
||||
#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) SEGGER_SYSVIEW_RecordU32x3(apiFastID_OFFSET + apiID_XQUEUERECEIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) SEGGER_SYSVIEW_RecordU32x3(apiFastID_OFFSET + apiID_XQUEUERECEIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), SEGGER_SYSVIEW_ShrinkId((U32)pvBuffer), (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_VQUEUEADDTOREGISTRY, SEGGER_SYSVIEW_ShrinkId((U32)xQueue), (U32)pcQueueName)
|
||||
@@ -245,10 +244,8 @@ Notes:
|
||||
#define traceQUEUE_SEND( pxQueue ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSEND, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), 0, 0, xCopyPosition)
|
||||
#endif
|
||||
#define traceQUEUE_SEND_FAILED( pxQueue ) SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSEND, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pvItemToQueue, xTicksToWait, xCopyPosition)
|
||||
#define traceQUEUE_SEND_FROM_ISR( pxQueue ) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSENDFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pvItemToQueue, (U32)pxHigherPriorityTaskWoken, xCopyPosition)
|
||||
#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) SEGGER_SYSVIEW_RecordU32x4(apiFastID_OFFSET + apiID_XQUEUEGENERICSENDFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pvItemToQueue, (U32)pxHigherPriorityTaskWoken, xCopyPosition)
|
||||
#define traceQUEUE_GIVE_FROM_ISR( pxQueue ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_XQUEUEGIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceQUEUE_GIVE_FROM_ISR_FAILED( pxQueue ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_XQUEUEGIVEFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceQUEUE_SEND_FROM_ISR( pxQueue ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_XQUEUEGENERICSENDFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pxHigherPriorityTaskWoken)
|
||||
#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) SEGGER_SYSVIEW_RecordU32x2(apiFastID_OFFSET + apiID_XQUEUEGENERICSENDFROMISR, SEGGER_SYSVIEW_ShrinkId((U32)pxQueue), (U32)pxHigherPriorityTaskWoken)
|
||||
|
||||
#if( portSTACK_GROWTH < 0 )
|
||||
#define traceTASK_CREATE(pxNewTCB) if (pxNewTCB != NULL) { \
|
||||
@@ -290,12 +287,12 @@ Notes:
|
||||
#define traceTASK_SWITCHED_IN() if(prvGetTCBFromHandle(NULL) == xTaskGetIdleTaskHandle()) { \
|
||||
SEGGER_SYSVIEW_OnIdle(); \
|
||||
} else { \
|
||||
SEGGER_SYSVIEW_OnTaskStartExec((U32)pxCurrentTCB[cpu_hal_get_core_id()]); \
|
||||
SEGGER_SYSVIEW_OnTaskStartExec((U32)pxCurrentTCB[xPortGetCoreID()]); \
|
||||
}
|
||||
#else
|
||||
#define traceTASK_SWITCHED_IN() { \
|
||||
if (memcmp(pxCurrentTCB[cpu_hal_get_core_id()]->pcTaskName, "IDLE", 5) != 0) { \
|
||||
SEGGER_SYSVIEW_OnTaskStartExec((U32)pxCurrentTCB[cpu_hal_get_core_id()]); \
|
||||
if (memcmp(pxCurrentTCB[xPortGetCoreID()]->pcTaskName, "IDLE", 5) != 0) { \
|
||||
SEGGER_SYSVIEW_OnTaskStartExec((U32)pxCurrentTCB[xPortGetCoreID()]); \
|
||||
} else { \
|
||||
SEGGER_SYSVIEW_OnIdle(); \
|
||||
} \
|
||||
@@ -305,15 +302,14 @@ Notes:
|
||||
#define traceMOVED_TASK_TO_READY_STATE(pxTCB) SEGGER_SYSVIEW_OnTaskStartReady((U32)pxTCB)
|
||||
#define traceREADDED_TASK_TO_READY_STATE(pxTCB)
|
||||
|
||||
#define traceMOVED_TASK_TO_DELAYED_LIST() SEGGER_SYSVIEW_OnTaskStopReady((U32)pxCurrentTCB[cpu_hal_get_core_id()], (1u << 2))
|
||||
#define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST() SEGGER_SYSVIEW_OnTaskStopReady((U32)pxCurrentTCB[cpu_hal_get_core_id()], (1u << 2))
|
||||
#define traceMOVED_TASK_TO_DELAYED_LIST() SEGGER_SYSVIEW_OnTaskStopReady((U32)pxCurrentTCB[xPortGetCoreID()], (1u << 2))
|
||||
#define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST() SEGGER_SYSVIEW_OnTaskStopReady((U32)pxCurrentTCB[xPortGetCoreID()], (1u << 2))
|
||||
#define traceMOVED_TASK_TO_SUSPENDED_LIST(pxTCB) SEGGER_SYSVIEW_OnTaskStopReady((U32)pxTCB, ((3u << 3) | 3))
|
||||
|
||||
#define traceISR_EXIT_TO_SCHEDULER() SEGGER_SYSVIEW_RecordExitISRToScheduler()
|
||||
#define traceISR_EXIT() SEGGER_SYSVIEW_RecordExitISR()
|
||||
#define traceISR_ENTER(_n_) SEGGER_SYSVIEW_RecordEnterISR(_n_)
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* API functions
|
||||
|
||||
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "string.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "SEGGER_RTT.h"
|
||||
#include "SEGGER_SYSVIEW.h"
|
||||
#include "SEGGER_SYSVIEW_Conf.h"
|
||||
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
const static char *TAG = "segger_rtt";
|
||||
|
||||
#define SYSVIEW_EVENTS_BUF_SZ 255U
|
||||
|
||||
// size of down channel data buf
|
||||
#define SYSVIEW_DOWN_BUF_SIZE 32
|
||||
#define SEGGER_STOP_WAIT_TMO 1000000 //us
|
||||
#if CONFIG_APPTRACE_SV_BUF_WAIT_TMO == -1
|
||||
#define SEGGER_HOST_WAIT_TMO ESP_APPTRACE_TMO_INFINITE
|
||||
#else
|
||||
#define SEGGER_HOST_WAIT_TMO CONFIG_APPTRACE_SV_BUF_WAIT_TMO
|
||||
#endif
|
||||
|
||||
static uint8_t s_events_buf[SYSVIEW_EVENTS_BUF_SZ];
|
||||
static uint16_t s_events_buf_filled;
|
||||
static uint8_t s_down_buf[SYSVIEW_DOWN_BUF_SIZE];
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Public code
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_ESP_FlushNoLock()
|
||||
*
|
||||
* Function description
|
||||
* Flushes buffered events.
|
||||
*
|
||||
* Parameters
|
||||
* min_sz Threshold for flushing data. If current filling level is above this value, data will be flushed. TRAX destinations only.
|
||||
* tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* Return value
|
||||
* None.
|
||||
*/
|
||||
void SEGGER_RTT_ESP_FlushNoLock(unsigned long min_sz, unsigned long tmo)
|
||||
{
|
||||
esp_err_t res;
|
||||
if (s_events_buf_filled > 0) {
|
||||
res = esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, s_events_buf, s_events_buf_filled, tmo);
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to flush buffered events (%d)!\n", res);
|
||||
}
|
||||
}
|
||||
// flush even if we failed to write buffered events, because no new events will be sent after STOP
|
||||
res = esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, min_sz, tmo);
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to flush apptrace data (%d)!\n", res);
|
||||
}
|
||||
s_events_buf_filled = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_ESP_Flush()
|
||||
*
|
||||
* Function description
|
||||
* Flushes buffered events.
|
||||
*
|
||||
* Parameters
|
||||
* min_sz Threshold for flushing data. If current filling level is above this value, data will be flushed. TRAX destinations only.
|
||||
* tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* Return value
|
||||
* None.
|
||||
*/
|
||||
void SEGGER_RTT_ESP_Flush(unsigned long min_sz, unsigned long tmo)
|
||||
{
|
||||
SEGGER_SYSVIEW_LOCK();
|
||||
SEGGER_RTT_ESP_FlushNoLock(min_sz, tmo);
|
||||
SEGGER_SYSVIEW_UNLOCK();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_ReadNoLock()
|
||||
*
|
||||
* Function description
|
||||
* Reads characters from SEGGER real-time-terminal control block
|
||||
* which have been previously stored by the host.
|
||||
* Do not lock against interrupts and multiple access.
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal").
|
||||
* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
|
||||
* BufferSize Size of the target application buffer.
|
||||
*
|
||||
* Return value
|
||||
* Number of bytes that have been read.
|
||||
*/
|
||||
unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) {
|
||||
uint32_t size = BufferSize;
|
||||
esp_err_t res = esp_apptrace_read(ESP_APPTRACE_DEST_TRAX, pData, &size, 0);
|
||||
if (res != ESP_OK) {
|
||||
return 0;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_WriteSkipNoLock
|
||||
*
|
||||
* Function description
|
||||
* Stores a specified number of characters in SEGGER RTT
|
||||
* control block which is then read by the host.
|
||||
* SEGGER_RTT_WriteSkipNoLock does not lock the application and
|
||||
* skips all data, if the data does not fit into the buffer.
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
|
||||
* pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
|
||||
* NumBytes Number of bytes to be stored in the SEGGER RTT control block.
|
||||
*
|
||||
* Return value
|
||||
* Number of bytes which have been stored in the "Up"-buffer.
|
||||
*
|
||||
* Notes
|
||||
* (1) If there is not enough space in the "Up"-buffer, all data is dropped.
|
||||
* (2) For performance reasons this function does not call Init()
|
||||
* and may only be called after RTT has been initialized.
|
||||
* Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
|
||||
*/
|
||||
unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
|
||||
uint8_t *pbuf = (uint8_t *)pBuffer;
|
||||
uint8_t event_id = *pbuf;
|
||||
|
||||
if (NumBytes > SYSVIEW_EVENTS_BUF_SZ) {
|
||||
ESP_LOGE(TAG, "Too large event %u bytes!", NumBytes);
|
||||
return 0;
|
||||
}
|
||||
if (cpu_hal_get_core_id()) { // dual core specific code
|
||||
// use the highest - 1 bit of event ID to indicate core ID
|
||||
// the highest bit can not be used due to event ID encoding method
|
||||
// this reduces supported ID range to [0..63] (for 1 byte IDs) plus [128..16383] (for 2 bytes IDs)
|
||||
if (*pbuf & 0x80) { // 2 bytes ID
|
||||
*(pbuf + 1) |= (1 << 6);
|
||||
} else if (NumBytes != 10 || *pbuf != 0) { // ignore sync sequence
|
||||
*pbuf |= (1 << 6);
|
||||
}
|
||||
}
|
||||
if (s_events_buf_filled + NumBytes > SYSVIEW_EVENTS_BUF_SZ) {
|
||||
esp_err_t res = esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, s_events_buf, s_events_buf_filled, SEGGER_HOST_WAIT_TMO);
|
||||
if (res != ESP_OK) {
|
||||
return 0; // skip current data buffer only, accumulated events are kept
|
||||
}
|
||||
s_events_buf_filled = 0;
|
||||
}
|
||||
memcpy(&s_events_buf[s_events_buf_filled], pBuffer, NumBytes);
|
||||
s_events_buf_filled += NumBytes;
|
||||
if (event_id == SYSVIEW_EVTID_TRACE_STOP) {
|
||||
SEGGER_RTT_ESP_FlushNoLock(0, SEGGER_STOP_WAIT_TMO);
|
||||
}
|
||||
return NumBytes;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_ConfigUpBuffer
|
||||
*
|
||||
* Function description
|
||||
* Run-time configuration of a specific up-buffer (T->H).
|
||||
* Buffer to be configured is specified by index.
|
||||
* This includes: Buffer address, size, name, flags, ...
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of the buffer to configure.
|
||||
* sName Pointer to a constant name string.
|
||||
* pBuffer Pointer to a buffer to be used.
|
||||
* BufferSize Size of the buffer.
|
||||
* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
|
||||
*
|
||||
* Return value
|
||||
* >= 0 - O.K.
|
||||
* < 0 - Error
|
||||
*
|
||||
* Additional information
|
||||
* Buffer 0 is configured on compile-time.
|
||||
* May only be called once per buffer.
|
||||
* Buffer name and flags can be reconfigured using the appropriate functions.
|
||||
*/
|
||||
int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
|
||||
s_events_buf_filled = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_ConfigDownBuffer
|
||||
*
|
||||
* Function description
|
||||
* Run-time configuration of a specific down-buffer (H->T).
|
||||
* Buffer to be configured is specified by index.
|
||||
* This includes: Buffer address, size, name, flags, ...
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of the buffer to configure.
|
||||
* sName Pointer to a constant name string.
|
||||
* pBuffer Pointer to a buffer to be used.
|
||||
* BufferSize Size of the buffer.
|
||||
* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
|
||||
*
|
||||
* Return value
|
||||
* >= 0 O.K.
|
||||
* < 0 Error
|
||||
*
|
||||
* Additional information
|
||||
* Buffer 0 is configured on compile-time.
|
||||
* May only be called once per buffer.
|
||||
* Buffer name and flags can be reconfigured using the appropriate functions.
|
||||
*/
|
||||
int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
|
||||
esp_apptrace_down_buffer_config(s_down_buf, sizeof(s_down_buf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
215
components/app_trace/sys_view/esp32/SEGGER_RTT_esp32.c
Normal file
215
components/app_trace/sys_view/esp32/SEGGER_RTT_esp32.c
Normal file
@@ -0,0 +1,215 @@
|
||||
// Copyright 2017 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 "string.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "SEGGER_RTT.h"
|
||||
#include "SEGGER_SYSVIEW.h"
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
#include "esp_app_trace.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "segger_rtt";
|
||||
|
||||
#define SYSVIEW_EVENTS_BUF_SZ 255U
|
||||
|
||||
// size of down channel data buf
|
||||
#define SYSVIEW_DOWN_BUF_SIZE 32
|
||||
#define SEGGER_HOST_WAIT_TMO 500 //us
|
||||
#define SEGGER_STOP_WAIT_TMO 1000000 //us
|
||||
|
||||
static uint8_t s_events_buf[SYSVIEW_EVENTS_BUF_SZ];
|
||||
static uint16_t s_events_buf_filled;
|
||||
static uint8_t s_down_buf[SYSVIEW_DOWN_BUF_SIZE];
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Public code
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_ESP32_FlushNoLock()
|
||||
*
|
||||
* Function description
|
||||
* Flushes buffered events.
|
||||
*
|
||||
* Parameters
|
||||
* min_sz Threshold for flushing data. If current filling level is above this value, data will be flushed. TRAX destinations only.
|
||||
* tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* Return value
|
||||
* None.
|
||||
*/
|
||||
void SEGGER_RTT_ESP32_FlushNoLock(unsigned long min_sz, unsigned long tmo)
|
||||
{
|
||||
esp_err_t res = esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, s_events_buf, s_events_buf_filled, tmo);
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to flush buffered events (%d)!\n", res);
|
||||
}
|
||||
// flush even if we failed to write buffered events, because no new events will be sent after STOP
|
||||
res = esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, min_sz, tmo);
|
||||
if (res != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to flush apptrace data (%d)!\n", res);
|
||||
}
|
||||
s_events_buf_filled = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_ReadNoLock()
|
||||
*
|
||||
* Function description
|
||||
* Reads characters from SEGGER real-time-terminal control block
|
||||
* which have been previously stored by the host.
|
||||
* Do not lock against interrupts and multiple access.
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal").
|
||||
* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
|
||||
* BufferSize Size of the target application buffer.
|
||||
*
|
||||
* Return value
|
||||
* Number of bytes that have been read.
|
||||
*/
|
||||
unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) {
|
||||
uint32_t size = BufferSize;
|
||||
esp_err_t res = esp_apptrace_read(ESP_APPTRACE_DEST_TRAX, pData, &size, 0);
|
||||
if (res != ESP_OK) {
|
||||
return 0;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_WriteSkipNoLock
|
||||
*
|
||||
* Function description
|
||||
* Stores a specified number of characters in SEGGER RTT
|
||||
* control block which is then read by the host.
|
||||
* SEGGER_RTT_WriteSkipNoLock does not lock the application and
|
||||
* skips all data, if the data does not fit into the buffer.
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
|
||||
* pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
|
||||
* NumBytes Number of bytes to be stored in the SEGGER RTT control block.
|
||||
*
|
||||
* Return value
|
||||
* Number of bytes which have been stored in the "Up"-buffer.
|
||||
*
|
||||
* Notes
|
||||
* (1) If there is not enough space in the "Up"-buffer, all data is dropped.
|
||||
* (2) For performance reasons this function does not call Init()
|
||||
* and may only be called after RTT has been initialized.
|
||||
* Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
|
||||
*/
|
||||
unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
|
||||
uint8_t *pbuf = (uint8_t *)pBuffer;
|
||||
uint8_t event_id = *pbuf;
|
||||
|
||||
if (NumBytes > SYSVIEW_EVENTS_BUF_SZ) {
|
||||
ESP_LOGE(TAG, "Too large event %u bytes!", NumBytes);
|
||||
return 0;
|
||||
}
|
||||
if (xPortGetCoreID()) { // dual core specific code
|
||||
// use the highest - 1 bit of event ID to indicate core ID
|
||||
// the highest bit can not be used due to event ID encoding method
|
||||
// this reduces supported ID range to [0..63] (for 1 byte IDs) plus [128..16383] (for 2 bytes IDs)
|
||||
if (*pbuf & 0x80) { // 2 bytes ID
|
||||
*(pbuf + 1) |= (1 << 6);
|
||||
} else if (NumBytes != 10 || *pbuf != 0) { // ignore sync sequence
|
||||
*pbuf |= (1 << 6);
|
||||
}
|
||||
}
|
||||
if (s_events_buf_filled + NumBytes > SYSVIEW_EVENTS_BUF_SZ) {
|
||||
esp_err_t res = esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, s_events_buf, s_events_buf_filled, SEGGER_HOST_WAIT_TMO);
|
||||
if (res != ESP_OK) {
|
||||
return 0; // skip current data buffer only, accumulated events are kept
|
||||
}
|
||||
s_events_buf_filled = 0;
|
||||
}
|
||||
memcpy(&s_events_buf[s_events_buf_filled], pBuffer, NumBytes);
|
||||
s_events_buf_filled += NumBytes;
|
||||
if (event_id == SYSVIEW_EVTID_TRACE_STOP) {
|
||||
SEGGER_RTT_ESP32_FlushNoLock(0, SEGGER_STOP_WAIT_TMO);
|
||||
}
|
||||
return NumBytes;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_ConfigUpBuffer
|
||||
*
|
||||
* Function description
|
||||
* Run-time configuration of a specific up-buffer (T->H).
|
||||
* Buffer to be configured is specified by index.
|
||||
* This includes: Buffer address, size, name, flags, ...
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of the buffer to configure.
|
||||
* sName Pointer to a constant name string.
|
||||
* pBuffer Pointer to a buffer to be used.
|
||||
* BufferSize Size of the buffer.
|
||||
* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
|
||||
*
|
||||
* Return value
|
||||
* >= 0 - O.K.
|
||||
* < 0 - Error
|
||||
*
|
||||
* Additional information
|
||||
* Buffer 0 is configured on compile-time.
|
||||
* May only be called once per buffer.
|
||||
* Buffer name and flags can be reconfigured using the appropriate functions.
|
||||
*/
|
||||
int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
|
||||
s_events_buf_filled = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_ConfigDownBuffer
|
||||
*
|
||||
* Function description
|
||||
* Run-time configuration of a specific down-buffer (H->T).
|
||||
* Buffer to be configured is specified by index.
|
||||
* This includes: Buffer address, size, name, flags, ...
|
||||
*
|
||||
* Parameters
|
||||
* BufferIndex Index of the buffer to configure.
|
||||
* sName Pointer to a constant name string.
|
||||
* pBuffer Pointer to a buffer to be used.
|
||||
* BufferSize Size of the buffer.
|
||||
* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
|
||||
*
|
||||
* Return value
|
||||
* >= 0 O.K.
|
||||
* < 0 Error
|
||||
*
|
||||
* Additional information
|
||||
* Buffer 0 is configured on compile-time.
|
||||
* May only be called once per buffer.
|
||||
* Buffer name and flags can be reconfigured using the appropriate functions.
|
||||
*/
|
||||
int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
|
||||
esp_apptrace_down_buffer_config(s_down_buf, sizeof(s_down_buf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <sdkconfig.h>
|
||||
#include "SEGGER_SYSVIEW.h"
|
||||
#include "SEGGER_RTT.h"
|
||||
#include "esp_app_trace.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "sysview_heap_trace";
|
||||
|
||||
#ifdef CONFIG_HEAP_TRACING_STACK_DEPTH
|
||||
#define CALLSTACK_SIZE CONFIG_HEAP_TRACING_STACK_DEPTH
|
||||
#else
|
||||
#define CALLSTACK_SIZE 0
|
||||
#endif
|
||||
|
||||
static SEGGER_SYSVIEW_MODULE s_esp_sysview_heap_module = {
|
||||
.sModule = "ESP32 SystemView Heap Tracing Module",
|
||||
.NumEvents = 2,
|
||||
};
|
||||
|
||||
static bool s_mod_registered;
|
||||
|
||||
|
||||
esp_err_t esp_sysview_heap_trace_start(uint32_t tmo)
|
||||
{
|
||||
uint32_t tmo_ticks = tmo/(1000*portTICK_PERIOD_MS);
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "%s", __func__);
|
||||
do {
|
||||
if (tmo != (uint32_t)-1) {
|
||||
// Currently timeout implementation is simple and has granularity of 1 OS tick,
|
||||
// so just count down the number of times to call vTaskDelay
|
||||
if (tmo_ticks-- == 0) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
vTaskDelay(1);
|
||||
} while(!SEGGER_SYSVIEW_Started());
|
||||
|
||||
SEGGER_SYSVIEW_RegisterModule(&s_esp_sysview_heap_module);
|
||||
s_mod_registered = true;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_sysview_heap_trace_stop(void)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __func__);
|
||||
SEGGER_RTT_ESP_Flush(0, ESP_APPTRACE_TMO_INFINITE);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_sysview_heap_trace_alloc(const void *addr, uint32_t size, const void *callers)
|
||||
{
|
||||
U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + (2+CALLSTACK_SIZE)*SEGGER_SYSVIEW_QUANTA_U32];
|
||||
U8* pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket);
|
||||
U32 *calls = (U32 *)callers;
|
||||
|
||||
if (!s_mod_registered) {
|
||||
return;
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "%s %p %lu", __func__, addr, size);
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, (U32)addr);
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, size);
|
||||
for (int i = 0; i < CALLSTACK_SIZE; i++) {
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, calls[i]);
|
||||
}
|
||||
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, s_esp_sysview_heap_module.EventOffset + 0);
|
||||
}
|
||||
|
||||
void esp_sysview_heap_trace_free(const void *addr, const void *callers)
|
||||
{
|
||||
U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + (1+CALLSTACK_SIZE)*SEGGER_SYSVIEW_QUANTA_U32];
|
||||
U8* pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket);
|
||||
U32 *calls = (U32 *)callers;
|
||||
|
||||
if (!s_mod_registered) {
|
||||
return;
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "%s %p", __func__, addr);
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, (U32)addr);
|
||||
for (int i = 0; i < CALLSTACK_SIZE; i++) {
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, calls[i]);
|
||||
}
|
||||
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, s_esp_sysview_heap_module.EventOffset + 1);
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <sdkconfig.h>
|
||||
#include "SEGGER_SYSVIEW_Int.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
static portMUX_TYPE s_log_mutex = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
int esp_sysview_vprintf(const char * format, va_list args)
|
||||
{
|
||||
static char log_buffer[SEGGER_SYSVIEW_MAX_STRING_LEN];
|
||||
|
||||
portENTER_CRITICAL(&s_log_mutex);
|
||||
size_t len = vsnprintf(log_buffer, sizeof(log_buffer), format, args);
|
||||
if (len > sizeof(log_buffer) - 1) {
|
||||
log_buffer[sizeof(log_buffer - 1)] = 0;
|
||||
}
|
||||
SEGGER_SYSVIEW_Print(log_buffer);
|
||||
portEXIT_CRITICAL(&s_log_mutex);
|
||||
return len;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
idf_component_register(SRC_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES cmock driver)
|
||||
@@ -1,8 +1,3 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
@@ -10,12 +5,11 @@
|
||||
#include <stdarg.h>
|
||||
#include "unity.h"
|
||||
#include "driver/timer.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "soc/cpu.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/task.h"
|
||||
#if CONFIG_APPTRACE_ENABLE == 1
|
||||
#if CONFIG_ESP32_APPTRACE_ENABLE == 1
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_app_trace_util.h"
|
||||
|
||||
@@ -37,7 +31,7 @@ const static char *TAG = "esp_apptrace_test";
|
||||
else \
|
||||
ret = xSemaphoreTake(s_print_lock, portMAX_DELAY); \
|
||||
if (ret == pdTRUE) { \
|
||||
esp_rom_printf(format, ##__VA_ARGS__); \
|
||||
ets_printf(format, ##__VA_ARGS__); \
|
||||
if (xPortInIsrContext()) \
|
||||
xSemaphoreGiveFromISR(s_print_lock, NULL); \
|
||||
else \
|
||||
@@ -47,7 +41,7 @@ const static char *TAG = "esp_apptrace_test";
|
||||
#else
|
||||
#define ESP_APPTRACE_TEST_LOG( format, ... ) \
|
||||
do { \
|
||||
esp_rom_printf(format, ##__VA_ARGS__); \
|
||||
ets_printf(format, ##__VA_ARGS__); \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
@@ -88,7 +82,7 @@ static void esp_apptrace_test_timer_init(int timer_group, int timer_idx, uint32_
|
||||
timer_enable_intr(timer_group, timer_idx);
|
||||
}
|
||||
|
||||
#if CONFIG_APPTRACE_SV_ENABLE == 0
|
||||
#if CONFIG_SYSVIEW_ENABLE == 0
|
||||
#define ESP_APPTRACE_TEST_WRITE(_b_, _s_) esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, _b_, _s_, ESP_APPTRACE_TMO_INFINITE)
|
||||
#define ESP_APPTRACE_TEST_WRITE_FROM_ISR(_b_, _s_) esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, _b_, _s_, 0UL)
|
||||
#define ESP_APPTRACE_TEST_WRITE_NOWAIT(_b_, _s_) esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, _b_, _s_, 0)
|
||||
@@ -131,7 +125,7 @@ typedef struct {
|
||||
static SemaphoreHandle_t s_print_lock;
|
||||
#endif
|
||||
|
||||
static uint64_t esp_apptrace_test_ts_get(void);
|
||||
static uint64_t esp_apptrace_test_ts_get();
|
||||
|
||||
static void esp_apptrace_test_timer_isr(void *arg)
|
||||
{
|
||||
@@ -144,32 +138,72 @@ static void esp_apptrace_test_timer_isr(void *arg)
|
||||
if (res != ESP_OK) {
|
||||
} else {
|
||||
if (0) {
|
||||
esp_rom_printf("tim-%d-%d: Written chunk%d %d bytes, %x\n",
|
||||
ets_printf("tim-%d-%d: Written chunk%d %d bytes, %x\n",
|
||||
tim_arg->group, tim_arg->id, tim_arg->data.wr_cnt, tim_arg->data.buf_sz, tim_arg->data.wr_cnt & tim_arg->data.mask);
|
||||
}
|
||||
tim_arg->data.wr_err = 0;
|
||||
}
|
||||
|
||||
tim_arg->data.wr_cnt++;
|
||||
timer_group_clr_intr_status_in_isr(tim_arg->group, tim_arg->id);
|
||||
timer_group_enable_alarm_in_isr(tim_arg->group, tim_arg->id);
|
||||
if (tim_arg->group == 0) {
|
||||
if (tim_arg->id == 0) {
|
||||
TIMERG0.int_clr_timers.t0 = 1;
|
||||
TIMERG0.hw_timer[0].update = 1;
|
||||
TIMERG0.hw_timer[0].config.alarm_en = 1;
|
||||
} else {
|
||||
TIMERG0.int_clr_timers.t1 = 1;
|
||||
TIMERG0.hw_timer[1].update = 1;
|
||||
TIMERG0.hw_timer[1].config.alarm_en = 1;
|
||||
}
|
||||
}
|
||||
if (tim_arg->group == 1) {
|
||||
if (tim_arg->id == 0) {
|
||||
TIMERG1.int_clr_timers.t0 = 1;
|
||||
TIMERG1.hw_timer[0].update = 1;
|
||||
TIMERG1.hw_timer[0].config.alarm_en = 1;
|
||||
} else {
|
||||
TIMERG1.int_clr_timers.t1 = 1;
|
||||
TIMERG1.hw_timer[1].update = 1;
|
||||
TIMERG1.hw_timer[1].config.alarm_en = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void esp_apptrace_test_timer_isr_crash(void *arg)
|
||||
{
|
||||
esp_apptrace_test_timer_arg_t *tim_arg = (esp_apptrace_test_timer_arg_t *)arg;
|
||||
|
||||
timer_group_clr_intr_status_in_isr(tim_arg->group, tim_arg->id);
|
||||
timer_group_enable_alarm_in_isr(tim_arg->group, tim_arg->id);
|
||||
if (tim_arg->group == 0) {
|
||||
if (tim_arg->id == 0) {
|
||||
TIMERG0.int_clr_timers.t0 = 1;
|
||||
TIMERG0.hw_timer[0].update = 1;
|
||||
TIMERG0.hw_timer[0].config.alarm_en = 1;
|
||||
} else {
|
||||
TIMERG0.int_clr_timers.t1 = 1;
|
||||
TIMERG0.hw_timer[1].update = 1;
|
||||
TIMERG0.hw_timer[1].config.alarm_en = 1;
|
||||
}
|
||||
}
|
||||
if (tim_arg->group == 1) {
|
||||
if (tim_arg->id == 0) {
|
||||
TIMERG1.int_clr_timers.t0 = 1;
|
||||
TIMERG1.hw_timer[0].update = 1;
|
||||
TIMERG1.hw_timer[0].config.alarm_en = 1;
|
||||
} else {
|
||||
TIMERG1.int_clr_timers.t1 = 1;
|
||||
TIMERG1.hw_timer[1].update = 1;
|
||||
TIMERG1.hw_timer[1].config.alarm_en = 1;
|
||||
}
|
||||
}
|
||||
if (tim_arg->data.wr_cnt < ESP_APPTRACE_TEST_BLOCKS_BEFORE_CRASH) {
|
||||
uint32_t *ts = (uint32_t *)(tim_arg->data.buf + sizeof(uint32_t));
|
||||
*ts = (uint32_t)esp_apptrace_test_ts_get();//xthal_get_ccount();//xTaskGetTickCount();
|
||||
memset(tim_arg->data.buf + 2 * sizeof(uint32_t), tim_arg->data.wr_cnt & tim_arg->data.mask, tim_arg->data.buf_sz - 2 * sizeof(uint32_t));
|
||||
int res = ESP_APPTRACE_TEST_WRITE_FROM_ISR(tim_arg->data.buf, tim_arg->data.buf_sz);
|
||||
if (res != ESP_OK) {
|
||||
esp_rom_printf("tim-%d-%d: Failed to write trace %d %x!\n", tim_arg->group, tim_arg->id, res, tim_arg->data.wr_cnt & tim_arg->data.mask);
|
||||
ets_printf("tim-%d-%d: Failed to write trace %d %x!\n", tim_arg->group, tim_arg->id, res, tim_arg->data.wr_cnt & tim_arg->data.mask);
|
||||
} else {
|
||||
esp_rom_printf("tim-%d-%d: Written chunk%d %d bytes, %x\n",
|
||||
ets_printf("tim-%d-%d: Written chunk%d %d bytes, %x\n",
|
||||
tim_arg->group, tim_arg->id, tim_arg->data.wr_cnt, tim_arg->data.buf_sz, tim_arg->data.wr_cnt & tim_arg->data.mask);
|
||||
tim_arg->data.wr_cnt++;
|
||||
}
|
||||
@@ -214,7 +248,7 @@ static void esp_apptrace_dummy_task(void *p)
|
||||
|
||||
i = 0;
|
||||
while (!arg->stop) {
|
||||
ESP_APPTRACE_TEST_LOGD("%x: dummy task work %d.%d", xTaskGetCurrentTaskHandle(), cpu_hal_get_core_id(), i++);
|
||||
ESP_APPTRACE_TEST_LOGD("%x: dummy task work %d.%d", xTaskGetCurrentTaskHandle(), xPortGetCoreID(), i++);
|
||||
if (tmo_ticks) {
|
||||
vTaskDelay(tmo_ticks);
|
||||
}
|
||||
@@ -259,7 +293,7 @@ static void esp_apptrace_test_task(void *p)
|
||||
ESP_APPTRACE_TEST_LOGE("Failed to timer_isr_register (%d)!", res);
|
||||
goto on_fail;
|
||||
}
|
||||
*(uint32_t *)arg->timers[i].data.buf = ((uint32_t)inth[i]) | (1 << 31) | (cpu_hal_get_core_id() ? 0x1 : 0);
|
||||
*(uint32_t *)arg->timers[i].data.buf = ((uint32_t)inth[i]) | (1 << 31) | (xPortGetCoreID() ? 0x1 : 0);
|
||||
ESP_APPTRACE_TEST_LOGI("%x: start timer %x period %u us", xTaskGetCurrentTaskHandle(), inth[i], arg->timers[i].data.period);
|
||||
res = timer_start(arg->timers[i].group, arg->timers[i].id);
|
||||
if (res != ESP_OK) {
|
||||
@@ -269,7 +303,7 @@ static void esp_apptrace_test_task(void *p)
|
||||
}
|
||||
}
|
||||
|
||||
*(uint32_t *)arg->data.buf = (uint32_t)xTaskGetCurrentTaskHandle() | (cpu_hal_get_core_id() ? 0x1 : 0);
|
||||
*(uint32_t *)arg->data.buf = (uint32_t)xTaskGetCurrentTaskHandle() | (xPortGetCoreID() ? 0x1 : 0);
|
||||
arg->data.wr_cnt = 0;
|
||||
arg->data.wr_err = 0;
|
||||
while (!arg->stop) {
|
||||
@@ -349,7 +383,7 @@ static void esp_apptrace_test_task_crash(void *p)
|
||||
|
||||
static int s_ts_timer_group, s_ts_timer_idx;
|
||||
|
||||
static uint64_t esp_apptrace_test_ts_get(void)
|
||||
static uint64_t esp_apptrace_test_ts_get()
|
||||
{
|
||||
uint64_t ts = 0;
|
||||
timer_get_counter_value(s_ts_timer_group, s_ts_timer_idx, &ts);
|
||||
@@ -379,7 +413,7 @@ static void esp_apptrace_test_ts_init(int timer_group, int timer_idx)
|
||||
timer_start(timer_group, timer_idx);
|
||||
}
|
||||
|
||||
static void esp_apptrace_test_ts_cleanup(void)
|
||||
static void esp_apptrace_test_ts_cleanup()
|
||||
{
|
||||
timer_config_t config;
|
||||
|
||||
@@ -410,7 +444,7 @@ static void esp_apptrace_test(esp_apptrace_test_cfg_t *test_cfg)
|
||||
#if ESP_APPTRACE_TEST_USE_PRINT_LOCK == 1
|
||||
s_print_lock = xSemaphoreCreateBinary();
|
||||
if (!s_print_lock) {
|
||||
esp_rom_printf("%s: Failed to create print lock!", TAG);
|
||||
ets_printf("%s: Failed to create print lock!", TAG);
|
||||
return;
|
||||
}
|
||||
xSemaphoreGive(s_print_lock);
|
||||
@@ -749,7 +783,7 @@ static void esp_logtrace_task(void *p)
|
||||
ESP_LOGI(TAG, "%p: sample print 4 %c", xTaskGetCurrentTaskHandle(), ((i & 0xFF) % 95) + 32);
|
||||
ESP_LOGI(TAG, "%p: sample print 5 %f", xTaskGetCurrentTaskHandle(), 1.0);
|
||||
ESP_LOGI(TAG, "%p: sample print 6 %f", xTaskGetCurrentTaskHandle(), 3.45);
|
||||
ESP_LOGI(TAG, "%p: logtrace task work %d.%d", xTaskGetCurrentTaskHandle(), cpu_hal_get_core_id(), i);
|
||||
ESP_LOGI(TAG, "%p: logtrace task work %d.%d", xTaskGetCurrentTaskHandle(), xPortGetCoreID(), i);
|
||||
if (++i == 10000) {
|
||||
break;
|
||||
}
|
||||
@@ -816,8 +850,28 @@ static void esp_sysview_test_timer_isr(void *arg)
|
||||
|
||||
//ESP_APPTRACE_TEST_LOGI("tim-%d: IRQ %d/%d\n", tim_arg->id, tim_arg->group, tim_arg->timer);
|
||||
|
||||
timer_group_clr_intr_status_in_isr(tim_arg->group, tim_arg->id);
|
||||
timer_group_enable_alarm_in_isr(tim_arg->group, tim_arg->id);
|
||||
if (tim_arg->group == 0) {
|
||||
if (tim_arg->timer == 0) {
|
||||
TIMERG0.int_clr_timers.t0 = 1;
|
||||
TIMERG0.hw_timer[0].update = 1;
|
||||
TIMERG0.hw_timer[0].config.alarm_en = 1;
|
||||
} else {
|
||||
TIMERG0.int_clr_timers.t1 = 1;
|
||||
TIMERG0.hw_timer[1].update = 1;
|
||||
TIMERG0.hw_timer[1].config.alarm_en = 1;
|
||||
}
|
||||
}
|
||||
if (tim_arg->group == 1) {
|
||||
if (tim_arg->timer == 0) {
|
||||
TIMERG1.int_clr_timers.t0 = 1;
|
||||
TIMERG1.hw_timer[0].update = 1;
|
||||
TIMERG1.hw_timer[0].config.alarm_en = 1;
|
||||
} else {
|
||||
TIMERG1.int_clr_timers.t1 = 1;
|
||||
TIMERG1.hw_timer[1].update = 1;
|
||||
TIMERG1.hw_timer[1].config.alarm_en = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void esp_sysviewtrace_test_task(void *p)
|
||||
|
||||
@@ -1,89 +1,7 @@
|
||||
idf_component_register(SRCS "esp_ota_ops.c"
|
||||
"esp_app_desc.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES spi_flash partition_table bootloader_support
|
||||
PRIV_REQUIRES esptool_py efuse)
|
||||
set(COMPONENT_SRCS "esp_ota_ops.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||
|
||||
# esp_app_desc structure is added as an undefined symbol because otherwise the
|
||||
# linker will ignore this structure as it has no other files depending on it.
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_app_desc")
|
||||
set(COMPONENT_REQUIRES spi_flash)
|
||||
set(COMPONENT_PRIV_REQUIRES bootloader_support)
|
||||
|
||||
if(CONFIG_APP_PROJECT_VER_FROM_CONFIG)
|
||||
# Ignore current PROJECT_VER (which was set in __project_get_revision()).
|
||||
# Gets the version from the CONFIG_APP_PROJECT_VER.
|
||||
idf_build_set_property(PROJECT_VER "${CONFIG_APP_PROJECT_VER}")
|
||||
endif()
|
||||
|
||||
# cut PROJECT_VER and PROJECT_NAME to required 32 characters.
|
||||
idf_build_get_property(project_ver PROJECT_VER)
|
||||
idf_build_get_property(project_name PROJECT_NAME)
|
||||
string(SUBSTRING "${project_ver}" 0 31 PROJECT_VER_CUT)
|
||||
string(SUBSTRING "${project_name}" 0 31 PROJECT_NAME_CUT)
|
||||
message(STATUS "App \"${PROJECT_NAME_CUT}\" version: ${PROJECT_VER_CUT}")
|
||||
|
||||
set_source_files_properties(
|
||||
SOURCE "esp_app_desc.c"
|
||||
PROPERTIES COMPILE_DEFINITIONS
|
||||
"PROJECT_VER=\"${PROJECT_VER_CUT}\"; PROJECT_NAME=\"${PROJECT_NAME_CUT}\"")
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
partition_table_get_partition_info(otadata_offset "--partition-type data --partition-subtype ota" "offset")
|
||||
partition_table_get_partition_info(otadata_size "--partition-type data --partition-subtype ota" "size")
|
||||
|
||||
# Add custom target for generating empty otadata partition for flashing
|
||||
if(otadata_size AND otadata_offset)
|
||||
idf_build_get_property(build_dir BUILD_DIR)
|
||||
set(blank_otadata_file ${build_dir}/ota_data_initial.bin)
|
||||
|
||||
idf_build_get_property(idf_path IDF_PATH)
|
||||
idf_build_get_property(python PYTHON)
|
||||
|
||||
idf_component_get_property(partition_table_dir partition_table COMPONENT_DIR)
|
||||
|
||||
add_custom_command(OUTPUT ${blank_otadata_file}
|
||||
COMMAND ${python} ${partition_table_dir}/gen_empty_partition.py
|
||||
${otadata_size} ${blank_otadata_file})
|
||||
|
||||
add_custom_target(blank_ota_data ALL DEPENDS ${blank_otadata_file})
|
||||
add_dependencies(flash blank_ota_data)
|
||||
add_dependencies(encrypted-flash blank_ota_data)
|
||||
|
||||
set(otatool_py ${python} ${COMPONENT_DIR}/otatool.py)
|
||||
|
||||
set(esptool_args "--esptool-args;before=${CONFIG_ESPTOOLPY_BEFORE};after=${CONFIG_ESPTOOLPY_AFTER}")
|
||||
set(otatool_args "--partition-table-file;${PARTITION_CSV_PATH}"
|
||||
"--partition-table-offset;${PARTITION_TABLE_OFFSET}")
|
||||
idf_component_get_property(esptool_py_dir esptool_py COMPONENT_DIR)
|
||||
|
||||
add_custom_target(read-otadata DEPENDS "${PARTITION_CSV_PATH}"
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D IDF_PATH="${idf_path}"
|
||||
-D SERIAL_TOOL="${otatool_py}"
|
||||
-D SERIAL_TOOL_ARGS="${esptool_args};${otatool_args};read_otadata"
|
||||
-D WORKING_DIRECTORY="${build_dir}"
|
||||
-P ${esptool_py_dir}/run_serial_tool.cmake
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
USES_TERMINAL
|
||||
)
|
||||
add_deprecated_target_alias(read_otadata read-otadata)
|
||||
|
||||
add_custom_target(erase-otadata DEPENDS "${PARTITION_CSV_PATH}"
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D IDF_PATH="${idf_path}"
|
||||
-D SERIAL_TOOL="${otatool_py}"
|
||||
-D SERIAL_TOOL_ARGS="${esptool_args};${otatool_args};erase_otadata"
|
||||
-D WORKING_DIRECTORY="${build_dir}"
|
||||
-P ${esptool_py_dir}/run_serial_tool.cmake
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
USES_TERMINAL
|
||||
)
|
||||
add_deprecated_target_alias(erase_otadata erase-otadata)
|
||||
|
||||
idf_component_get_property(main_args esptool_py FLASH_ARGS)
|
||||
idf_component_get_property(sub_args esptool_py FLASH_SUB_ARGS)
|
||||
esptool_py_flash_target(otadata-flash "${main_args}" "${sub_args}")
|
||||
esptool_py_flash_target_image(otadata-flash otadata "${otadata_offset}" "${blank_otadata_file}")
|
||||
|
||||
esptool_py_flash_target_image(flash otadata "${otadata_offset}" "${blank_otadata_file}")
|
||||
endif()
|
||||
endif()
|
||||
register_component()
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
menu "Application manager"
|
||||
|
||||
config APP_COMPILE_TIME_DATE
|
||||
bool "Use time/date stamp for app"
|
||||
default y
|
||||
help
|
||||
If set, then the app will be built with the current time/date stamp. It is stored in the app description
|
||||
structure. If not set, time/date stamp will be excluded from app image. This can be useful for getting the
|
||||
same binary image files made from the same source, but at different times.
|
||||
|
||||
config APP_EXCLUDE_PROJECT_VER_VAR
|
||||
bool "Exclude PROJECT_VER from firmware image"
|
||||
default n
|
||||
help
|
||||
The PROJECT_VER variable from the build system will not affect the firmware image.
|
||||
This value will not be contained in the esp_app_desc structure.
|
||||
|
||||
config APP_EXCLUDE_PROJECT_NAME_VAR
|
||||
bool "Exclude PROJECT_NAME from firmware image"
|
||||
default n
|
||||
help
|
||||
The PROJECT_NAME variable from the build system will not affect the firmware image.
|
||||
This value will not be contained in the esp_app_desc structure.
|
||||
|
||||
config APP_PROJECT_VER_FROM_CONFIG
|
||||
bool "Get the project version from Kconfig"
|
||||
default n
|
||||
help
|
||||
If this is enabled, then config item APP_PROJECT_VER will be used for the variable PROJECT_VER.
|
||||
Other ways to set PROJECT_VER will be ignored.
|
||||
|
||||
config APP_PROJECT_VER
|
||||
string "Project version"
|
||||
default "1"
|
||||
depends on APP_PROJECT_VER_FROM_CONFIG
|
||||
help
|
||||
Project version
|
||||
|
||||
config APP_RETRIEVE_LEN_ELF_SHA
|
||||
int "The length of APP ELF SHA is stored in RAM(chars)"
|
||||
default 16
|
||||
range 8 64
|
||||
help
|
||||
At startup, the app will read this many hex characters from the embedded APP ELF SHA-256 hash value
|
||||
and store it in static RAM. This ensures the app ELF SHA-256 value is always available
|
||||
if it needs to be printed by the panic handler code.
|
||||
Changing this value will change the size of a static buffer, in bytes.
|
||||
|
||||
endmenu # "Application manager"
|
||||
@@ -1,54 +0,0 @@
|
||||
# Generate partition binary
|
||||
#
|
||||
.PHONY: blank_ota_data erase_otadata read_otadata
|
||||
|
||||
OTATOOL_PY := $(PYTHON) $(COMPONENT_PATH)/otatool.py
|
||||
PARTTOOL_PY := $(PYTHON) $(IDF_PATH)/components/partition_table/parttool.py
|
||||
|
||||
# Generate blank partition file
|
||||
BLANK_OTA_DATA_FILE = $(BUILD_DIR_BASE)/ota_data_initial.bin
|
||||
|
||||
# Copy PARTITION_TABLE_CSV_PATH definition here from $IDF_PATH/components/partition_table/Makefile.projbuild
|
||||
# to avoid undefined variables warning for PARTITION_TABLE_CSV_PATH
|
||||
ifndef PARTITION_TABLE_CSV_PATH
|
||||
PARTITION_TABLE_ROOT := $(call dequote,$(if $(CONFIG_PARTITION_TABLE_CUSTOM),$(PROJECT_PATH),$(IDF_PATH)/components/partition_table))
|
||||
PARTITION_TABLE_CSV_PATH := $(call dequote,$(abspath $(PARTITION_TABLE_ROOT)/$(call dequote,$(CONFIG_PARTITION_TABLE_FILENAME))))
|
||||
endif
|
||||
|
||||
$(BLANK_OTA_DATA_FILE): partition_table_get_info $(PARTITION_TABLE_CSV_PATH) | check_python_dependencies
|
||||
$(shell if [ "$(OTA_DATA_OFFSET)" != "" ] && [ "$(OTA_DATA_SIZE)" != "" ]; then \
|
||||
$(PYTHON) $(IDF_PATH)/components/partition_table/gen_empty_partition.py $(OTA_DATA_SIZE) $(BLANK_OTA_DATA_FILE); \
|
||||
fi; )
|
||||
$(eval BLANK_OTA_DATA_FILE = $(shell if [ "$(OTA_DATA_OFFSET)" != "" ] && [ "$(OTA_DATA_SIZE)" != "" ]; then \
|
||||
echo $(BLANK_OTA_DATA_FILE); else echo " "; fi) )
|
||||
|
||||
blank_ota_data: $(BLANK_OTA_DATA_FILE)
|
||||
|
||||
# If there is no otadata partition, both OTA_DATA_OFFSET and BLANK_OTA_DATA_FILE
|
||||
# expand to empty values.
|
||||
ESPTOOL_ALL_FLASH_ARGS += $(OTA_DATA_OFFSET) $(BLANK_OTA_DATA_FILE)
|
||||
|
||||
ESPTOOL_ARGS := --esptool-args port=$(CONFIG_ESPTOOLPY_PORT) baud=$(CONFIG_ESPTOOLPY_BAUD) before=$(CONFIG_ESPTOOLPY_BEFORE) after=$(CONFIG_ESPTOOLPY_AFTER)
|
||||
|
||||
erase_otadata: $(PARTITION_TABLE_CSV_PATH) partition_table_get_info | check_python_dependencies
|
||||
$(OTATOOL_PY) $(ESPTOOL_ARGS) --partition-table-file $(PARTITION_TABLE_CSV_PATH) \
|
||||
--partition-table-offset $(PARTITION_TABLE_OFFSET) \
|
||||
erase_otadata
|
||||
|
||||
read_otadata: $(PARTITION_TABLE_CSV_PATH) partition_table_get_info | check_python_dependencies
|
||||
$(OTATOOL_PY) $(ESPTOOL_ARGS) --partition-table-file $(PARTITION_TABLE_CSV_PATH) \
|
||||
--partition-table-offset $(partition_table_offset) \
|
||||
read_otadata
|
||||
|
||||
all: blank_ota_data
|
||||
flash: blank_ota_data
|
||||
ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
|
||||
encrypted-flash: blank_ota_data
|
||||
endif
|
||||
|
||||
TMP_DEFINES := $(BUILD_DIR_BASE)/app_update/tmp_cppflags.txt
|
||||
export TMP_DEFINES
|
||||
|
||||
clean:
|
||||
rm -f $(BLANK_OTA_DATA_FILE)
|
||||
rm -f $(TMP_DEFINES)
|
||||
@@ -3,54 +3,3 @@
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
||||
# esp_app_desc structure is added as an undefined symbol because otherwise the
|
||||
# linker will ignore this structure as it has no other files depending on it.
|
||||
COMPONENT_ADD_LDFLAGS += -u esp_app_desc
|
||||
|
||||
ifndef IS_BOOTLOADER_BUILD
|
||||
# If ``CONFIG_APP_PROJECT_VER_FROM_CONFIG`` option is set, the value of ``CONFIG_APP_PROJECT_VER`` will be used
|
||||
# Else, if ``PROJECT_VER`` variable set in project Makefile file, its value will be used.
|
||||
# Else, if the ``$PROJECT_PATH/version.txt`` exists, its contents will be used as ``PROJECT_VER``.
|
||||
# Else, if the project is located inside a Git repository, the output of git describe will be used.
|
||||
# Otherwise, ``PROJECT_VER`` will be "1".
|
||||
ifdef CONFIG_APP_PROJECT_VER_FROM_CONFIG
|
||||
PROJECT_VER:= $(CONFIG_APP_PROJECT_VER)
|
||||
else
|
||||
ifneq ("${PROJECT_VER}", "")
|
||||
PROJECT_VER:= $(PROJECT_VER)
|
||||
else
|
||||
ifneq ("$(wildcard ${PROJECT_PATH}/version.txt)","")
|
||||
PROJECT_VER := $(shell cat ${PROJECT_PATH}/version.txt)
|
||||
else
|
||||
GIT_PROJECT_VER := $(shell cd ${PROJECT_PATH} && git describe --always --tags --dirty 2> /dev/null)
|
||||
ifeq ("${GIT_PROJECT_VER}", "")
|
||||
PROJECT_VER := "1"
|
||||
$(info Project is not inside a git repository, or git repository has no commits)
|
||||
$(info will not use 'git describe' to determine PROJECT_VER.)
|
||||
else
|
||||
PROJECT_VER:= $(GIT_PROJECT_VER)
|
||||
endif # a git repository
|
||||
endif # version.txt
|
||||
endif # PROJECT_VER
|
||||
endif # CONFIG_APP_PROJECT_VER_FROM_CONFIG
|
||||
|
||||
# cut PROJECT_VER and PROJECT_NAME to required 32 characters.
|
||||
PROJECT_VER_CUT := $(shell echo "$(PROJECT_VER)" | cut -c 1-31)
|
||||
PROJECT_NAME_CUT := $(shell echo "$(PROJECT_NAME)" | cut -c 1-31)
|
||||
|
||||
$(info App "$(PROJECT_NAME_CUT)" version: $(PROJECT_VER_CUT))
|
||||
|
||||
NEW_DEFINES:= "$(PROJECT_VER_CUT) $(PROJECT_NAME_CUT) $(IDF_VER)"
|
||||
ifeq ("$(wildcard ${TMP_DEFINES})","")
|
||||
OLD_DEFINES:= ""
|
||||
else
|
||||
OLD_DEFINES:= "$(shell cat $(TMP_DEFINES))"
|
||||
endif
|
||||
|
||||
# If NEW_DEFINES (PROJECT_VER, PROJECT_NAME) were changed then rebuild only esp_app_desc.
|
||||
ifneq (${NEW_DEFINES}, ${OLD_DEFINES})
|
||||
$(shell echo $(NEW_DEFINES) > $(TMP_DEFINES); rm -f esp_app_desc.o;)
|
||||
endif
|
||||
|
||||
esp_app_desc.o: CPPFLAGS += -D PROJECT_VER=\""$(PROJECT_VER_CUT)"\" -D PROJECT_NAME=\""$(PROJECT_NAME_CUT)"\"
|
||||
endif # IS_BOOTLOADER_BUILD
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/param.h>
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_attr.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
// Application version info
|
||||
const __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = {
|
||||
.magic_word = ESP_APP_DESC_MAGIC_WORD,
|
||||
#ifdef CONFIG_APP_EXCLUDE_PROJECT_VER_VAR
|
||||
.version = "",
|
||||
#else
|
||||
.version = PROJECT_VER,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR
|
||||
.project_name = "",
|
||||
#else
|
||||
.project_name = PROJECT_NAME,
|
||||
#endif
|
||||
.idf_ver = IDF_VER,
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_SECURE_VERSION
|
||||
.secure_version = CONFIG_BOOTLOADER_APP_SECURE_VERSION,
|
||||
#else
|
||||
.secure_version = 0,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_APP_COMPILE_TIME_DATE
|
||||
.time = __TIME__,
|
||||
.date = __DATE__,
|
||||
#else
|
||||
.time = "",
|
||||
.date = "",
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#ifndef CONFIG_APP_EXCLUDE_PROJECT_VER_VAR
|
||||
_Static_assert(sizeof(PROJECT_VER) <= sizeof(esp_app_desc.version), "PROJECT_VER is longer than version field in structure");
|
||||
#endif
|
||||
_Static_assert(sizeof(IDF_VER) <= sizeof(esp_app_desc.idf_ver), "IDF_VER is longer than idf_ver field in structure");
|
||||
#ifndef CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR
|
||||
_Static_assert(sizeof(PROJECT_NAME) <= sizeof(esp_app_desc.project_name), "PROJECT_NAME is longer than project_name field in structure");
|
||||
#endif
|
||||
|
||||
const esp_app_desc_t *esp_ota_get_app_description(void)
|
||||
{
|
||||
return &esp_app_desc;
|
||||
}
|
||||
|
||||
/* The following two functions may be called from the panic handler
|
||||
* or core dump, hence IRAM_ATTR.
|
||||
*/
|
||||
|
||||
static inline char IRAM_ATTR to_hex_digit(unsigned val)
|
||||
{
|
||||
return (val < 10) ? ('0' + val) : ('a' + val - 10);
|
||||
}
|
||||
|
||||
__attribute__((constructor)) void esp_ota_init_app_elf_sha256(void)
|
||||
{
|
||||
esp_ota_get_app_elf_sha256(NULL, 0);
|
||||
}
|
||||
|
||||
/* The esp_app_desc.app_elf_sha256 should be possible to print in panic handler during cache is disabled.
|
||||
* But because the cache is disabled the reading esp_app_desc.app_elf_sha256 is not right and
|
||||
* can lead to a complete lock-up of the CPU.
|
||||
* For this reason we do a reading of esp_app_desc.app_elf_sha256 while start up in esp_ota_init_app_elf_sha256()
|
||||
* and keep it in the static s_app_elf_sha256 value.
|
||||
*/
|
||||
int IRAM_ATTR esp_ota_get_app_elf_sha256(char* dst, size_t size)
|
||||
{
|
||||
static char s_app_elf_sha256[CONFIG_APP_RETRIEVE_LEN_ELF_SHA / 2];
|
||||
static bool first_call = true;
|
||||
if (first_call) {
|
||||
first_call = false;
|
||||
// At -O2 optimization level, GCC optimizes out the copying of the first byte of the app_elf_sha256,
|
||||
// because it is zero at compile time, and only modified afterwards by esptool.
|
||||
// Casting to volatile disables the optimization.
|
||||
const volatile uint8_t* src = (const volatile uint8_t*)esp_app_desc.app_elf_sha256;
|
||||
for (size_t i = 0; i < sizeof(s_app_elf_sha256); ++i) {
|
||||
s_app_elf_sha256[i] = src[i];
|
||||
}
|
||||
}
|
||||
if (dst == NULL || size == 0) {
|
||||
return 0;
|
||||
}
|
||||
size_t n = MIN((size - 1) / 2, sizeof(s_app_elf_sha256));
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
dst[2*i] = to_hex_digit(s_app_elf_sha256[i] >> 4);
|
||||
dst[2*i + 1] = to_hex_digit(s_app_elf_sha256[i] & 0xf);
|
||||
}
|
||||
dst[2*n] = 0;
|
||||
return 2*n + 1;
|
||||
}
|
||||
@@ -1,8 +1,16 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
// Copyright 2015-2016 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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
@@ -11,6 +19,8 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_partition.h"
|
||||
@@ -22,32 +32,39 @@
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "esp_ota_ops.h"
|
||||
#include "sys/queue.h"
|
||||
#include "rom/queue.h"
|
||||
#include "rom/crc.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "bootloader_common.h"
|
||||
#include "sys/param.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
|
||||
#define OTA_MAX(a,b) ((a) >= (b) ? (a) : (b))
|
||||
#define OTA_MIN(a,b) ((a) <= (b) ? (a) : (b))
|
||||
#define SUB_TYPE_ID(i) (i & 0x0F)
|
||||
|
||||
/* Partial_data is word aligned so no reallocation is necessary for encrypted flash write */
|
||||
typedef struct ota_ops_entry_ {
|
||||
uint32_t handle;
|
||||
const esp_partition_t *part;
|
||||
bool need_erase;
|
||||
uint32_t erased_size;
|
||||
uint32_t wrote_size;
|
||||
uint8_t partial_bytes;
|
||||
WORD_ALIGNED_ATTR uint8_t partial_data[16];
|
||||
uint8_t partial_data[16];
|
||||
LIST_ENTRY(ota_ops_entry_) entries;
|
||||
} ota_ops_entry_t;
|
||||
|
||||
/* OTA selection structure (two copies in the OTA data partition.)
|
||||
Size of 32 bytes is friendly to flash encryption */
|
||||
typedef struct {
|
||||
uint32_t ota_seq;
|
||||
uint8_t seq_label[24];
|
||||
uint32_t crc; /* CRC32 of ota_seq field only */
|
||||
} ota_select;
|
||||
|
||||
static LIST_HEAD(ota_ops_entries_head, ota_ops_entry_) s_ota_ops_entries_head =
|
||||
LIST_HEAD_INITIALIZER(s_ota_ops_entries_head);
|
||||
|
||||
static uint32_t s_ota_ops_last_handle = 0;
|
||||
static ota_select s_ota_select[2];
|
||||
|
||||
const static char *TAG = "esp_ota_ops";
|
||||
|
||||
@@ -60,56 +77,6 @@ static bool is_ota_partition(const esp_partition_t *p)
|
||||
&& p->subtype < ESP_PARTITION_SUBTYPE_APP_OTA_MAX);
|
||||
}
|
||||
|
||||
// Read otadata partition and fill array from two otadata structures.
|
||||
// Also return pointer to otadata info partition.
|
||||
static const esp_partition_t *read_otadata(esp_ota_select_entry_t *two_otadata)
|
||||
{
|
||||
const esp_partition_t *otadata_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
|
||||
if (otadata_partition == NULL) {
|
||||
ESP_LOGE(TAG, "not found otadata");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spi_flash_mmap_handle_t ota_data_map;
|
||||
const void *result = NULL;
|
||||
esp_err_t err = esp_partition_mmap(otadata_partition, 0, otadata_partition->size, SPI_FLASH_MMAP_DATA, &result, &ota_data_map);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "mmap otadata filed. Err=0x%8x", err);
|
||||
return NULL;
|
||||
} else {
|
||||
memcpy(&two_otadata[0], result, sizeof(esp_ota_select_entry_t));
|
||||
memcpy(&two_otadata[1], result + SPI_FLASH_SEC_SIZE, sizeof(esp_ota_select_entry_t));
|
||||
spi_flash_munmap(ota_data_map);
|
||||
}
|
||||
return otadata_partition;
|
||||
}
|
||||
|
||||
static esp_err_t image_validate(const esp_partition_t *partition, esp_image_load_mode_t load_mode)
|
||||
{
|
||||
esp_image_metadata_t data;
|
||||
const esp_partition_pos_t part_pos = {
|
||||
.offset = partition->address,
|
||||
.size = partition->size,
|
||||
};
|
||||
|
||||
if (esp_image_verify(load_mode, &part_pos, &data) != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_ota_img_states_t set_new_state_otadata(void)
|
||||
{
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
ESP_LOGD(TAG, "Monitoring the first boot of the app is enabled.");
|
||||
return ESP_OTA_IMG_NEW;
|
||||
#else
|
||||
return ESP_OTA_IMG_UNDEFINED;
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_begin(const esp_partition_t *partition, size_t image_size, esp_ota_handle_t *out_handle)
|
||||
{
|
||||
ota_ops_entry_t *new_entry;
|
||||
@@ -128,32 +95,19 @@ esp_err_t esp_ota_begin(const esp_partition_t *partition, size_t image_size, esp
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const esp_partition_t* running_partition = esp_ota_get_running_partition();
|
||||
if (partition == running_partition) {
|
||||
if (partition == esp_ota_get_running_partition()) {
|
||||
return ESP_ERR_OTA_PARTITION_CONFLICT;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
esp_ota_img_states_t ota_state_running_part;
|
||||
if (esp_ota_get_state_partition(running_partition, &ota_state_running_part) == ESP_OK) {
|
||||
if (ota_state_running_part == ESP_OTA_IMG_PENDING_VERIFY) {
|
||||
ESP_LOGE(TAG, "Running app has not confirmed state (ESP_OTA_IMG_PENDING_VERIFY)");
|
||||
return ESP_ERR_OTA_ROLLBACK_INVALID_STATE;
|
||||
}
|
||||
// If input image size is 0 or OTA_SIZE_UNKNOWN, erase entire partition
|
||||
if ((image_size == 0) || (image_size == OTA_SIZE_UNKNOWN)) {
|
||||
ret = esp_partition_erase_range(partition, 0, partition->size);
|
||||
} else {
|
||||
ret = esp_partition_erase_range(partition, 0, (image_size / SPI_FLASH_SEC_SIZE + 1) * SPI_FLASH_SEC_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (image_size != OTA_WITH_SEQUENTIAL_WRITES) {
|
||||
// If input image size is 0 or OTA_SIZE_UNKNOWN, erase entire partition
|
||||
if ((image_size == 0) || (image_size == OTA_SIZE_UNKNOWN)) {
|
||||
ret = esp_partition_erase_range(partition, 0, partition->size);
|
||||
} else {
|
||||
const int aligned_erase_size = (image_size + SPI_FLASH_SEC_SIZE - 1) & ~(SPI_FLASH_SEC_SIZE - 1);
|
||||
ret = esp_partition_erase_range(partition, 0, aligned_erase_size);
|
||||
}
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
new_entry = (ota_ops_entry_t *) calloc(sizeof(ota_ops_entry_t), 1);
|
||||
@@ -163,9 +117,14 @@ esp_err_t esp_ota_begin(const esp_partition_t *partition, size_t image_size, esp
|
||||
|
||||
LIST_INSERT_HEAD(&s_ota_ops_entries_head, new_entry, entries);
|
||||
|
||||
if ((image_size == 0) || (image_size == OTA_SIZE_UNKNOWN)) {
|
||||
new_entry->erased_size = partition->size;
|
||||
} else {
|
||||
new_entry->erased_size = image_size;
|
||||
}
|
||||
|
||||
new_entry->part = partition;
|
||||
new_entry->handle = ++s_ota_ops_last_handle;
|
||||
new_entry->need_erase = (image_size == OTA_WITH_SEQUENTIAL_WRITES);
|
||||
*out_handle = new_entry->handle;
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -184,22 +143,8 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
|
||||
// find ota handle in linked list
|
||||
for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) {
|
||||
if (it->handle == handle) {
|
||||
if (it->need_erase) {
|
||||
// must erase the partition before writing to it
|
||||
uint32_t first_sector = it->wrote_size / SPI_FLASH_SEC_SIZE;
|
||||
uint32_t last_sector = (it->wrote_size + size) / SPI_FLASH_SEC_SIZE;
|
||||
|
||||
ret = ESP_OK;
|
||||
if ((it->wrote_size % SPI_FLASH_SEC_SIZE) == 0) {
|
||||
ret = esp_partition_erase_range(it->part, it->wrote_size, ((last_sector - first_sector) + 1) * SPI_FLASH_SEC_SIZE);
|
||||
} else if (first_sector != last_sector) {
|
||||
ret = esp_partition_erase_range(it->part, (first_sector + 1) * SPI_FLASH_SEC_SIZE, (last_sector - first_sector) * SPI_FLASH_SEC_SIZE);
|
||||
}
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// must erase the partition before writing to it
|
||||
assert(it->erased_size > 0 && "must erase the partition before writing to it");
|
||||
if (it->wrote_size == 0 && it->partial_bytes == 0 && size > 0 && data_bytes[0] != ESP_IMAGE_HEADER_MAGIC) {
|
||||
ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x)", data_bytes[0]);
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
@@ -211,7 +156,7 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
|
||||
|
||||
/* check if we have partially written data from earlier */
|
||||
if (it->partial_bytes != 0) {
|
||||
copy_len = MIN(16 - it->partial_bytes, size);
|
||||
copy_len = OTA_MIN(16 - it->partial_bytes, size);
|
||||
memcpy(it->partial_data + it->partial_bytes, data_bytes, copy_len);
|
||||
it->partial_bytes += copy_len;
|
||||
if (it->partial_bytes != 16) {
|
||||
@@ -250,70 +195,16 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_write_with_offset(esp_ota_handle_t handle, const void *data, size_t size, uint32_t offset)
|
||||
esp_err_t esp_ota_end(esp_ota_handle_t handle)
|
||||
{
|
||||
const uint8_t *data_bytes = (const uint8_t *)data;
|
||||
esp_err_t ret;
|
||||
ota_ops_entry_t *it;
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (data == NULL) {
|
||||
ESP_LOGE(TAG, "write data is invalid");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// find ota handle in linked list
|
||||
for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) {
|
||||
if (it->handle == handle) {
|
||||
// must erase the partition before writing to it
|
||||
assert(it->need_erase == 0 && "must erase the partition before writing to it");
|
||||
|
||||
/* esp_ota_write_with_offset is used to write data in non contiguous manner.
|
||||
* Hence, unaligned data(less than 16 bytes) cannot be cached if flash encryption is enabled.
|
||||
*/
|
||||
if (esp_flash_encryption_enabled() && (size % 16)) {
|
||||
ESP_LOGE(TAG, "Size should be 16byte aligned for flash encryption case");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
ret = esp_partition_write(it->part, offset, data_bytes, size);
|
||||
if (ret == ESP_OK) {
|
||||
it->wrote_size += size;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// OTA handle is not found in linked list
|
||||
ESP_LOGE(TAG,"OTA handle not found");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
static ota_ops_entry_t *get_ota_ops_entry(esp_ota_handle_t handle)
|
||||
{
|
||||
ota_ops_entry_t *it = NULL;
|
||||
for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) {
|
||||
if (it->handle == handle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_abort(esp_ota_handle_t handle)
|
||||
{
|
||||
ota_ops_entry_t *it = get_ota_ops_entry(handle);
|
||||
|
||||
if (it == NULL) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
LIST_REMOVE(it, entries);
|
||||
free(it);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_end(esp_ota_handle_t handle)
|
||||
{
|
||||
ota_ops_entry_t *it = get_ota_ops_entry(handle);
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (it == NULL) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
@@ -322,7 +213,7 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle)
|
||||
/* 'it' holds the ota_ops_entry_t for 'handle' */
|
||||
|
||||
// esp_ota_end() is only valid if some data was written to this handle
|
||||
if (it->wrote_size == 0) {
|
||||
if ((it->erased_size == 0) || (it->wrote_size == 0)) {
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -344,7 +235,7 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle)
|
||||
.size = it->part->size,
|
||||
};
|
||||
|
||||
if (esp_image_verify(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) {
|
||||
if (esp_image_load(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) {
|
||||
ret = ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -355,23 +246,35 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t rewrite_ota_seq(esp_ota_select_entry_t *two_otadata, uint32_t seq, uint8_t sec_id, const esp_partition_t *ota_data_partition)
|
||||
static uint32_t ota_select_crc(const ota_select *s)
|
||||
{
|
||||
if (two_otadata == NULL || sec_id > 1) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return crc32_le(UINT32_MAX, (uint8_t *)&s->ota_seq, 4);
|
||||
}
|
||||
|
||||
two_otadata[sec_id].ota_seq = seq;
|
||||
two_otadata[sec_id].crc = bootloader_common_ota_select_crc(&two_otadata[sec_id]);
|
||||
esp_err_t ret = esp_partition_erase_range(ota_data_partition, sec_id * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
static bool ota_select_valid(const ota_select *s)
|
||||
{
|
||||
return s->ota_seq != UINT32_MAX && s->crc == ota_select_crc(s);
|
||||
}
|
||||
|
||||
static esp_err_t rewrite_ota_seq(uint32_t seq, uint8_t sec_id, const esp_partition_t *ota_data_partition)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
if (sec_id == 0 || sec_id == 1) {
|
||||
s_ota_select[sec_id].ota_seq = seq;
|
||||
s_ota_select[sec_id].crc = ota_select_crc(&s_ota_select[sec_id]);
|
||||
ret = esp_partition_erase_range(ota_data_partition, sec_id * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
} else {
|
||||
return esp_partition_write(ota_data_partition, SPI_FLASH_SEC_SIZE * sec_id, &s_ota_select[sec_id].ota_seq, sizeof(ota_select));
|
||||
}
|
||||
} else {
|
||||
return esp_partition_write(ota_data_partition, SPI_FLASH_SEC_SIZE * sec_id, &two_otadata[sec_id], sizeof(esp_ota_select_entry_t));
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t esp_ota_get_app_partition_count(void)
|
||||
static uint8_t get_ota_partition_count(void)
|
||||
{
|
||||
uint16_t ota_app_count = 0;
|
||||
while (esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_app_count, NULL) != NULL) {
|
||||
@@ -383,88 +286,119 @@ uint8_t esp_ota_get_app_partition_count(void)
|
||||
|
||||
static esp_err_t esp_rewrite_ota_data(esp_partition_subtype_t subtype)
|
||||
{
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
const esp_partition_t *otadata_partition = read_otadata(otadata);
|
||||
if (otadata_partition == NULL) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
esp_err_t ret;
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
uint16_t ota_app_count = 0;
|
||||
uint32_t i = 0;
|
||||
uint32_t seq;
|
||||
spi_flash_mmap_handle_t ota_data_map;
|
||||
const void *result = NULL;
|
||||
|
||||
uint8_t ota_app_count = esp_ota_get_app_partition_count();
|
||||
if (SUB_TYPE_ID(subtype) >= ota_app_count) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
//esp32_idf use two sector for store information about which partition is running
|
||||
//it defined the two sector as ota data partition,two structure esp_ota_select_entry_t is saved in the two sector
|
||||
//named data in first sector as otadata[0], second sector data as otadata[1]
|
||||
//e.g.
|
||||
//if otadata[0].ota_seq == otadata[1].ota_seq == 0xFFFFFFFF,means ota info partition is in init status
|
||||
//so it will boot factory application(if there is),if there's no factory application,it will boot ota[0] application
|
||||
//if otadata[0].ota_seq != 0 and otadata[1].ota_seq != 0,it will choose a max seq ,and get value of max_seq%max_ota_app_number
|
||||
//and boot a subtype (mask 0x0F) value is (max_seq - 1)%max_ota_app_number,so if want switch to run ota[x],can use next formulas.
|
||||
//for example, if otadata[0].ota_seq = 4, otadata[1].ota_seq = 5, and there are 8 ota application,
|
||||
//current running is (5-1)%8 = 4,running ota[4],so if we want to switch to run ota[7],
|
||||
//we should add otadata[0].ota_seq (is 4) to 4 ,(8-1)%8=7,then it will boot ota[7]
|
||||
//if A=(B - C)%D
|
||||
//then B=(A + C)%D + D*n ,n= (0,1,2...)
|
||||
//so current ota app sub type id is x , dest bin subtype is y,total ota app count is n
|
||||
//seq will add (x + n*1 + 1 - seq)%n
|
||||
|
||||
int active_otadata = bootloader_common_get_active_otadata(otadata);
|
||||
if (active_otadata != -1) {
|
||||
uint32_t seq = otadata[active_otadata].ota_seq;
|
||||
uint32_t i = 0;
|
||||
while (seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
if (find_partition != NULL) {
|
||||
ota_app_count = get_ota_partition_count();
|
||||
//esp32_idf use two sector for store information about which partition is running
|
||||
//it defined the two sector as ota data partition,two structure ota_select is saved in the two sector
|
||||
//named data in first sector as s_ota_select[0], second sector data as s_ota_select[1]
|
||||
//e.g.
|
||||
//if s_ota_select[0].ota_seq == s_ota_select[1].ota_seq == 0xFFFFFFFF,means ota info partition is in init status
|
||||
//so it will boot factory application(if there is),if there's no factory application,it will boot ota[0] application
|
||||
//if s_ota_select[0].ota_seq != 0 and s_ota_select[1].ota_seq != 0,it will choose a max seq ,and get value of max_seq%max_ota_app_number
|
||||
//and boot a subtype (mask 0x0F) value is (max_seq - 1)%max_ota_app_number,so if want switch to run ota[x],can use next formulas.
|
||||
//for example, if s_ota_select[0].ota_seq = 4, s_ota_select[1].ota_seq = 5, and there are 8 ota application,
|
||||
//current running is (5-1)%8 = 4,running ota[4],so if we want to switch to run ota[7],
|
||||
//we should add s_ota_select[0].ota_seq (is 4) to 4 ,(8-1)%8=7,then it will boot ota[7]
|
||||
//if A=(B - C)%D
|
||||
//then B=(A + C)%D + D*n ,n= (0,1,2...)
|
||||
//so current ota app sub type id is x , dest bin subtype is y,total ota app count is n
|
||||
//seq will add (x + n*1 + 1 - seq)%n
|
||||
if (SUB_TYPE_ID(subtype) >= ota_app_count) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
int next_otadata = (~active_otadata)&1; // if 0 -> will be next 1. and if 1 -> will be next 0.
|
||||
otadata[next_otadata].ota_state = set_new_state_otadata();
|
||||
return rewrite_ota_seq(otadata, (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, next_otadata, otadata_partition);
|
||||
|
||||
ret = esp_partition_mmap(find_partition, 0, find_partition->size, SPI_FLASH_MMAP_DATA, &result, &ota_data_map);
|
||||
if (ret != ESP_OK) {
|
||||
result = NULL;
|
||||
return ret;
|
||||
} else {
|
||||
memcpy(&s_ota_select[0], result, sizeof(ota_select));
|
||||
memcpy(&s_ota_select[1], result + SPI_FLASH_SEC_SIZE, sizeof(ota_select));
|
||||
spi_flash_munmap(ota_data_map);
|
||||
}
|
||||
|
||||
if (ota_select_valid(&s_ota_select[0]) && ota_select_valid(&s_ota_select[1])) {
|
||||
seq = OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq);
|
||||
while (seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
|
||||
if (s_ota_select[0].ota_seq >= s_ota_select[1].ota_seq) {
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 1, find_partition);
|
||||
} else {
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 0, find_partition);
|
||||
}
|
||||
|
||||
} else if (ota_select_valid(&s_ota_select[0])) {
|
||||
while (s_ota_select[0].ota_seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 1, find_partition);
|
||||
|
||||
} else if (ota_select_valid(&s_ota_select[1])) {
|
||||
while (s_ota_select[1].ota_seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 0, find_partition);
|
||||
|
||||
} else {
|
||||
/* Both OTA slots are invalid, probably because unformatted... */
|
||||
return rewrite_ota_seq(SUB_TYPE_ID(subtype) + 1, 0, find_partition);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Both OTA slots are invalid, probably because unformatted... */
|
||||
int next_otadata = 0;
|
||||
otadata[next_otadata].ota_state = set_new_state_otadata();
|
||||
return rewrite_ota_seq(otadata, SUB_TYPE_ID(subtype) + 1, next_otadata, otadata_partition);
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_set_boot_partition(const esp_partition_t *partition)
|
||||
{
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
if (partition == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (image_validate(partition, ESP_IMAGE_VERIFY) != ESP_OK) {
|
||||
esp_image_metadata_t data;
|
||||
const esp_partition_pos_t part_pos = {
|
||||
.offset = partition->address,
|
||||
.size = partition->size,
|
||||
};
|
||||
if (esp_image_load(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURE_SIGNED_ON_UPDATE
|
||||
esp_err_t ret = esp_secure_boot_verify_signature(partition->address, data.image_len);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
#endif
|
||||
// if set boot partition to factory bin ,just format ota info partition
|
||||
if (partition->type == ESP_PARTITION_TYPE_APP) {
|
||||
if (partition->subtype == ESP_PARTITION_SUBTYPE_APP_FACTORY) {
|
||||
const esp_partition_t *find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
if (find_partition != NULL) {
|
||||
return esp_partition_erase_range(find_partition, 0, find_partition->size);
|
||||
} else {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
} else {
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
esp_app_desc_t partition_app_desc;
|
||||
esp_err_t err = esp_ota_get_partition_description(partition, &partition_app_desc);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
// try to find this partition in flash,if not find it ,return error
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
if (find_partition != NULL) {
|
||||
return esp_rewrite_ota_data(partition->subtype);
|
||||
} else {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (esp_efuse_check_secure_version(partition_app_desc.secure_version) == false) {
|
||||
ESP_LOGE(TAG, "This a new partition can not be booted due to a secure version is lower than stored in efuse. Partition will be erased.");
|
||||
esp_err_t err = esp_partition_erase_range(partition, 0, partition->size);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
return ESP_ERR_OTA_SMALL_SEC_VER;
|
||||
}
|
||||
#endif
|
||||
return esp_rewrite_ota_data(partition->subtype);
|
||||
}
|
||||
} else {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@@ -501,30 +435,58 @@ static const esp_partition_t *find_default_boot_partition(void)
|
||||
|
||||
const esp_partition_t *esp_ota_get_boot_partition(void)
|
||||
{
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
const esp_partition_t *otadata_partition = read_otadata(otadata);
|
||||
if (otadata_partition == NULL) {
|
||||
esp_err_t ret;
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
spi_flash_mmap_handle_t ota_data_map;
|
||||
const void *result = NULL;
|
||||
uint16_t ota_app_count = 0;
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
|
||||
if (find_partition == NULL) {
|
||||
ESP_LOGE(TAG, "not found ota data");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ota_app_count = esp_ota_get_app_partition_count();
|
||||
ret = esp_partition_mmap(find_partition, 0, find_partition->size, SPI_FLASH_MMAP_DATA, &result, &ota_data_map);
|
||||
if (ret != ESP_OK) {
|
||||
spi_flash_munmap(ota_data_map);
|
||||
ESP_LOGE(TAG, "mmap ota data filed");
|
||||
return NULL;
|
||||
} else {
|
||||
memcpy(&s_ota_select[0], result, sizeof(ota_select));
|
||||
memcpy(&s_ota_select[1], result + 0x1000, sizeof(ota_select));
|
||||
spi_flash_munmap(ota_data_map);
|
||||
}
|
||||
ota_app_count = get_ota_partition_count();
|
||||
|
||||
ESP_LOGD(TAG, "found ota app max = %d", ota_app_count);
|
||||
|
||||
if ((bootloader_common_ota_select_invalid(&otadata[0]) &&
|
||||
bootloader_common_ota_select_invalid(&otadata[1])) ||
|
||||
ota_app_count == 0) {
|
||||
ESP_LOGD(TAG, "finding factory app...");
|
||||
if (s_ota_select[0].ota_seq == 0xFFFFFFFF && s_ota_select[1].ota_seq == 0xFFFFFFFF) {
|
||||
ESP_LOGD(TAG, "finding factory app......");
|
||||
return find_default_boot_partition();
|
||||
} else if (ota_select_valid(&s_ota_select[0]) && ota_select_valid(&s_ota_select[1])) {
|
||||
ESP_LOGD(TAG, "finding ota_%d app......", \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ((OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq) - 1) % ota_app_count));
|
||||
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ((OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq) - 1) % ota_app_count), NULL);
|
||||
} else if (ota_select_valid(&s_ota_select[0])) {
|
||||
ESP_LOGD(TAG, "finding ota_%d app......", \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[0].ota_seq - 1) % ota_app_count);
|
||||
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[0].ota_seq - 1) % ota_app_count, NULL);
|
||||
|
||||
} else if (ota_select_valid(&s_ota_select[1])) {
|
||||
ESP_LOGD(TAG, "finding ota_%d app......", \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[1].ota_seq - 1) % ota_app_count);
|
||||
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[1].ota_seq - 1) % ota_app_count, NULL);
|
||||
|
||||
} else {
|
||||
int active_otadata = bootloader_common_get_active_otadata(otadata);
|
||||
if (active_otadata != -1) {
|
||||
int ota_slot = (otadata[active_otadata].ota_seq - 1) % ota_app_count; // Actual OTA partition selection
|
||||
ESP_LOGD(TAG, "finding ota_%d app...", ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_slot);
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_slot, NULL);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "ota data invalid, no current app. Assuming factory");
|
||||
return find_default_boot_partition();
|
||||
}
|
||||
ESP_LOGE(TAG, "ota data invalid, no current app. Assuming factory");
|
||||
return find_default_boot_partition();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,349 +575,3 @@ const esp_partition_t* esp_ota_get_next_update_partition(const esp_partition_t *
|
||||
return default_ota;
|
||||
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_get_partition_description(const esp_partition_t *partition, esp_app_desc_t *app_desc)
|
||||
{
|
||||
if (partition == NULL || app_desc == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if(partition->type != ESP_PARTITION_TYPE_APP) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
esp_err_t err = esp_partition_read(partition, sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t), app_desc, sizeof(esp_app_desc_t));
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (app_desc->magic_word != ESP_APP_DESC_MAGIC_WORD) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
static esp_err_t esp_ota_set_anti_rollback(void) {
|
||||
const esp_app_desc_t *app_desc = esp_ota_get_app_description();
|
||||
return esp_efuse_update_secure_version(app_desc->secure_version);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Checks applications on the slots which can be booted in case of rollback.
|
||||
// Returns true if the slots have at least one app (except the running app).
|
||||
bool esp_ota_check_rollback_is_possible(void)
|
||||
{
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
if (read_otadata(otadata) == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int ota_app_count = esp_ota_get_app_partition_count();
|
||||
if (ota_app_count == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool valid_otadata[2];
|
||||
valid_otadata[0] = bootloader_common_ota_select_valid(&otadata[0]);
|
||||
valid_otadata[1] = bootloader_common_ota_select_valid(&otadata[1]);
|
||||
|
||||
int active_ota = bootloader_common_select_otadata(otadata, valid_otadata, true);
|
||||
if (active_ota == -1) {
|
||||
return false;
|
||||
}
|
||||
int last_active_ota = (~active_ota)&1;
|
||||
|
||||
const esp_partition_t *partition = NULL;
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
if (valid_otadata[last_active_ota] == false) {
|
||||
partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
|
||||
if (partition != NULL) {
|
||||
if(image_validate(partition, ESP_IMAGE_VERIFY_SILENT) == ESP_OK) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (valid_otadata[last_active_ota] == true) {
|
||||
int slot = (otadata[last_active_ota].ota_seq - 1) % ota_app_count;
|
||||
partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_MIN + slot, NULL);
|
||||
if (partition != NULL) {
|
||||
if(image_validate(partition, ESP_IMAGE_VERIFY_SILENT) == ESP_OK) {
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
esp_app_desc_t app_desc;
|
||||
if (esp_ota_get_partition_description(partition, &app_desc) == ESP_OK &&
|
||||
esp_efuse_check_secure_version(app_desc.secure_version) == true) {
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// if valid == false - will done rollback with reboot. After reboot will boot previous OTA[x] or Factory partition.
|
||||
// if valid == true - it confirm that current OTA[x] is workable. Reboot will not happen.
|
||||
static esp_err_t esp_ota_current_ota_is_workable(bool valid)
|
||||
{
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
const esp_partition_t *otadata_partition = read_otadata(otadata);
|
||||
if (otadata_partition == NULL) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
int active_otadata = bootloader_common_get_active_otadata(otadata);
|
||||
if (active_otadata != -1 && esp_ota_get_app_partition_count() != 0) {
|
||||
if (valid == true && otadata[active_otadata].ota_state != ESP_OTA_IMG_VALID) {
|
||||
otadata[active_otadata].ota_state = ESP_OTA_IMG_VALID;
|
||||
ESP_LOGD(TAG, "OTA[current] partition is marked as VALID");
|
||||
esp_err_t err = rewrite_ota_seq(otadata, otadata[active_otadata].ota_seq, active_otadata, otadata_partition);
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
if (err == ESP_OK) {
|
||||
return esp_ota_set_anti_rollback();
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
} else if (valid == false) {
|
||||
if (esp_ota_check_rollback_is_possible() == false) {
|
||||
ESP_LOGE(TAG, "Rollback is not possible, do not have any suitable apps in slots");
|
||||
return ESP_ERR_OTA_ROLLBACK_FAILED;
|
||||
}
|
||||
ESP_LOGD(TAG, "OTA[current] partition is marked as INVALID");
|
||||
otadata[active_otadata].ota_state = ESP_OTA_IMG_INVALID;
|
||||
esp_err_t err = rewrite_ota_seq(otadata, otadata[active_otadata].ota_seq, active_otadata, otadata_partition);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
ESP_LOGI(TAG, "Rollback to previously worked partition. Restart.");
|
||||
esp_restart();
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Running firmware is factory");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_mark_app_valid_cancel_rollback(void)
|
||||
{
|
||||
return esp_ota_current_ota_is_workable(true);
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_mark_app_invalid_rollback_and_reboot(void)
|
||||
{
|
||||
return esp_ota_current_ota_is_workable(false);
|
||||
}
|
||||
|
||||
static bool check_invalid_otadata (const esp_ota_select_entry_t *s) {
|
||||
return s->ota_seq != UINT32_MAX &&
|
||||
s->crc == bootloader_common_ota_select_crc(s) &&
|
||||
(s->ota_state == ESP_OTA_IMG_INVALID ||
|
||||
s->ota_state == ESP_OTA_IMG_ABORTED);
|
||||
}
|
||||
|
||||
static int get_last_invalid_otadata(const esp_ota_select_entry_t *two_otadata)
|
||||
{
|
||||
|
||||
bool invalid_otadata[2];
|
||||
invalid_otadata[0] = check_invalid_otadata(&two_otadata[0]);
|
||||
invalid_otadata[1] = check_invalid_otadata(&two_otadata[1]);
|
||||
int num_invalid_otadata = bootloader_common_select_otadata(two_otadata, invalid_otadata, false);
|
||||
ESP_LOGD(TAG, "Invalid otadata[%d]", num_invalid_otadata);
|
||||
return num_invalid_otadata;
|
||||
}
|
||||
|
||||
const esp_partition_t* esp_ota_get_last_invalid_partition(void)
|
||||
{
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
if (read_otadata(otadata) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int invalid_otadata = get_last_invalid_otadata(otadata);
|
||||
|
||||
int ota_app_count = esp_ota_get_app_partition_count();
|
||||
if (invalid_otadata != -1 && ota_app_count != 0) {
|
||||
int ota_slot = (otadata[invalid_otadata].ota_seq - 1) % ota_app_count;
|
||||
ESP_LOGD(TAG, "Find invalid ota_%d app", ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_slot);
|
||||
|
||||
const esp_partition_t* invalid_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_slot, NULL);
|
||||
if (invalid_partition != NULL) {
|
||||
if (image_validate(invalid_partition, ESP_IMAGE_VERIFY_SILENT) != ESP_OK) {
|
||||
ESP_LOGD(TAG, "Last invalid partition has corrupted app");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return invalid_partition;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_get_state_partition(const esp_partition_t *partition, esp_ota_img_states_t *ota_state)
|
||||
{
|
||||
if (partition == NULL || ota_state == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!is_ota_partition(partition)) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
int ota_app_count = esp_ota_get_app_partition_count();
|
||||
if (read_otadata(otadata) == NULL || ota_app_count == 0) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
int req_ota_slot = partition->subtype - ESP_PARTITION_SUBTYPE_APP_OTA_MIN;
|
||||
bool not_found = true;
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
int ota_slot = (otadata[i].ota_seq - 1) % ota_app_count;
|
||||
if (ota_slot == req_ota_slot && otadata[i].crc == bootloader_common_ota_select_crc(&otadata[i])) {
|
||||
*ota_state = otadata[i].ota_state;
|
||||
not_found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (not_found) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_erase_last_boot_app_partition(void)
|
||||
{
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
const esp_partition_t* ota_data_partition = read_otadata(otadata);
|
||||
if (ota_data_partition == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
int active_otadata = bootloader_common_get_active_otadata(otadata);
|
||||
int ota_app_count = esp_ota_get_app_partition_count();
|
||||
if (active_otadata == -1 || ota_app_count == 0) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
int inactive_otadata = (~active_otadata)&1;
|
||||
if (otadata[inactive_otadata].ota_seq == UINT32_MAX || otadata[inactive_otadata].crc != bootloader_common_ota_select_crc(&otadata[inactive_otadata])) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
int ota_slot = (otadata[inactive_otadata].ota_seq - 1) % ota_app_count; // Actual OTA partition selection
|
||||
ESP_LOGD(TAG, "finding last_boot_app_partition ota_%d app...", ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_slot);
|
||||
|
||||
const esp_partition_t* last_boot_app_partition_from_otadata = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_slot, NULL);
|
||||
if (last_boot_app_partition_from_otadata == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
const esp_partition_t* running_partition = esp_ota_get_running_partition();
|
||||
if (running_partition == NULL || last_boot_app_partition_from_otadata == running_partition) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t err = esp_partition_erase_range(last_boot_app_partition_from_otadata, 0, last_boot_app_partition_from_otadata->size);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
int sec_id = inactive_otadata;
|
||||
err = esp_partition_erase_range(ota_data_partition, sec_id * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1 && CONFIG_SECURE_BOOT_V2_ENABLED
|
||||
esp_err_t esp_ota_revoke_secure_boot_public_key(esp_ota_secure_boot_public_key_index_t index) {
|
||||
|
||||
if (!esp_secure_boot_enabled()) {
|
||||
ESP_LOGE(TAG, "Secure boot v2 has not been enabled.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (index != SECURE_BOOT_PUBLIC_KEY_INDEX_0 &&
|
||||
index != SECURE_BOOT_PUBLIC_KEY_INDEX_1 &&
|
||||
index != SECURE_BOOT_PUBLIC_KEY_INDEX_2) {
|
||||
ESP_LOGE(TAG, "Invalid Index found for public key revocation %d.", index);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_image_sig_public_key_digests_t app_digests = { 0 };
|
||||
esp_err_t err = esp_secure_boot_get_signature_blocks_for_running_app(true, &app_digests);
|
||||
if (err != ESP_OK || app_digests.num_digests == 0) {
|
||||
ESP_LOGE(TAG, "This app is not signed, but check signature on update is enabled in config. It won't be possible to verify any update.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t ret;
|
||||
ets_secure_boot_key_digests_t trusted_keys;
|
||||
ret = esp_secure_boot_read_key_digests(&trusted_keys);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not read the secure boot key digests from efuse. Aborting..");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (trusted_keys.key_digests[index] == NULL) {
|
||||
ESP_LOGI(TAG, "Trusted Key block(%d) already revoked.", index);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_image_sig_public_key_digests_t trusted_digests = { 0 };
|
||||
for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
|
||||
if (i == index) {
|
||||
continue; // omitting - to find if there is a valid key after revoking this digest
|
||||
}
|
||||
|
||||
if (trusted_keys.key_digests[i] != NULL) {
|
||||
bool all_zeroes = true;
|
||||
for (unsigned j = 0; j < ESP_SECURE_BOOT_DIGEST_LEN; j++) {
|
||||
all_zeroes = all_zeroes && (*(uint8_t *)(trusted_keys.key_digests[i] + j) == 0);
|
||||
}
|
||||
if (!all_zeroes) {
|
||||
memcpy(trusted_digests.key_digests[trusted_digests.num_digests++], (uint8_t *)trusted_keys.key_digests[i], ESP_SECURE_BOOT_DIGEST_LEN);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Empty trusted key block (%d).", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool match = false;
|
||||
for (unsigned i = 0; i < trusted_digests.num_digests; i++) {
|
||||
if (match == true) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned j = 0; j < app_digests.num_digests; j++) {
|
||||
if (memcmp(trusted_digests.key_digests[i], app_digests.key_digests[j], ESP_SECURE_BOOT_DIGEST_LEN) == 0) {
|
||||
ESP_LOGI(TAG, "App key block(%d) matches Trusted key block(%d)[%d -> Next active trusted key block].", j, i, i);
|
||||
esp_err_t err = esp_efuse_set_digest_revoke(index);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to revoke digest (0x%x).", err);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_LOGI(TAG, "Revoked signature block %d.", index);
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match == false) {
|
||||
ESP_LOGE(TAG, "Running app doesn't have another valid secure boot key. Cannot revoke current key(%d).", index);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
// Copyright 2015-2016 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.
|
||||
|
||||
#ifndef _OTA_OPS_H
|
||||
#define _OTA_OPS_H
|
||||
@@ -12,9 +20,6 @@
|
||||
#include <stddef.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
@@ -22,16 +27,11 @@ extern "C"
|
||||
#endif
|
||||
|
||||
#define OTA_SIZE_UNKNOWN 0xffffffff /*!< Used for esp_ota_begin() if new image size is unknown */
|
||||
#define OTA_WITH_SEQUENTIAL_WRITES 0xfffffffe /*!< Used for esp_ota_begin() if new image size is unknown and erase can be done in incremental manner (assuming write operation is in continuous sequence) */
|
||||
|
||||
#define ESP_ERR_OTA_BASE 0x1500 /*!< Base error code for ota_ops api */
|
||||
#define ESP_ERR_OTA_PARTITION_CONFLICT (ESP_ERR_OTA_BASE + 0x01) /*!< Error if request was to write or erase the current running partition */
|
||||
#define ESP_ERR_OTA_SELECT_INFO_INVALID (ESP_ERR_OTA_BASE + 0x02) /*!< Error if OTA data partition contains invalid content */
|
||||
#define ESP_ERR_OTA_VALIDATE_FAILED (ESP_ERR_OTA_BASE + 0x03) /*!< Error if OTA app image is invalid */
|
||||
#define ESP_ERR_OTA_SMALL_SEC_VER (ESP_ERR_OTA_BASE + 0x04) /*!< Error if the firmware has a secure version less than the running firmware. */
|
||||
#define ESP_ERR_OTA_ROLLBACK_FAILED (ESP_ERR_OTA_BASE + 0x05) /*!< Error if flash does not have valid firmware in passive partition and hence rollback is not possible */
|
||||
#define ESP_ERR_OTA_ROLLBACK_INVALID_STATE (ESP_ERR_OTA_BASE + 0x06) /*!< Error if current active firmware is still marked in pending validation state (ESP_OTA_IMG_PENDING_VERIFY), essentially first boot of firmware image post upgrade and hence firmware upgrade is not possible */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Opaque handle for an application OTA update
|
||||
@@ -41,24 +41,6 @@ extern "C"
|
||||
*/
|
||||
typedef uint32_t esp_ota_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Return esp_app_desc structure. This structure includes app version.
|
||||
*
|
||||
* Return description for running app.
|
||||
* @return Pointer to esp_app_desc structure.
|
||||
*/
|
||||
const esp_app_desc_t *esp_ota_get_app_description(void);
|
||||
|
||||
/**
|
||||
* @brief Fill the provided buffer with SHA256 of the ELF file, formatted as hexadecimal, null-terminated.
|
||||
* If the buffer size is not sufficient to fit the entire SHA256 in hex plus a null terminator,
|
||||
* the largest possible number of bytes will be written followed by a null.
|
||||
* @param dst Destination buffer
|
||||
* @param size Size of the buffer
|
||||
* @return Number of bytes written to dst (including null terminator)
|
||||
*/
|
||||
int esp_ota_get_app_elf_sha256(char* dst, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Commence an OTA update writing to the specified partition.
|
||||
|
||||
@@ -70,10 +52,6 @@ int esp_ota_get_app_elf_sha256(char* dst, size_t size);
|
||||
* On success, this function allocates memory that remains in use
|
||||
* until esp_ota_end() is called with the returned handle.
|
||||
*
|
||||
* Note: If the rollback option is enabled and the running application has the ESP_OTA_IMG_PENDING_VERIFY state then
|
||||
* it will lead to the ESP_ERR_OTA_ROLLBACK_INVALID_STATE error. Confirm the running app before to run download a new app,
|
||||
* use esp_ota_mark_app_valid_cancel_rollback() function for it (this should be done as early as possible when you first download a new application).
|
||||
*
|
||||
* @param partition Pointer to info for partition which will receive the OTA update. Required.
|
||||
* @param image_size Size of new OTA app image. Partition will be erased in order to receive this size of image. If 0 or OTA_SIZE_UNKNOWN, the entire partition is erased.
|
||||
* @param out_handle On success, returns a handle which should be used for subsequent esp_ota_write() and esp_ota_end() calls.
|
||||
@@ -87,7 +65,6 @@ int esp_ota_get_app_elf_sha256(char* dst, size_t size);
|
||||
* - ESP_ERR_OTA_SELECT_INFO_INVALID: The OTA data partition contains invalid data.
|
||||
* - ESP_ERR_INVALID_SIZE: Partition doesn't fit in configured flash size.
|
||||
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
|
||||
* - ESP_ERR_OTA_ROLLBACK_INVALID_STATE: If the running app has not confirmed state. Before performing an update, the application must be valid.
|
||||
*/
|
||||
esp_err_t esp_ota_begin(const esp_partition_t* partition, size_t image_size, esp_ota_handle_t* out_handle);
|
||||
|
||||
@@ -111,29 +88,6 @@ esp_err_t esp_ota_begin(const esp_partition_t* partition, size_t image_size, esp
|
||||
*/
|
||||
esp_err_t esp_ota_write(esp_ota_handle_t handle, const void* data, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Write OTA update data to partition
|
||||
*
|
||||
* This function can write data in non contiguous manner.
|
||||
* If flash encryption is enabled, data should be 16 byte aligned.
|
||||
*
|
||||
* @param handle Handle obtained from esp_ota_begin
|
||||
* @param data Data buffer to write
|
||||
* @param size Size of data buffer in bytes
|
||||
* @param offset Offset in flash partition
|
||||
*
|
||||
* @note While performing OTA, if the packets arrive out of order, esp_ota_write_with_offset() can be used to write data in non contiguous manner.
|
||||
* Use of esp_ota_write_with_offset() in combination with esp_ota_write() is not recommended.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Data was written to flash successfully.
|
||||
* - ESP_ERR_INVALID_ARG: handle is invalid.
|
||||
* - ESP_ERR_OTA_VALIDATE_FAILED: First byte of image contains invalid app image magic byte.
|
||||
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
|
||||
* - ESP_ERR_OTA_SELECT_INFO_INVALID: OTA data partition has invalid contents
|
||||
*/
|
||||
esp_err_t esp_ota_write_with_offset(esp_ota_handle_t handle, const void *data, size_t size, uint32_t offset);
|
||||
|
||||
/**
|
||||
* @brief Finish OTA update and validate newly written app image.
|
||||
*
|
||||
@@ -150,18 +104,6 @@ esp_err_t esp_ota_write_with_offset(esp_ota_handle_t handle, const void *data, s
|
||||
*/
|
||||
esp_err_t esp_ota_end(esp_ota_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Abort OTA update, free the handle and memory associated with it.
|
||||
*
|
||||
* @param handle obtained from esp_ota_begin().
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Handle and its associated memory is freed successfully.
|
||||
* - ESP_ERR_NOT_FOUND: OTA handle was not found.
|
||||
*/
|
||||
esp_err_t esp_ota_abort(esp_ota_handle_t handle);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configure OTA data for a new boot partition
|
||||
*
|
||||
@@ -190,7 +132,7 @@ esp_err_t esp_ota_set_boot_partition(const esp_partition_t* partition);
|
||||
* If the OTA data partition is not present or not valid then the result is the first app partition found in the
|
||||
* partition table. In priority order, this means: the factory app, the first OTA app slot, or the test app partition.
|
||||
*
|
||||
* Note that there is no guarantee the returned partition is a valid app. Use esp_image_verify(ESP_IMAGE_VERIFY, ...) to verify if the
|
||||
* Note that there is no guarantee the returned partition is a valid app. Use esp_image_load(ESP_IMAGE_VERIFY, ...) to verify if the
|
||||
* returned partition contains a bootable image.
|
||||
*
|
||||
* @return Pointer to info for partition structure, or NULL if partition table is invalid or a flash read operation failed. Any returned pointer is valid for the lifetime of the application.
|
||||
@@ -228,119 +170,6 @@ const esp_partition_t* esp_ota_get_running_partition(void);
|
||||
*/
|
||||
const esp_partition_t* esp_ota_get_next_update_partition(const esp_partition_t *start_from);
|
||||
|
||||
/**
|
||||
* @brief Returns esp_app_desc structure for app partition. This structure includes app version.
|
||||
*
|
||||
* Returns a description for the requested app partition.
|
||||
* @param[in] partition Pointer to app partition. (only app partition)
|
||||
* @param[out] app_desc Structure of info about app.
|
||||
* @return
|
||||
* - ESP_OK Successful.
|
||||
* - ESP_ERR_NOT_FOUND app_desc structure is not found. Magic word is incorrect.
|
||||
* - ESP_ERR_NOT_SUPPORTED Partition is not application.
|
||||
* - ESP_ERR_INVALID_ARG Arguments is NULL or if partition's offset exceeds partition size.
|
||||
* - ESP_ERR_INVALID_SIZE Read would go out of bounds of the partition.
|
||||
* - or one of error codes from lower-level flash driver.
|
||||
*/
|
||||
esp_err_t esp_ota_get_partition_description(const esp_partition_t *partition, esp_app_desc_t *app_desc);
|
||||
|
||||
/**
|
||||
* @brief Returns number of ota partitions provided in partition table.
|
||||
*
|
||||
* @return
|
||||
* - Number of OTA partitions
|
||||
*/
|
||||
uint8_t esp_ota_get_app_partition_count(void);
|
||||
|
||||
/**
|
||||
* @brief This function is called to indicate that the running app is working well.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: if successful.
|
||||
*/
|
||||
esp_err_t esp_ota_mark_app_valid_cancel_rollback(void);
|
||||
|
||||
/**
|
||||
* @brief This function is called to roll back to the previously workable app with reboot.
|
||||
*
|
||||
* If rollback is successful then device will reset else API will return with error code.
|
||||
* Checks applications on a flash drive that can be booted in case of rollback.
|
||||
* If the flash does not have at least one app (except the running app) then rollback is not possible.
|
||||
* @return
|
||||
* - ESP_FAIL: if not successful.
|
||||
* - ESP_ERR_OTA_ROLLBACK_FAILED: The rollback is not possible due to flash does not have any apps.
|
||||
*/
|
||||
esp_err_t esp_ota_mark_app_invalid_rollback_and_reboot(void);
|
||||
|
||||
/**
|
||||
* @brief Returns last partition with invalid state (ESP_OTA_IMG_INVALID or ESP_OTA_IMG_ABORTED).
|
||||
*
|
||||
* @return partition.
|
||||
*/
|
||||
const esp_partition_t* esp_ota_get_last_invalid_partition(void);
|
||||
|
||||
/**
|
||||
* @brief Returns state for given partition.
|
||||
*
|
||||
* @param[in] partition Pointer to partition.
|
||||
* @param[out] ota_state state of partition (if this partition has a record in otadata).
|
||||
* @return
|
||||
* - ESP_OK: Successful.
|
||||
* - ESP_ERR_INVALID_ARG: partition or ota_state arguments were NULL.
|
||||
* - ESP_ERR_NOT_SUPPORTED: partition is not ota.
|
||||
* - ESP_ERR_NOT_FOUND: Partition table does not have otadata or state was not found for given partition.
|
||||
*/
|
||||
esp_err_t esp_ota_get_state_partition(const esp_partition_t *partition, esp_ota_img_states_t *ota_state);
|
||||
|
||||
/**
|
||||
* @brief Erase previous boot app partition and corresponding otadata select for this partition.
|
||||
*
|
||||
* When current app is marked to as valid then you can erase previous app partition.
|
||||
* @return
|
||||
* - ESP_OK: Successful, otherwise ESP_ERR.
|
||||
*/
|
||||
esp_err_t esp_ota_erase_last_boot_app_partition(void);
|
||||
|
||||
/**
|
||||
* @brief Checks applications on the slots which can be booted in case of rollback.
|
||||
*
|
||||
* These applications should be valid (marked in otadata as not UNDEFINED, INVALID or ABORTED and crc is good) and be able booted,
|
||||
* and secure_version of app >= secure_version of efuse (if anti-rollback is enabled).
|
||||
*
|
||||
* @return
|
||||
* - True: Returns true if the slots have at least one app (except the running app).
|
||||
* - False: The rollback is not possible.
|
||||
*/
|
||||
bool esp_ota_check_rollback_is_possible(void);
|
||||
|
||||
#if SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1 && (CONFIG_SECURE_BOOT_V2_ENABLED || __DOXYGEN__)
|
||||
|
||||
/**
|
||||
* Secure Boot V2 public key indexes.
|
||||
*/
|
||||
typedef enum {
|
||||
SECURE_BOOT_PUBLIC_KEY_INDEX_0, /*!< Points to the 0th index of the Secure Boot v2 public key */
|
||||
SECURE_BOOT_PUBLIC_KEY_INDEX_1, /*!< Points to the 1st index of the Secure Boot v2 public key */
|
||||
SECURE_BOOT_PUBLIC_KEY_INDEX_2 /*!< Points to the 2nd index of the Secure Boot v2 public key */
|
||||
} esp_ota_secure_boot_public_key_index_t;
|
||||
|
||||
/**
|
||||
* @brief Revokes the old signature digest. To be called in the application after the rollback logic.
|
||||
*
|
||||
* Relevant for Secure boot v2 on ESP32-S2 where upto 3 key digests can be stored (Key #N-1, Key #N, Key #N+1).
|
||||
* When key #N-1 used to sign an app is invalidated, an OTA update is to be sent with an app signed with key #N-1 & Key #N.
|
||||
* After successfully booting the OTA app should call this function to revoke Key #N-1.
|
||||
*
|
||||
* @param index - The index of the signature block to be revoked
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: If revocation is successful.
|
||||
* - ESP_ERR_INVALID_ARG: If the index of the public key to be revoked is incorrect.
|
||||
* - ESP_FAIL: If secure boot v2 has not been enabled.
|
||||
*/
|
||||
esp_err_t esp_ota_revoke_secure_boot_public_key(esp_ota_secure_boot_public_key_index_t index);
|
||||
#endif /* SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,373 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# otatool is used to perform ota-level operations - flashing ota partition
|
||||
# erasing ota partition and switching ota partition
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
from __future__ import division, print_function
|
||||
|
||||
import argparse
|
||||
import binascii
|
||||
import collections
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
try:
|
||||
from parttool import PARTITION_TABLE_OFFSET, PartitionName, PartitionType, ParttoolTarget
|
||||
except ImportError:
|
||||
COMPONENTS_PATH = os.path.expandvars(os.path.join('$IDF_PATH', 'components'))
|
||||
PARTTOOL_DIR = os.path.join(COMPONENTS_PATH, 'partition_table')
|
||||
sys.path.append(PARTTOOL_DIR)
|
||||
from parttool import PARTITION_TABLE_OFFSET, PartitionName, PartitionType, ParttoolTarget
|
||||
|
||||
__version__ = '2.0'
|
||||
|
||||
SPI_FLASH_SEC_SIZE = 0x2000
|
||||
|
||||
quiet = False
|
||||
|
||||
|
||||
def status(msg):
|
||||
if not quiet:
|
||||
print(msg)
|
||||
|
||||
|
||||
class OtatoolTarget():
|
||||
|
||||
OTADATA_PARTITION = PartitionType('data', 'ota')
|
||||
|
||||
def __init__(self, port=None, baud=None, partition_table_offset=PARTITION_TABLE_OFFSET, partition_table_file=None,
|
||||
spi_flash_sec_size=SPI_FLASH_SEC_SIZE, esptool_args=[], esptool_write_args=[],
|
||||
esptool_read_args=[], esptool_erase_args=[]):
|
||||
self.target = ParttoolTarget(port, baud, partition_table_offset, partition_table_file, esptool_args,
|
||||
esptool_write_args, esptool_read_args, esptool_erase_args)
|
||||
self.spi_flash_sec_size = spi_flash_sec_size
|
||||
|
||||
temp_file = tempfile.NamedTemporaryFile(delete=False)
|
||||
temp_file.close()
|
||||
try:
|
||||
self.target.read_partition(OtatoolTarget.OTADATA_PARTITION, temp_file.name)
|
||||
with open(temp_file.name, 'rb') as f:
|
||||
self.otadata = f.read()
|
||||
finally:
|
||||
os.unlink(temp_file.name)
|
||||
|
||||
def _check_otadata_partition(self):
|
||||
if not self.otadata:
|
||||
raise Exception('No otadata partition found')
|
||||
|
||||
def erase_otadata(self):
|
||||
self._check_otadata_partition()
|
||||
self.target.erase_partition(OtatoolTarget.OTADATA_PARTITION)
|
||||
|
||||
def _get_otadata_info(self):
|
||||
info = []
|
||||
|
||||
otadata_info = collections.namedtuple('otadata_info', 'seq crc')
|
||||
|
||||
for i in range(2):
|
||||
start = i * (self.spi_flash_sec_size >> 1)
|
||||
|
||||
seq = bytearray(self.otadata[start:start + 4])
|
||||
crc = bytearray(self.otadata[start + 28:start + 32])
|
||||
|
||||
seq = struct.unpack('I', seq)
|
||||
crc = struct.unpack('I', crc)
|
||||
info.append(otadata_info(seq[0], crc[0]))
|
||||
|
||||
return info
|
||||
|
||||
def _get_partition_id_from_ota_id(self, ota_id):
|
||||
if isinstance(ota_id, int):
|
||||
return PartitionType('app', 'ota_' + str(ota_id))
|
||||
else:
|
||||
return PartitionName(ota_id)
|
||||
|
||||
def switch_ota_partition(self, ota_id):
|
||||
self._check_otadata_partition()
|
||||
|
||||
import gen_esp32part as gen
|
||||
|
||||
def is_otadata_info_valid(status):
|
||||
seq = status.seq % (1 << 32)
|
||||
crc = binascii.crc32(struct.pack('I', seq), 0xFFFFFFFF) % (1 << 32)
|
||||
return seq < (int('0xFFFFFFFF', 16) % (1 << 32)) and status.crc == crc
|
||||
|
||||
partition_table = self.target.partition_table
|
||||
|
||||
ota_partitions = list()
|
||||
|
||||
for i in range(gen.NUM_PARTITION_SUBTYPE_APP_OTA):
|
||||
ota_partition = filter(lambda p: p.subtype == (gen.MIN_PARTITION_SUBTYPE_APP_OTA + i), partition_table)
|
||||
|
||||
try:
|
||||
ota_partitions.append(list(ota_partition)[0])
|
||||
except IndexError:
|
||||
break
|
||||
|
||||
ota_partitions = sorted(ota_partitions, key=lambda p: p.subtype)
|
||||
|
||||
if not ota_partitions:
|
||||
raise Exception('No ota app partitions found')
|
||||
|
||||
# Look for the app partition to switch to
|
||||
ota_partition_next = None
|
||||
|
||||
try:
|
||||
if isinstance(ota_id, int):
|
||||
ota_partition_next = filter(lambda p: p.subtype - gen.MIN_PARTITION_SUBTYPE_APP_OTA == ota_id, ota_partitions)
|
||||
else:
|
||||
ota_partition_next = filter(lambda p: p.name == ota_id, ota_partitions)
|
||||
|
||||
ota_partition_next = list(ota_partition_next)[0]
|
||||
except IndexError:
|
||||
raise Exception('Partition to switch to not found')
|
||||
|
||||
otadata_info = self._get_otadata_info()
|
||||
|
||||
# Find the copy to base the computation for ota sequence number on
|
||||
otadata_compute_base = -1
|
||||
|
||||
# Both are valid, take the max as computation base
|
||||
if is_otadata_info_valid(otadata_info[0]) and is_otadata_info_valid(otadata_info[1]):
|
||||
if otadata_info[0].seq >= otadata_info[1].seq:
|
||||
otadata_compute_base = 0
|
||||
else:
|
||||
otadata_compute_base = 1
|
||||
# Only one copy is valid, use that
|
||||
elif is_otadata_info_valid(otadata_info[0]):
|
||||
otadata_compute_base = 0
|
||||
elif is_otadata_info_valid(otadata_info[1]):
|
||||
otadata_compute_base = 1
|
||||
# Both are invalid (could be initial state - all 0xFF's)
|
||||
else:
|
||||
pass
|
||||
|
||||
ota_seq_next = 0
|
||||
ota_partitions_num = len(ota_partitions)
|
||||
|
||||
target_seq = (ota_partition_next.subtype & 0x0F) + 1
|
||||
|
||||
# Find the next ota sequence number
|
||||
if otadata_compute_base == 0 or otadata_compute_base == 1:
|
||||
base_seq = otadata_info[otadata_compute_base].seq % (1 << 32)
|
||||
|
||||
i = 0
|
||||
while base_seq > target_seq % ota_partitions_num + i * ota_partitions_num:
|
||||
i += 1
|
||||
|
||||
ota_seq_next = target_seq % ota_partitions_num + i * ota_partitions_num
|
||||
else:
|
||||
ota_seq_next = target_seq
|
||||
|
||||
# Create binary data from computed values
|
||||
ota_seq_next = struct.pack('I', ota_seq_next)
|
||||
ota_seq_crc_next = binascii.crc32(ota_seq_next, 0xFFFFFFFF) % (1 << 32)
|
||||
ota_seq_crc_next = struct.pack('I', ota_seq_crc_next)
|
||||
|
||||
temp_file = tempfile.NamedTemporaryFile(delete=False)
|
||||
temp_file.close()
|
||||
|
||||
try:
|
||||
with open(temp_file.name, 'wb') as otadata_next_file:
|
||||
start = (1 if otadata_compute_base == 0 else 0) * (self.spi_flash_sec_size >> 1)
|
||||
|
||||
otadata_next_file.write(self.otadata)
|
||||
|
||||
otadata_next_file.seek(start)
|
||||
otadata_next_file.write(ota_seq_next)
|
||||
|
||||
otadata_next_file.seek(start + 28)
|
||||
otadata_next_file.write(ota_seq_crc_next)
|
||||
|
||||
otadata_next_file.flush()
|
||||
|
||||
self.target.write_partition(OtatoolTarget.OTADATA_PARTITION, temp_file.name)
|
||||
finally:
|
||||
os.unlink(temp_file.name)
|
||||
|
||||
def read_ota_partition(self, ota_id, output):
|
||||
self.target.read_partition(self._get_partition_id_from_ota_id(ota_id), output)
|
||||
|
||||
def write_ota_partition(self, ota_id, input):
|
||||
self.target.write_partition(self._get_partition_id_from_ota_id(ota_id), input)
|
||||
|
||||
def erase_ota_partition(self, ota_id):
|
||||
self.target.erase_partition(self._get_partition_id_from_ota_id(ota_id))
|
||||
|
||||
|
||||
def _read_otadata(target):
|
||||
target._check_otadata_partition()
|
||||
|
||||
otadata_info = target._get_otadata_info()
|
||||
|
||||
print(' {:8s} \t {:8s} | \t {:8s} \t {:8s}'.format('OTA_SEQ', 'CRC', 'OTA_SEQ', 'CRC'))
|
||||
print('Firmware: 0x{:08x} \t0x{:08x} | \t0x{:08x} \t 0x{:08x}'.format(otadata_info[0].seq, otadata_info[0].crc,
|
||||
otadata_info[1].seq, otadata_info[1].crc))
|
||||
|
||||
|
||||
def _erase_otadata(target):
|
||||
target.erase_otadata()
|
||||
status('Erased ota_data partition contents')
|
||||
|
||||
|
||||
def _switch_ota_partition(target, ota_id):
|
||||
target.switch_ota_partition(ota_id)
|
||||
|
||||
|
||||
def _read_ota_partition(target, ota_id, output):
|
||||
target.read_ota_partition(ota_id, output)
|
||||
status('Read ota partition contents to file {}'.format(output))
|
||||
|
||||
|
||||
def _write_ota_partition(target, ota_id, input):
|
||||
target.write_ota_partition(ota_id, input)
|
||||
status('Written contents of file {} to ota partition'.format(input))
|
||||
|
||||
|
||||
def _erase_ota_partition(target, ota_id):
|
||||
target.erase_ota_partition(ota_id)
|
||||
status('Erased contents of ota partition')
|
||||
|
||||
|
||||
def main():
|
||||
global quiet
|
||||
|
||||
parser = argparse.ArgumentParser('ESP-IDF OTA Partitions Tool')
|
||||
|
||||
parser.add_argument('--quiet', '-q', help='suppress stderr messages', action='store_true')
|
||||
parser.add_argument('--esptool-args', help='additional main arguments for esptool', nargs='+')
|
||||
parser.add_argument('--esptool-write-args', help='additional subcommand arguments for esptool write_flash', nargs='+')
|
||||
parser.add_argument('--esptool-read-args', help='additional subcommand arguments for esptool read_flash', nargs='+')
|
||||
parser.add_argument('--esptool-erase-args', help='additional subcommand arguments for esptool erase_region', nargs='+')
|
||||
|
||||
# There are two possible sources for the partition table: a device attached to the host
|
||||
# or a partition table CSV/binary file. These sources are mutually exclusive.
|
||||
parser.add_argument('--port', '-p', help='port where the device to read the partition table from is attached')
|
||||
|
||||
parser.add_argument('--baud', '-b', help='baudrate to use', type=int)
|
||||
|
||||
parser.add_argument('--partition-table-offset', '-o', help='offset to read the partition table from', type=str)
|
||||
|
||||
parser.add_argument('--partition-table-file', '-f', help='file (CSV/binary) to read the partition table from; \
|
||||
overrides device attached to specified port as the partition table source when defined')
|
||||
|
||||
subparsers = parser.add_subparsers(dest='operation', help='run otatool -h for additional help')
|
||||
|
||||
spi_flash_sec_size = argparse.ArgumentParser(add_help=False)
|
||||
spi_flash_sec_size.add_argument('--spi-flash-sec-size', help='value of SPI_FLASH_SEC_SIZE macro', type=str)
|
||||
|
||||
# Specify the supported operations
|
||||
subparsers.add_parser('read_otadata', help='read otadata partition', parents=[spi_flash_sec_size])
|
||||
subparsers.add_parser('erase_otadata', help='erase otadata partition')
|
||||
|
||||
slot_or_name_parser = argparse.ArgumentParser(add_help=False)
|
||||
slot_or_name_parser_args = slot_or_name_parser.add_mutually_exclusive_group()
|
||||
slot_or_name_parser_args.add_argument('--slot', help='slot number of the ota partition', type=int)
|
||||
slot_or_name_parser_args.add_argument('--name', help='name of the ota partition')
|
||||
|
||||
subparsers.add_parser('switch_ota_partition', help='switch otadata partition', parents=[slot_or_name_parser, spi_flash_sec_size])
|
||||
|
||||
read_ota_partition_subparser = subparsers.add_parser('read_ota_partition', help='read contents of an ota partition', parents=[slot_or_name_parser])
|
||||
read_ota_partition_subparser.add_argument('--output', help='file to write the contents of the ota partition to', required=True)
|
||||
|
||||
write_ota_partition_subparser = subparsers.add_parser('write_ota_partition', help='write contents to an ota partition', parents=[slot_or_name_parser])
|
||||
write_ota_partition_subparser.add_argument('--input', help='file whose contents to write to the ota partition')
|
||||
|
||||
subparsers.add_parser('erase_ota_partition', help='erase contents of an ota partition', parents=[slot_or_name_parser])
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
quiet = args.quiet
|
||||
|
||||
# No operation specified, display help and exit
|
||||
if args.operation is None:
|
||||
if not quiet:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
target_args = {}
|
||||
|
||||
if args.port:
|
||||
target_args['port'] = args.port
|
||||
|
||||
if args.partition_table_file:
|
||||
target_args['partition_table_file'] = args.partition_table_file
|
||||
|
||||
if args.partition_table_offset:
|
||||
target_args['partition_table_offset'] = int(args.partition_table_offset, 0)
|
||||
|
||||
try:
|
||||
if args.spi_flash_sec_size:
|
||||
target_args['spi_flash_sec_size'] = int(args.spi_flash_sec_size, 0)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
if args.esptool_args:
|
||||
target_args['esptool_args'] = args.esptool_args
|
||||
|
||||
if args.esptool_write_args:
|
||||
target_args['esptool_write_args'] = args.esptool_write_args
|
||||
|
||||
if args.esptool_read_args:
|
||||
target_args['esptool_read_args'] = args.esptool_read_args
|
||||
|
||||
if args.esptool_erase_args:
|
||||
target_args['esptool_erase_args'] = args.esptool_erase_args
|
||||
|
||||
if args.baud:
|
||||
target_args['baud'] = args.baud
|
||||
|
||||
target = OtatoolTarget(**target_args)
|
||||
|
||||
# Create the operation table and execute the operation
|
||||
common_args = {'target':target}
|
||||
|
||||
ota_id = []
|
||||
|
||||
try:
|
||||
if args.name is not None:
|
||||
ota_id = ['name']
|
||||
else:
|
||||
if args.slot is not None:
|
||||
ota_id = ['slot']
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
otatool_ops = {
|
||||
'read_otadata':(_read_otadata, []),
|
||||
'erase_otadata':(_erase_otadata, []),
|
||||
'switch_ota_partition':(_switch_ota_partition, ota_id),
|
||||
'read_ota_partition':(_read_ota_partition, ['output'] + ota_id),
|
||||
'write_ota_partition':(_write_ota_partition, ['input'] + ota_id),
|
||||
'erase_ota_partition':(_erase_ota_partition, ota_id)
|
||||
}
|
||||
|
||||
(op, op_args) = otatool_ops[args.operation]
|
||||
|
||||
for op_arg in op_args:
|
||||
common_args.update({op_arg:vars(args)[op_arg]})
|
||||
|
||||
try:
|
||||
common_args['ota_id'] = common_args.pop('name')
|
||||
except KeyError:
|
||||
try:
|
||||
common_args['ota_id'] = common_args.pop('slot')
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if quiet:
|
||||
# If exceptions occur, suppress and exit quietly
|
||||
try:
|
||||
op(**common_args)
|
||||
except Exception:
|
||||
sys.exit(2)
|
||||
else:
|
||||
op(**common_args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,4 +0,0 @@
|
||||
idf_component_register(SRC_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES cmock test_utils app_update bootloader_support nvs_flash
|
||||
)
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "esp_ota_ops.h"
|
||||
#include "unity.h"
|
||||
|
||||
TEST_CASE("esp_ota_get_app_elf_sha256 test", "[esp_app_desc]")
|
||||
{
|
||||
const int sha256_hex_len = CONFIG_APP_RETRIEVE_LEN_ELF_SHA;
|
||||
char dst[sha256_hex_len + 2];
|
||||
const char fill = 0xcc;
|
||||
int res;
|
||||
size_t len;
|
||||
|
||||
char ref_sha256[sha256_hex_len + 1];
|
||||
const esp_app_desc_t* desc = esp_ota_get_app_description();
|
||||
for (int i = 0; i < sizeof(ref_sha256) / 2; ++i) {
|
||||
snprintf(ref_sha256 + 2*i, 3, "%02x", desc->app_elf_sha256[i]);
|
||||
}
|
||||
ref_sha256[sha256_hex_len] = 0;
|
||||
|
||||
printf("Ref: %s\n", ref_sha256);
|
||||
|
||||
memset(dst, fill, sizeof(dst));
|
||||
len = sizeof(dst);
|
||||
res = esp_ota_get_app_elf_sha256(dst, len);
|
||||
printf("%d: %s (%d)\n", len, dst, res);
|
||||
TEST_ASSERT_EQUAL(sha256_hex_len + 1, res);
|
||||
TEST_ASSERT_EQUAL(0, memcmp(dst, ref_sha256, res - 1));
|
||||
TEST_ASSERT_EQUAL_HEX(0, dst[sha256_hex_len]);
|
||||
TEST_ASSERT_EQUAL_HEX(fill, dst[sha256_hex_len + 1]);
|
||||
|
||||
memset(dst, fill, sizeof(dst));
|
||||
len = 9;
|
||||
res = esp_ota_get_app_elf_sha256(dst, len);
|
||||
printf("%d: %s (%d)\n", len, dst, res);
|
||||
TEST_ASSERT_EQUAL(9, res);
|
||||
TEST_ASSERT_EQUAL(0, memcmp(dst, ref_sha256, res - 1));
|
||||
TEST_ASSERT_EQUAL_HEX(0, dst[8]);
|
||||
TEST_ASSERT_EQUAL_HEX(fill, dst[9]);
|
||||
|
||||
memset(dst, fill, sizeof(dst));
|
||||
len = 8;
|
||||
res = esp_ota_get_app_elf_sha256(dst, len);
|
||||
printf("%d: %s (%d)\n", len, dst, res);
|
||||
// should output even number of characters plus '\0'
|
||||
TEST_ASSERT_EQUAL(7, res);
|
||||
TEST_ASSERT_EQUAL(0, memcmp(dst, ref_sha256, res - 1));
|
||||
TEST_ASSERT_EQUAL_HEX(0, dst[6]);
|
||||
TEST_ASSERT_EQUAL_HEX(fill, dst[7]);
|
||||
TEST_ASSERT_EQUAL_HEX(fill, dst[8]);
|
||||
}
|
||||
@@ -1,8 +1,3 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -13,7 +8,7 @@
|
||||
#include <unity.h>
|
||||
#include <test_utils.h>
|
||||
#include <esp_ota_ops.h>
|
||||
#include "bootloader_common.h"
|
||||
|
||||
|
||||
/* These OTA tests currently don't assume an OTA partition exists
|
||||
on the device, so they're a bit limited
|
||||
@@ -63,7 +58,7 @@ TEST_CASE("esp_ota_get_next_update_partition logic", "[ota]")
|
||||
TEST_ASSERT_NOT_NULL(ota_1);
|
||||
TEST_ASSERT_NULL(ota_2); /* this partition shouldn't exist in test partition table */
|
||||
|
||||
TEST_ASSERT_EQUAL_PTR(factory, running); /* this may not be true if/when we get OTA tests that do OTA updates */
|
||||
TEST_ASSERT_EQUAL_PTR(factory, running); /* this may not be true if/when we get OTA tests that do OTA updates */
|
||||
|
||||
/* (The test steps verify subtypes before verifying pointer equality, because the failure messages are more readable
|
||||
this way.)
|
||||
@@ -89,26 +84,3 @@ TEST_CASE("esp_ota_get_next_update_partition logic", "[ota]")
|
||||
TEST_ASSERT_EQUAL_PTR(ota_0, p);
|
||||
}
|
||||
|
||||
TEST_CASE("esp_ota_get_partition_description", "[ota]")
|
||||
{
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
TEST_ASSERT_NOT_NULL(running);
|
||||
esp_app_desc_t app_desc1, app_desc2;
|
||||
TEST_ESP_OK(esp_ota_get_partition_description(running, &app_desc1));
|
||||
const esp_partition_pos_t running_pos = {
|
||||
.offset = running->address,
|
||||
.size = running->size
|
||||
};
|
||||
TEST_ESP_OK(bootloader_common_get_partition_description(&running_pos, &app_desc2));
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE((uint8_t *)&app_desc1, (uint8_t *)&app_desc2, sizeof(app_desc1), "must be the same");
|
||||
|
||||
const esp_partition_t *not_app = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
TEST_ASSERT_NOT_NULL(not_app);
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_ota_get_partition_description(not_app, &app_desc1));
|
||||
const esp_partition_pos_t not_app_pos = {
|
||||
.offset = not_app->address,
|
||||
.size = not_app->size
|
||||
};
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, bootloader_common_get_partition_description(¬_app_pos, &app_desc1));
|
||||
}
|
||||
|
||||
@@ -1,826 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/*
|
||||
* Tests for switching between partitions: factory, OTAx, test.
|
||||
*/
|
||||
|
||||
#include <esp_types.h>
|
||||
#include <stdio.h>
|
||||
#include "string.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/rom/spi_flash.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/spi_flash.h"
|
||||
#endif
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "unity.h"
|
||||
|
||||
#include "bootloader_common.h"
|
||||
#include "../include_bootloader/bootloader_flash_priv.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_sleep.h"
|
||||
|
||||
|
||||
RTC_DATA_ATTR static int boot_count = 0;
|
||||
static const char *TAG = "ota_test";
|
||||
|
||||
/* @brief Copies a current app to next partition using handle.
|
||||
*
|
||||
* @param[in] update_handle - Handle of API ota.
|
||||
* @param[in] cur_app - Current app.
|
||||
*/
|
||||
static void copy_app_partition(esp_ota_handle_t update_handle, const esp_partition_t *curr_app)
|
||||
{
|
||||
const void *partition_bin = NULL;
|
||||
spi_flash_mmap_handle_t data_map;
|
||||
ESP_LOGI(TAG, "start the copy process");
|
||||
TEST_ESP_OK(esp_partition_mmap(curr_app, 0, curr_app->size, SPI_FLASH_MMAP_DATA, &partition_bin, &data_map));
|
||||
TEST_ESP_OK(esp_ota_write(update_handle, (const void *)partition_bin, curr_app->size));
|
||||
spi_flash_munmap(data_map);
|
||||
ESP_LOGI(TAG, "finish the copy process");
|
||||
}
|
||||
|
||||
/* @brief Copies a current app to next partition using handle.
|
||||
*
|
||||
* @param[in] update_handle - Handle of API ota.
|
||||
* @param[in] cur_app - Current app.
|
||||
*/
|
||||
static void copy_app_partition_with_offset(esp_ota_handle_t update_handle, const esp_partition_t *curr_app)
|
||||
{
|
||||
const void *partition_bin = NULL;
|
||||
spi_flash_mmap_handle_t data_map;
|
||||
ESP_LOGI(TAG, "start the copy process");
|
||||
uint32_t offset = 0, bytes_to_write = curr_app->size;
|
||||
uint32_t write_bytes;
|
||||
while (bytes_to_write > 0) {
|
||||
write_bytes = (bytes_to_write > (4 * 1024)) ? (4 * 1024) : bytes_to_write;
|
||||
TEST_ESP_OK(esp_partition_mmap(curr_app, offset, write_bytes, SPI_FLASH_MMAP_DATA, &partition_bin, &data_map));
|
||||
TEST_ESP_OK(esp_ota_write_with_offset(update_handle, (const void *)partition_bin, write_bytes, offset));
|
||||
spi_flash_munmap(data_map);
|
||||
bytes_to_write -= write_bytes;
|
||||
offset += write_bytes;
|
||||
}
|
||||
ESP_LOGI(TAG, "finish the copy process");
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BOOTLOADER_FACTORY_RESET) || defined(CONFIG_BOOTLOADER_APP_TEST)
|
||||
/* @brief Copies partition from source partition to destination partition.
|
||||
*
|
||||
* Partitions can be of any types and subtypes.
|
||||
* @param[in] dst_partition - Destination partition
|
||||
* @param[in] src_partition - Source partition
|
||||
*/
|
||||
static void copy_partition(const esp_partition_t *dst_partition, const esp_partition_t *src_partition)
|
||||
{
|
||||
const void *partition_bin = NULL;
|
||||
spi_flash_mmap_handle_t data_map;
|
||||
TEST_ESP_OK(esp_partition_mmap(src_partition, 0, src_partition->size, SPI_FLASH_MMAP_DATA, &partition_bin, &data_map));
|
||||
TEST_ESP_OK(esp_partition_erase_range(dst_partition, 0, dst_partition->size));
|
||||
TEST_ESP_OK(esp_partition_write(dst_partition, 0, (const void *)partition_bin, dst_partition->size));
|
||||
spi_flash_munmap(data_map);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* @brief Get the next partition of OTA for the update.
|
||||
*
|
||||
* @return The next partition of OTA(OTA0-15).
|
||||
*/
|
||||
static const esp_partition_t * get_next_update_partition(void)
|
||||
{
|
||||
const esp_partition_t *update_partition = esp_ota_get_next_update_partition(NULL);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, update_partition);
|
||||
ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", update_partition->subtype, update_partition->address);
|
||||
return update_partition;
|
||||
}
|
||||
|
||||
/* @brief Copies a current app to next partition (OTA0-15) and then configure OTA data for a new boot partition.
|
||||
*
|
||||
* @param[in] cur_app_partition - Current app.
|
||||
* @param[in] next_app_partition - Next app for boot.
|
||||
*/
|
||||
static void copy_current_app_to_next_part(const esp_partition_t *cur_app_partition, const esp_partition_t *next_app_partition)
|
||||
{
|
||||
esp_ota_get_next_update_partition(NULL);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, next_app_partition);
|
||||
ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", next_app_partition->subtype, next_app_partition->address);
|
||||
|
||||
esp_ota_handle_t update_handle = 0;
|
||||
TEST_ESP_OK(esp_ota_begin(next_app_partition, OTA_SIZE_UNKNOWN, &update_handle));
|
||||
|
||||
copy_app_partition(update_handle, cur_app_partition);
|
||||
|
||||
TEST_ESP_OK(esp_ota_end(update_handle));
|
||||
TEST_ESP_OK(esp_ota_set_boot_partition(next_app_partition));
|
||||
}
|
||||
|
||||
/* @brief Copies a current app to next partition (OTA0-15) and then configure OTA data for a new boot partition.
|
||||
*
|
||||
* @param[in] cur_app_partition - Current app.
|
||||
* @param[in] next_app_partition - Next app for boot.
|
||||
*/
|
||||
static void copy_current_app_to_next_part_with_offset(const esp_partition_t *cur_app_partition, const esp_partition_t *next_app_partition)
|
||||
{
|
||||
esp_ota_get_next_update_partition(NULL);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, next_app_partition);
|
||||
ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", next_app_partition->subtype, next_app_partition->address);
|
||||
|
||||
esp_ota_handle_t update_handle = 0;
|
||||
TEST_ESP_OK(esp_ota_begin(next_app_partition, OTA_SIZE_UNKNOWN, &update_handle));
|
||||
|
||||
copy_app_partition_with_offset(update_handle, cur_app_partition);
|
||||
|
||||
TEST_ESP_OK(esp_ota_end(update_handle));
|
||||
TEST_ESP_OK(esp_ota_set_boot_partition(next_app_partition));
|
||||
}
|
||||
|
||||
/* @brief Erase otadata partition
|
||||
*/
|
||||
static void erase_ota_data(void)
|
||||
{
|
||||
const esp_partition_t *data_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, data_partition);
|
||||
TEST_ESP_OK(esp_partition_erase_range(data_partition, 0, 2 * SPI_FLASH_SEC_SIZE));
|
||||
}
|
||||
|
||||
/* @brief Reboots ESP using mode deep sleep. This mode guaranty that RTC_DATA_ATTR variables is not reset.
|
||||
*/
|
||||
static void reboot_as_deep_sleep(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "reboot as deep sleep");
|
||||
esp_sleep_enable_timer_wakeup(2000);
|
||||
esp_deep_sleep_start();
|
||||
}
|
||||
|
||||
/* @brief Copies a current app to next partition (OTA0-15), after that ESP is rebooting and run this (the next) OTAx.
|
||||
*/
|
||||
static void copy_current_app_to_next_part_and_reboot(void)
|
||||
{
|
||||
const esp_partition_t *cur_app = esp_ota_get_running_partition();
|
||||
ESP_LOGI(TAG, "copy current app to next part");
|
||||
copy_current_app_to_next_part(cur_app, get_next_update_partition());
|
||||
reboot_as_deep_sleep();
|
||||
}
|
||||
|
||||
/* @brief Copies a current app to next partition (OTA0-15) using esp_ota_write_with_offest(), after that ESP is rebooting and run this (the next) OTAx.
|
||||
*/
|
||||
static void copy_current_app_to_next_part_with_offset_and_reboot(void)
|
||||
{
|
||||
const esp_partition_t *cur_app = esp_ota_get_running_partition();
|
||||
ESP_LOGI(TAG, "copy current app to next part");
|
||||
copy_current_app_to_next_part_with_offset(cur_app, get_next_update_partition());
|
||||
reboot_as_deep_sleep();
|
||||
}
|
||||
|
||||
/* @brief Get running app.
|
||||
*
|
||||
* @return The next partition of OTA(OTA0-15).
|
||||
*/
|
||||
static const esp_partition_t* get_running_firmware(void)
|
||||
{
|
||||
const esp_partition_t *configured = esp_ota_get_boot_partition();
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)",
|
||||
running->type, running->subtype, running->address);
|
||||
ESP_LOGI(TAG, "Configured partition type %d subtype %d (offset 0x%08x)",
|
||||
configured->type, configured->subtype, configured->address);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, configured);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, running);
|
||||
if (running->subtype != ESP_PARTITION_SUBTYPE_APP_TEST) {
|
||||
TEST_ASSERT_EQUAL_PTR(running, configured);
|
||||
}
|
||||
return running;
|
||||
}
|
||||
|
||||
// type of a corrupt ota_data
|
||||
typedef enum {
|
||||
CORR_CRC_1_SECTOR_OTA_DATA = (1 << 0), /*!< Corrupt CRC only 1 sector of ota_data */
|
||||
CORR_CRC_2_SECTOR_OTA_DATA = (1 << 1), /*!< Corrupt CRC only 2 sector of ota_data */
|
||||
} corrupt_ota_data_t;
|
||||
|
||||
/* @brief Get two copies ota_data from otadata partition.
|
||||
*
|
||||
* @param[in] otadata_partition - otadata partition.
|
||||
* @param[out] ota_data_0 - First copy from otadata_partition.
|
||||
* @param[out] ota_data_1 - Second copy from otadata_partition.
|
||||
*/
|
||||
static void get_ota_data(const esp_partition_t *otadata_partition, esp_ota_select_entry_t *ota_data_0, esp_ota_select_entry_t *ota_data_1)
|
||||
{
|
||||
uint32_t offset = otadata_partition->address;
|
||||
uint32_t size = otadata_partition->size;
|
||||
if (offset != 0) {
|
||||
const esp_ota_select_entry_t *ota_select_map;
|
||||
ota_select_map = bootloader_mmap(offset, size);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, ota_select_map);
|
||||
|
||||
memcpy(ota_data_0, ota_select_map, sizeof(esp_ota_select_entry_t));
|
||||
memcpy(ota_data_1, (uint8_t *)ota_select_map + SPI_FLASH_SEC_SIZE, sizeof(esp_ota_select_entry_t));
|
||||
bootloader_munmap(ota_select_map);
|
||||
}
|
||||
}
|
||||
|
||||
/* @brief Writes a ota_data into required sector of otadata_partition.
|
||||
*
|
||||
* @param[in] otadata_partition - Partition information otadata.
|
||||
* @param[in] ota_data - otadata structure.
|
||||
* @param[in] sec_id - Sector number 0 or 1.
|
||||
*/
|
||||
static void write_ota_data(const esp_partition_t *otadata_partition, esp_ota_select_entry_t *ota_data, int sec_id)
|
||||
{
|
||||
esp_partition_write(otadata_partition, SPI_FLASH_SEC_SIZE * sec_id, &ota_data[sec_id], sizeof(esp_ota_select_entry_t));
|
||||
}
|
||||
|
||||
/* @brief Makes a corrupt of ota_data.
|
||||
* @param[in] err - type error
|
||||
*/
|
||||
static void corrupt_ota_data(corrupt_ota_data_t err)
|
||||
{
|
||||
esp_ota_select_entry_t ota_data[2];
|
||||
|
||||
const esp_partition_t *otadata_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, otadata_partition);
|
||||
get_ota_data(otadata_partition, &ota_data[0], &ota_data[1]);
|
||||
|
||||
if (err & CORR_CRC_1_SECTOR_OTA_DATA) {
|
||||
ota_data[0].crc = 0;
|
||||
}
|
||||
if (err & CORR_CRC_2_SECTOR_OTA_DATA) {
|
||||
ota_data[1].crc = 0;
|
||||
}
|
||||
TEST_ESP_OK(esp_partition_erase_range(otadata_partition, 0, otadata_partition->size));
|
||||
write_ota_data(otadata_partition, &ota_data[0], 0);
|
||||
write_ota_data(otadata_partition, &ota_data[1], 1);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BOOTLOADER_FACTORY_RESET) || defined(CONFIG_BOOTLOADER_APP_TEST)
|
||||
/* @brief Sets the pin number to output and sets output level as low. After reboot (deep sleep) this pin keep the same level.
|
||||
*
|
||||
* The output level of the pad will be force locked and can not be changed.
|
||||
* Power down or call gpio_hold_dis will disable this function.
|
||||
*
|
||||
* @param[in] num_pin - Pin number
|
||||
*/
|
||||
static void set_output_pin(uint32_t num_pin)
|
||||
{
|
||||
TEST_ESP_OK(gpio_hold_dis(num_pin));
|
||||
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||
io_conf.pin_bit_mask = (1ULL << num_pin);
|
||||
io_conf.pull_down_en = 0;
|
||||
io_conf.pull_up_en = 0;
|
||||
TEST_ESP_OK(gpio_config(&io_conf));
|
||||
|
||||
TEST_ESP_OK(gpio_set_level(num_pin, 0));
|
||||
TEST_ESP_OK(gpio_hold_en(num_pin));
|
||||
}
|
||||
|
||||
/* @brief Unset the pin number hold function.
|
||||
*/
|
||||
static void reset_output_pin(uint32_t num_pin)
|
||||
{
|
||||
TEST_ESP_OK(gpio_hold_dis(num_pin));
|
||||
TEST_ESP_OK(gpio_reset_pin(num_pin));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void mark_app_valid(void)
|
||||
{
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
TEST_ESP_OK(esp_ota_mark_app_valid_cancel_rollback());
|
||||
#endif
|
||||
}
|
||||
|
||||
/* @brief Checks and prepares the partition so that the factory app is launched after that.
|
||||
*/
|
||||
static void start_test(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "boot count 1 - reset");
|
||||
boot_count = 1;
|
||||
erase_ota_data();
|
||||
ESP_LOGI(TAG, "ota_data erased");
|
||||
reboot_as_deep_sleep();
|
||||
}
|
||||
|
||||
static void test_flow1(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
copy_current_app_to_next_part_and_reboot();
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
copy_current_app_to_next_part_and_reboot();
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "OTA1");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
copy_current_app_to_next_part_and_reboot();
|
||||
break;
|
||||
case 5:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
mark_app_valid();
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
erase_ota_data();
|
||||
break;
|
||||
default:
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> copy OTA0 to OTA1 -> reboot --//--
|
||||
// 4 Stage: run OTA1 -> check it -> copy OTA1 to OTA0 -> reboot --//--
|
||||
// 5 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow1, test_flow1, test_flow1, test_flow1);
|
||||
|
||||
static void test_flow2(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
copy_current_app_to_next_part_and_reboot();
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
copy_current_app_to_next_part(cur_app, get_next_update_partition());
|
||||
corrupt_ota_data(CORR_CRC_1_SECTOR_OTA_DATA);
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
erase_ota_data();
|
||||
break;
|
||||
default:
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> corrupt ota data -> reboot --//--
|
||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, corrupt ota_sec1, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow2, test_flow2, test_flow2);
|
||||
|
||||
static void test_flow3(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
copy_current_app_to_next_part_and_reboot();
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
copy_current_app_to_next_part_and_reboot();
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "OTA1");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
copy_current_app_to_next_part(cur_app, get_next_update_partition());
|
||||
corrupt_ota_data(CORR_CRC_2_SECTOR_OTA_DATA);
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 5:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
erase_ota_data();
|
||||
break;
|
||||
default:
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> copy OTA0 to OTA1 -> reboot --//--
|
||||
// 3 Stage: run OTA1 -> check it -> corrupt ota sector2 -> reboot --//--
|
||||
// 4 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, currupt ota_sec2, OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow3, test_flow3, test_flow3, test_flow3);
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_FACTORY_RESET
|
||||
#define STORAGE_NAMESPACE "update_ota"
|
||||
|
||||
static void test_flow4(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
nvs_handle_t handle = 0;
|
||||
int32_t boot_count_nvs = 0;
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
|
||||
TEST_ESP_OK(nvs_flash_erase());
|
||||
TEST_ESP_OK(nvs_flash_init());
|
||||
TEST_ESP_OK(nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &handle));
|
||||
TEST_ESP_OK(nvs_set_i32(handle, "boot_count", boot_count));
|
||||
TEST_ESP_OK(nvs_commit(handle));
|
||||
nvs_close(handle);
|
||||
nvs_flash_deinit();
|
||||
|
||||
copy_current_app_to_next_part_and_reboot();
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
TEST_ESP_OK(nvs_flash_init());
|
||||
TEST_ESP_OK(nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &handle));
|
||||
TEST_ESP_OK(nvs_get_i32(handle, "boot_count", &boot_count_nvs));
|
||||
TEST_ASSERT_EQUAL(boot_count_nvs + 1, boot_count);
|
||||
nvs_close(handle);
|
||||
nvs_flash_deinit();
|
||||
|
||||
set_output_pin(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET);
|
||||
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 4:
|
||||
reset_output_pin(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET);
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
|
||||
int32_t boot_count_nvs;
|
||||
TEST_ESP_OK(nvs_flash_init());
|
||||
TEST_ESP_OK(nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &handle));
|
||||
TEST_ESP_ERR(ESP_ERR_NVS_NOT_FOUND, nvs_get_i32(handle, "boot_count", &boot_count_nvs));
|
||||
nvs_close(handle);
|
||||
nvs_flash_deinit();
|
||||
|
||||
erase_ota_data();
|
||||
break;
|
||||
default:
|
||||
reset_output_pin(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET);
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> set_pin_factory_reset -> reboot --//--
|
||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, sets pin_factory_reset, factory", "[app_update][timeout=90][ignore][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow4, test_flow4, test_flow4);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_TEST
|
||||
static void test_flow5(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
|
||||
set_output_pin(CONFIG_BOOTLOADER_NUM_PIN_APP_TEST);
|
||||
|
||||
copy_partition(esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEST, NULL), cur_app);
|
||||
esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 3:
|
||||
reset_output_pin(CONFIG_BOOTLOADER_NUM_PIN_APP_TEST);
|
||||
ESP_LOGI(TAG, "Test");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_TEST, cur_app->subtype);
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
erase_ota_data();
|
||||
break;
|
||||
default:
|
||||
reset_output_pin(CONFIG_BOOTLOADER_NUM_PIN_APP_TEST);
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to Test and set pin_test_app -> reboot --//--
|
||||
// 3 Stage: run test -> check it -> reset pin_test_app -> reboot --//--
|
||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, test, factory", "[app_update][timeout=90][ignore][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow5, test_flow5, test_flow5);
|
||||
#endif
|
||||
|
||||
static const esp_partition_t* app_update(void)
|
||||
{
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
const esp_partition_t* update_partition = esp_ota_get_next_update_partition(NULL);
|
||||
TEST_ASSERT_NOT_NULL(update_partition);
|
||||
esp_ota_handle_t update_handle = 0;
|
||||
TEST_ESP_OK(esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle));
|
||||
copy_app_partition(update_handle, cur_app);
|
||||
TEST_ESP_OK(esp_ota_end(update_handle));
|
||||
TEST_ESP_OK(esp_ota_set_boot_partition(update_partition));
|
||||
return update_partition;
|
||||
}
|
||||
|
||||
|
||||
static void test_rollback1(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
esp_ota_img_states_t ota_state = 0x5555AAAA;
|
||||
const esp_partition_t* update_partition = NULL;
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
update_partition = app_update();
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(update_partition, &ota_state));
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_NEW, ota_state);
|
||||
#endif
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_PENDING_VERIFY, ota_state);
|
||||
#endif
|
||||
TEST_ESP_OK(esp_ota_mark_app_valid_cancel_rollback());
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
|
||||
TEST_ESP_OK(esp_ota_mark_app_invalid_rollback_and_reboot());
|
||||
break;
|
||||
default:
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_rollback1_1(void)
|
||||
{
|
||||
boot_count = 5;
|
||||
esp_ota_img_states_t ota_state = 0x5555AAAA;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
|
||||
const esp_partition_t *invalid_partition = esp_ota_get_last_invalid_partition();
|
||||
const esp_partition_t* next_update_partition = esp_ota_get_next_update_partition(NULL);
|
||||
TEST_ASSERT_NOT_NULL(invalid_partition);
|
||||
TEST_ASSERT_NOT_NULL(next_update_partition);
|
||||
TEST_ASSERT_EQUAL_PTR(invalid_partition, next_update_partition);
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(invalid_partition, &ota_state));
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_INVALID, ota_state);
|
||||
|
||||
erase_ota_data();
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to next app slot -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> esp_ota_mark_app_valid_cancel_rollback() -> reboot --//--
|
||||
// 4 Stage: run OTA0 -> check it -> esp_ota_mark_app_invalid_rollback_and_reboot() -> reboot
|
||||
// 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA0, rollback -> factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback1, test_rollback1, test_rollback1, test_rollback1_1);
|
||||
|
||||
static void test_rollback2(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
esp_ota_img_states_t ota_state = 0x5555AAAA;
|
||||
const esp_partition_t* update_partition = NULL;
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
update_partition = app_update();
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(update_partition, &ota_state));
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_NEW, ota_state);
|
||||
#endif
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_PENDING_VERIFY, ota_state);
|
||||
#endif
|
||||
TEST_ESP_OK(esp_ota_mark_app_valid_cancel_rollback());
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
|
||||
update_partition = app_update();
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(update_partition, &ota_state));
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_NEW, ota_state);
|
||||
#endif
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "OTA1");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
TEST_ESP_OK(esp_ota_mark_app_invalid_rollback_and_reboot());
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_PENDING_VERIFY, ota_state);
|
||||
reboot_as_deep_sleep();
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_rollback2_1(void)
|
||||
{
|
||||
boot_count = 5;
|
||||
esp_ota_img_states_t ota_state = 0x5555AAAA;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
|
||||
const esp_partition_t *invalid_partition = esp_ota_get_last_invalid_partition();
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, invalid_partition->subtype);
|
||||
const esp_partition_t* next_update_partition = esp_ota_get_next_update_partition(NULL);
|
||||
TEST_ASSERT_NOT_NULL(invalid_partition);
|
||||
TEST_ASSERT_NOT_NULL(next_update_partition);
|
||||
TEST_ASSERT_EQUAL_PTR(invalid_partition, next_update_partition);
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(invalid_partition, &ota_state));
|
||||
#ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_INVALID, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_ABORTED, ota_state);
|
||||
#endif
|
||||
erase_ota_data();
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to next app slot -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> esp_ota_mark_app_valid_cancel_rollback(), copy to next app slot -> reboot --//--
|
||||
// 4 Stage: run OTA1 -> check it -> PENDING_VERIFY/esp_ota_mark_app_invalid_rollback_and_reboot() -> reboot
|
||||
// 5 Stage: run OTA0(rollback) -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA1, rollback -> OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback2, test_rollback2, test_rollback2, test_rollback2_1);
|
||||
|
||||
static void test_erase_last_app_flow(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
app_update();
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
app_update();
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "OTA1");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
|
||||
TEST_ESP_OK(esp_ota_erase_last_boot_app_partition());
|
||||
TEST_ESP_OK(esp_ota_mark_app_invalid_rollback_and_reboot());
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
default:
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_erase_last_app_rollback(void)
|
||||
{
|
||||
boot_count = 5;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
ESP_LOGI(TAG, "erase_last_app");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
TEST_ESP_ERR(ESP_FAIL, esp_ota_erase_last_boot_app_partition());
|
||||
erase_ota_data();
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> copy factory to OTA1 -> reboot --//--
|
||||
// 4 Stage: run OTA1 -> check it -> erase OTA0 and rollback -> reboot
|
||||
// 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Test erase_last_boot_app_partition. factory, OTA1, OTA0, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_rollback);
|
||||
|
||||
static void test_flow6(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
copy_current_app_to_next_part_with_offset_and_reboot();
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
erase_ota_data();
|
||||
break;
|
||||
default:
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0 using esp_ota_write_with_offset", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow6, test_flow6);
|
||||
@@ -1,41 +0,0 @@
|
||||
if(NOT CONFIG_LWIP_IPV6 AND NOT CMAKE_BUILD_EARLY_EXPANSION)
|
||||
# note: the component is still included in the build so it can become visible again in config
|
||||
# without needing to re-run CMake. However no source or header files are built.
|
||||
message(STATUS "IPV6 support is disabled so the asio component will not be built")
|
||||
idf_component_register()
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(asio_sources "asio/asio/src/asio.cpp")
|
||||
|
||||
if(CONFIG_ASIO_SSL_SUPPORT)
|
||||
if(CONFIG_ASIO_USE_ESP_OPENSSL)
|
||||
list(APPEND asio_sources
|
||||
"asio/asio/src/asio_ssl.cpp"
|
||||
"port/src/esp_asio_openssl_stubs.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_ASIO_USE_ESP_WOLFSSL)
|
||||
list(APPEND asio_sources
|
||||
"asio/asio/src/asio_ssl.cpp")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${asio_sources}
|
||||
INCLUDE_DIRS "asio/asio/include" "port/include"
|
||||
REQUIRES lwip)
|
||||
|
||||
if(CONFIG_ASIO_SSL_SUPPORT)
|
||||
if(CONFIG_ASIO_USE_ESP_WOLFSSL)
|
||||
idf_component_get_property(wolflib esp-wolfssl COMPONENT_LIB)
|
||||
idf_component_get_property(wolfdir esp-wolfssl COMPONENT_DIR)
|
||||
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC ${wolflib})
|
||||
target_include_directories(${COMPONENT_LIB} PUBLIC ${wolfdir}/wolfssl/wolfssl)
|
||||
endif()
|
||||
|
||||
if(CONFIG_ASIO_USE_ESP_OPENSSL)
|
||||
idf_component_get_property(esp_openssl openssl COMPONENT_LIB)
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC ${esp_openssl})
|
||||
endif()
|
||||
endif()
|
||||
@@ -1,27 +0,0 @@
|
||||
menu "ESP-ASIO"
|
||||
visible if LWIP_IPV6
|
||||
|
||||
config ASIO_SSL_SUPPORT
|
||||
bool "Enable SSL/TLS support of ASIO"
|
||||
default n
|
||||
help
|
||||
Enable support for basic SSL/TLS features, available for mbedTLS/OpenSSL
|
||||
as well as wolfSSL TLS library.
|
||||
|
||||
choice ASIO_SSL_LIBRARY_CHOICE
|
||||
prompt "Choose SSL/TLS library for ESP-TLS (See help for more Info)"
|
||||
default ASIO_USE_ESP_OPENSSL
|
||||
depends on ASIO_SSL_SUPPORT
|
||||
help
|
||||
The ASIO support multiple backend TLS libraries. Currently the mbedTLS with a thin ESP-OpenSSL
|
||||
port layer (default choice) and WolfSSL are supported.
|
||||
Different TLS libraries may support different features and have different resource
|
||||
usage. Consult the ESP-TLS documentation in ESP-IDF Programming guide for more details.
|
||||
config ASIO_USE_ESP_OPENSSL
|
||||
bool "esp-openssl"
|
||||
config ASIO_USE_ESP_WOLFSSL
|
||||
depends on TLS_STACK_WOLFSSL
|
||||
bool "wolfSSL (License info in wolfSSL directory README)"
|
||||
endchoice
|
||||
|
||||
endmenu
|
||||
Submodule components/asio/asio deleted from f31694c9f1
@@ -1,13 +0,0 @@
|
||||
ifdef CONFIG_LWIP_IPV6
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := asio/asio/include port/include
|
||||
COMPONENT_PRIV_INCLUDEDIRS := private_include
|
||||
COMPONENT_SRCDIRS := asio/asio/src port/src
|
||||
|
||||
ifeq ($(CONFIG_ASIO_SSL_SUPPORT), )
|
||||
COMPONENT_OBJEXCLUDE := asio/asio/src/asio_ssl.o port/src/esp_asio_openssl_stubs.o
|
||||
endif
|
||||
|
||||
COMPONENT_SUBMODULES += asio
|
||||
|
||||
endif # CONFIG_LWIP_IPV6
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef _ESP_ASIO_CONFIG_H_
|
||||
#define _ESP_ASIO_CONFIG_H_
|
||||
|
||||
//
|
||||
// Enabling exceptions only when they are enabled in menuconfig
|
||||
//
|
||||
# include <sdkconfig.h>
|
||||
# ifndef CONFIG_COMPILER_CXX_EXCEPTIONS
|
||||
# define ASIO_NO_EXCEPTIONS
|
||||
# endif // CONFIG_COMPILER_CXX_EXCEPTIONS
|
||||
|
||||
# ifndef CONFIG_COMPILER_RTTI
|
||||
# define ASIO_NO_TYPEID
|
||||
# endif // CONFIG_COMPILER_RTTI
|
||||
|
||||
//
|
||||
// Supress OpenSSL deprecation warning, when building ASIO
|
||||
//
|
||||
#define ESP_OPENSSL_SUPPRESS_LEGACY_WARNING
|
||||
|
||||
//
|
||||
// LWIP compatibility inet and address macros/functions
|
||||
//
|
||||
# define LWIP_COMPAT_SOCKET_INET 1
|
||||
# define LWIP_COMPAT_SOCKET_ADDR 1
|
||||
|
||||
//
|
||||
// Specific ASIO feature flags
|
||||
//
|
||||
# define ASIO_DISABLE_SERIAL_PORT
|
||||
# define ASIO_SEPARATE_COMPILATION
|
||||
# define ASIO_STANDALONE
|
||||
# define ASIO_HAS_PTHREADS
|
||||
|
||||
# ifdef CONFIG_ASIO_USE_ESP_OPENSSL
|
||||
# define ASIO_USE_ESP_OPENSSL
|
||||
# define OPENSSL_NO_ENGINE
|
||||
# elif CONFIG_ASIO_USE_ESP_WOLFSSL
|
||||
# define ASIO_USE_WOLFSSL
|
||||
# endif // CONFIG_ASIO_USE_ESP_OPENSSL
|
||||
|
||||
#endif // _ESP_ASIO_CONFIG_H_
|
||||
@@ -1,31 +0,0 @@
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef _ESP_EXCEPTION_H_
|
||||
#define _ESP_EXCEPTION_H_
|
||||
|
||||
//
|
||||
// This exception stub is enabled only if exceptions are disabled in menuconfig
|
||||
//
|
||||
#if !defined(CONFIG_COMPILER_CXX_EXCEPTIONS) && defined (ASIO_NO_EXCEPTIONS)
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
//
|
||||
// asio exception stub
|
||||
//
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
template <typename Exception>
|
||||
void throw_exception(const Exception& e)
|
||||
{
|
||||
ESP_LOGE("esp32_asio_exception", "Caught exception: %s!", e.what());
|
||||
abort();
|
||||
}
|
||||
}}
|
||||
#endif // CONFIG_COMPILER_CXX_EXCEPTIONS==1 && defined (ASIO_NO_EXCEPTIONS)
|
||||
|
||||
#endif // _ESP_EXCEPTION_H_
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ESP_ASIO_OPENSSL_CONF_H
|
||||
#define _ESP_ASIO_OPENSSL_CONF_H
|
||||
#include "esp_asio_config.h"
|
||||
#include "openssl/esp_asio_openssl_stubs.h"
|
||||
|
||||
#if defined(ASIO_USE_WOLFSSL)
|
||||
// SSLv3 Methods not present in current wolfSSL library
|
||||
#define OPENSSL_NO_SSL3
|
||||
#include_next "openssl/conf.h"
|
||||
#endif // ASIO_USE_WOLFSSL
|
||||
|
||||
#endif // _ESP_ASIO_OPENSSL_CONF_H
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ESP_ASIO_OPENSSL_DH_STUB_H
|
||||
#define _ESP_ASIO_OPENSSL_DH_STUB_H
|
||||
// Dummy header needed for ASIO compilation with esp-openssl
|
||||
|
||||
#if defined(ASIO_USE_WOLFSSL)
|
||||
#include_next "openssl/dh.h"
|
||||
#endif // ASIO_USE_WOLFSSL
|
||||
|
||||
#endif // _ESP_ASIO_OPENSSL_DH_STUB_H
|
||||
@@ -1,201 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ESP_ASIO_OPENSSL_STUBS_H
|
||||
#define _ESP_ASIO_OPENSSL_STUBS_H
|
||||
|
||||
/**
|
||||
* @note This header contains openssl API which are NOT implemented, and are only provided
|
||||
* as stubs or no-operations to get the ASIO library compiled and working with most
|
||||
* practical use cases as an embedded application on ESP platform
|
||||
*/
|
||||
|
||||
#if defined(ASIO_USE_WOLFSSL)
|
||||
|
||||
#include "wolfssl/ssl.h"
|
||||
// esp-wolfssl disables filesystem by default, but the ssl filesystem functions are needed for the ASIO to compile
|
||||
// - so we could either configure wolfSSL to use filesystem
|
||||
// - or use the default wolfSSL and declare the filesystem functions -- preferred option, as whenever
|
||||
// the filesystem functions are used from app code (potential security impact if private keys in a filesystem)
|
||||
// compilation fails with linking errors.
|
||||
|
||||
#if defined(NO_FILESYSTEM)
|
||||
// WolfSSL methods that are not included in standard esp-wolfssl config, must be defined here
|
||||
// as function stubs, so ASIO compiles, but would get link errors, if these functions were used.
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct WOLFSSL_CTX WOLFSSL_CTX;
|
||||
|
||||
void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx,int depth);
|
||||
int SSL_CTX_load_verify_locations(WOLFSSL_CTX*, const char*, const char*);
|
||||
int SSL_CTX_use_certificate_file(WOLFSSL_CTX*, const char*, int);
|
||||
int SSL_CTX_use_certificate_chain_file(WOLFSSL_CTX*, const char*);
|
||||
int SSL_CTX_use_PrivateKey_file(WOLFSSL_CTX*, const char*, int);
|
||||
int SSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX*, const char*, int);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern C */
|
||||
#endif
|
||||
|
||||
#endif // NO_FILESYSTEM
|
||||
|
||||
#elif defined(ASIO_USE_ESP_OPENSSL)
|
||||
|
||||
#include "internal/ssl_x509.h"
|
||||
#include "internal/ssl_pkey.h"
|
||||
#include "mbedtls/pem.h"
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// The most applicable OpenSSL version wrtt ASIO usage
|
||||
#define OPENSSL_VERSION_NUMBER 0x10100001L
|
||||
// SSLv2 methods not supported
|
||||
// OpenSSL port supports: TLS_ANY, TLS_1, TLS_1_1, TLS_1_2, SSL_3
|
||||
#define OPENSSL_NO_SSL2
|
||||
#define SSL2_VERSION 0x0002
|
||||
|
||||
#define SSL_R_SHORT_READ 219
|
||||
#define SSL_OP_ALL 0
|
||||
#define SSL_OP_SINGLE_DH_USE 0
|
||||
#define SSL_OP_NO_COMPRESSION 0
|
||||
// Translates mbedTLS PEM parse error, used by ASIO
|
||||
#define PEM_R_NO_START_LINE -MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
|
||||
|
||||
#define SSL_OP_NO_SSLv2 0x01000000L
|
||||
#define SSL_OP_NO_SSLv3 0x02000000L
|
||||
#define SSL_OP_NO_TLSv1 0x04000000L
|
||||
|
||||
#define X509_FILETYPE_PEM 1
|
||||
#define X509_FILETYPE_ASN1 2
|
||||
#define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1
|
||||
#define SSL_FILETYPE_PEM X509_FILETYPE_PEM
|
||||
|
||||
#define NID_subject_alt_name 85
|
||||
|
||||
|
||||
#define GEN_DNS 2
|
||||
#define GEN_IPADD 7
|
||||
#define V_ASN1_OCTET_STRING 4
|
||||
#define V_ASN1_IA5STRING 22
|
||||
#define NID_commonName 13
|
||||
|
||||
#define SSL_CTX_get_app_data(ctx) ((void*)SSL_CTX_get_ex_data(ctx, 0))
|
||||
|
||||
/**
|
||||
* @brief Frees DH object -- not implemented
|
||||
*
|
||||
* Current implementation calls SSL_ASSERT
|
||||
*
|
||||
* @param r DH object
|
||||
*/
|
||||
void DH_free(DH *r);
|
||||
|
||||
/**
|
||||
* @brief Frees GENERAL_NAMES -- not implemented
|
||||
*
|
||||
* Current implementation calls SSL_ASSERT
|
||||
*
|
||||
* @param r GENERAL_NAMES object
|
||||
*/
|
||||
void GENERAL_NAMES_free(GENERAL_NAMES * gens);
|
||||
|
||||
/**
|
||||
* @brief Returns subject name from X509 -- not implemented
|
||||
*
|
||||
* Current implementation calls SSL_ASSERT
|
||||
*
|
||||
* @param r X509 object
|
||||
*/
|
||||
X509_NAME *X509_get_subject_name(X509 *a);
|
||||
|
||||
/**
|
||||
* @brief API provaded as declaration only
|
||||
*
|
||||
*/
|
||||
int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
|
||||
|
||||
/**
|
||||
* @brief API provaded as declaration only
|
||||
*
|
||||
*/
|
||||
int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos);
|
||||
|
||||
/**
|
||||
* @brief API provaded as declaration only
|
||||
*
|
||||
*/
|
||||
X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
|
||||
|
||||
/**
|
||||
* @brief API provaded as declaration only
|
||||
*
|
||||
*/
|
||||
ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
|
||||
|
||||
/**
|
||||
* @brief API provaded as declaration only
|
||||
*
|
||||
*/
|
||||
void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
|
||||
|
||||
/**
|
||||
* @brief API provaded as declaration only
|
||||
*
|
||||
*/
|
||||
X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
|
||||
|
||||
/**
|
||||
* @brief Reads DH params from a bio object -- not implemented
|
||||
*
|
||||
* Current implementation calls SSL_ASSERT
|
||||
*/
|
||||
DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u);
|
||||
|
||||
/**
|
||||
* @brief API provaded as declaration only
|
||||
*
|
||||
*/
|
||||
void * X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx);
|
||||
|
||||
/**
|
||||
* @brief Sets DH params to ssl ctx -- not implemented
|
||||
*
|
||||
* Current implementation calls SSL_ASSERT
|
||||
*/
|
||||
int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh);
|
||||
|
||||
/**
|
||||
* @brief API provaded as declaration only
|
||||
*
|
||||
*/
|
||||
void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *data);
|
||||
|
||||
/**
|
||||
* @brief API provaded as declaration only
|
||||
*
|
||||
*/
|
||||
void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
|
||||
|
||||
/**
|
||||
* @brief Clears any existing chain associated with the current certificate of ctx.
|
||||
*
|
||||
*/
|
||||
int SSL_CTX_clear_chain_certs(SSL_CTX *ctx);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern C */
|
||||
#endif
|
||||
|
||||
#endif /* ASIO_USE_ESP_OPENSSL, ASIO_USE_WOLFSSL */
|
||||
#endif /* _ESP_ASIO_OPENSSL_STUBS_H */
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _ESP_ASIO_OPENSSL_RSA_STUB_H
|
||||
#define _ESP_ASIO_OPENSSL_RSA_STUB_H
|
||||
// Dummy header needed for ASIO compilation with esp-openssl
|
||||
|
||||
#if defined(ASIO_USE_WOLFSSL)
|
||||
#include_next "openssl/rsa.h"
|
||||
#endif // ASIO_USE_WOLFSSL
|
||||
|
||||
#endif // _ESP_ASIO_OPENSSL_RSA_STUB_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user