forked from espressif/esp-idf
Compare commits
609 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16d9971302 | ||
|
|
2e73c5ddec | ||
|
|
d3f0969e4f | ||
|
|
e52ef6c326 | ||
|
|
b56a7524e3 | ||
|
|
0e3ec4fb99 | ||
|
|
a0b1d016e4 | ||
|
|
ee3c14519b | ||
|
|
cba053da3d | ||
|
|
b137ae4259 | ||
|
|
2a83da379f | ||
|
|
61e1b81752 | ||
|
|
a8489a7796 | ||
|
|
34c9af3e2d | ||
|
|
94c4c3186d | ||
|
|
35ddb13090 | ||
|
|
fd551af189 | ||
|
|
f60bbf5172 | ||
|
|
30013ca66f | ||
|
|
692265302e | ||
|
|
cd43531831 | ||
|
|
6042412a35 | ||
|
|
908192f504 | ||
|
|
5fe7d538a5 | ||
|
|
3fa2d25983 | ||
|
|
3a532ecb5c | ||
|
|
d06fac5c8b | ||
|
|
58f378602f | ||
|
|
fa6655cbcf | ||
|
|
440c4a28d7 | ||
|
|
91f679bdb3 | ||
|
|
181b75e152 | ||
|
|
c9ff4822c5 | ||
|
|
7df94ffb2e | ||
|
|
3207993eb7 | ||
|
|
71fdd0e146 | ||
|
|
0f2aa2eae4 | ||
|
|
15090af9d1 | ||
|
|
d6f857a2f0 | ||
|
|
92ccc5fa95 | ||
|
|
0d5f7b5521 | ||
|
|
28e50c1180 | ||
|
|
4be976e40d | ||
|
|
adc9261443 | ||
|
|
2e9e5d6e7c | ||
|
|
2ba9cd6c54 | ||
|
|
656ea5c664 | ||
|
|
e0cf810bab | ||
|
|
a9b515d0d1 | ||
|
|
068221cb33 | ||
|
|
b4ef1b80a2 | ||
|
|
94bac458bf | ||
|
|
30b2cad3b7 | ||
|
|
c4f39a5d91 | ||
|
|
588436db47 | ||
|
|
df8ebc9bba | ||
|
|
e48cf0c188 | ||
|
|
3477c342e2 | ||
|
|
ffd68203f6 | ||
|
|
e1d3993309 | ||
|
|
dfd3a9c3bc | ||
|
|
4edc903bb3 | ||
|
|
e688645ff9 | ||
|
|
f8a0279e5d | ||
|
|
81d1226f53 | ||
|
|
846cbf14dc | ||
|
|
a818e9ca91 | ||
|
|
a37e9318ef | ||
|
|
1ad55d707b | ||
|
|
1d72f077c5 | ||
|
|
6d3dc2e616 | ||
|
|
8ef2842074 | ||
|
|
bf4f9b9e41 | ||
|
|
b1f7ad6983 | ||
|
|
fdbb3da1b4 | ||
|
|
9532e1ccc6 | ||
|
|
f8c098658c | ||
|
|
21daee7dce | ||
|
|
436be30045 | ||
|
|
4ef87d2505 | ||
|
|
d04a94320a | ||
|
|
8b1826f86e | ||
|
|
b1b92d46e5 | ||
|
|
20106fc141 | ||
|
|
9b0e8266c8 | ||
|
|
f4e5ba7d9f | ||
|
|
54d9f265dc | ||
|
|
51af60adf0 | ||
|
|
e0f7d6834d | ||
|
|
5628f1f21d | ||
|
|
be564ffd28 | ||
|
|
2d7ae879f1 | ||
|
|
1ffc02dfaf | ||
|
|
0c7d32bcdb | ||
|
|
671303bbd5 | ||
|
|
62cc246d5f | ||
|
|
d6c2bae1bc | ||
|
|
37ec8e835b | ||
|
|
a7935539b5 | ||
|
|
6c27359d13 | ||
|
|
6217fb46db | ||
|
|
99339caedc | ||
|
|
638a1b9bf3 | ||
|
|
df294b7b69 | ||
|
|
6808bbc26c | ||
|
|
5025931e7c | ||
|
|
d1bb7cfb3f | ||
|
|
e414dce1ff | ||
|
|
9c35eeecbd | ||
|
|
86ec13eb21 | ||
|
|
2cc879120b | ||
|
|
2a712fccd4 | ||
|
|
0269d062d0 | ||
|
|
9ab1c4c9e0 | ||
|
|
351a209540 | ||
|
|
a7c99f4eae | ||
|
|
2ddb34c3c0 | ||
|
|
9cb98bf6da | ||
|
|
217d2d0775 | ||
|
|
47424affaf | ||
|
|
3842d27be3 | ||
|
|
68f206959b | ||
|
|
3a69b1d94f | ||
|
|
342f566002 | ||
|
|
983547290b | ||
|
|
9bec068e52 | ||
|
|
edde9c7892 | ||
|
|
912f2ea76c | ||
|
|
d9be879a76 | ||
|
|
75c720bcd3 | ||
|
|
92d6c4a502 | ||
|
|
d7f614d58a | ||
|
|
d75674579e | ||
|
|
4efc516c1a | ||
|
|
2ffd558153 | ||
|
|
52de71c60e | ||
|
|
39b6a3fcbf | ||
|
|
f789336ab9 | ||
|
|
1ef989a1b5 | ||
|
|
06ce378142 | ||
|
|
6a92fb2d76 | ||
|
|
b729bf804d | ||
|
|
eca8b7ca41 | ||
|
|
eeea576409 | ||
|
|
1457686a94 | ||
|
|
0393a5647a | ||
|
|
673d0371ba | ||
|
|
361a604276 | ||
|
|
f4852bc055 | ||
|
|
1d933ad02c | ||
|
|
ab0eac5508 | ||
|
|
8ffddf53bc | ||
|
|
cd598bd7c0 | ||
|
|
70c737af4d | ||
|
|
c6a96e9a57 | ||
|
|
0f1db7fd9c | ||
|
|
300b881428 | ||
|
|
b668c0cc4d | ||
|
|
cbca71a4e7 | ||
|
|
7eaeaaa784 | ||
|
|
b752da1a01 | ||
|
|
2ef0e2d126 | ||
|
|
1dca246310 | ||
|
|
79c9a043f2 | ||
|
|
e583dd0cfa | ||
|
|
330db29120 | ||
|
|
053a59a0b1 | ||
|
|
99adcfbda0 | ||
|
|
4b0c1d6f71 | ||
|
|
2f8b58d88f | ||
|
|
6f86e1bb63 | ||
|
|
491b95925e | ||
|
|
0997c6df99 | ||
|
|
6fd6a8b40b | ||
|
|
47ccdef8c1 | ||
|
|
3d0076a31f | ||
|
|
6e13fc803a | ||
|
|
16c14a196b | ||
|
|
004d8e9450 | ||
|
|
a20b6c4d95 | ||
|
|
e00a689a77 | ||
|
|
828f9920c3 | ||
|
|
d30480c113 | ||
|
|
9b3ce4b15f | ||
|
|
112bfbe465 | ||
|
|
02fe2fa96f | ||
|
|
65cfc9e656 | ||
|
|
5f27ec9157 | ||
|
|
79cdc465fd | ||
|
|
2d7f61758b | ||
|
|
9e15d184d1 | ||
|
|
f11e17f886 | ||
|
|
22e630b145 | ||
|
|
106fcdcc1c | ||
|
|
9338d1d121 | ||
|
|
7cb6468fff | ||
|
|
c399f5d1e7 | ||
|
|
0b8d52a926 | ||
|
|
df29179a56 | ||
|
|
46c5ad2292 | ||
|
|
a7b249b182 | ||
|
|
fe5a5284ba | ||
|
|
8f1f424390 | ||
|
|
3c8bab0285 | ||
|
|
6b9381f754 | ||
|
|
55da7a2f2e | ||
|
|
8cf5786444 | ||
|
|
d975bb0086 | ||
|
|
e4e76aedc4 | ||
|
|
a469559e1a | ||
|
|
028f1d9345 | ||
|
|
0aa2b4eaec | ||
|
|
0f2003cd79 | ||
|
|
769335dae3 | ||
|
|
6fe0f873c2 | ||
|
|
3f728f68c7 | ||
|
|
ae84265128 | ||
|
|
1955dcda69 | ||
|
|
81ac6fb7f0 | ||
|
|
e98d72ee76 | ||
|
|
29f5f119b2 | ||
|
|
bfbe5dcbbe | ||
|
|
cf3413384a | ||
|
|
4bc28054ee | ||
|
|
b31f974b99 | ||
|
|
b30ff28034 | ||
|
|
f02c6037d4 | ||
|
|
ad94b8b9dc | ||
|
|
7a14739e71 | ||
|
|
1bcb419fd2 | ||
|
|
5f3f615ff1 | ||
|
|
24fa86f270 | ||
|
|
047adc5ebc | ||
|
|
ad71c0031c | ||
|
|
b8bd3ada55 | ||
|
|
3f49170ab1 | ||
|
|
f5f7a77895 | ||
|
|
f817722109 | ||
|
|
077c5fb0b8 | ||
|
|
040ae4ac72 | ||
|
|
731cb09ab4 | ||
|
|
c735cbde58 | ||
|
|
002a16c367 | ||
|
|
496f2a5741 | ||
|
|
74b912f494 | ||
|
|
ace832abf5 | ||
|
|
fb8ce7d010 | ||
|
|
adebd5c5c3 | ||
|
|
6f99b8da73 | ||
|
|
115663df95 | ||
|
|
1674c63f82 | ||
|
|
dd59c5d5c5 | ||
|
|
74845d89cb | ||
|
|
4ddd1f9d11 | ||
|
|
dd9aa85ca9 | ||
|
|
615e67bd6b | ||
|
|
c166160f64 | ||
|
|
91ed14b50f | ||
|
|
4670bcf40e | ||
|
|
63f6fe34ac | ||
|
|
74fc0578f5 | ||
|
|
724032022c | ||
|
|
d3df24d950 | ||
|
|
fc36f08d3f | ||
|
|
5c78283f6e | ||
|
|
073da59d27 | ||
|
|
d501fd4b96 | ||
|
|
ef356e464d | ||
|
|
8ff2ce6852 | ||
|
|
f8e45766b5 | ||
|
|
501d67fdc5 | ||
|
|
30a17ea53d | ||
|
|
9e9fb39a07 | ||
|
|
b1f93150f9 | ||
|
|
40c0c33ae0 | ||
|
|
726ceb4fed | ||
|
|
9a09f24572 | ||
|
|
ab375388ef | ||
|
|
47bd9d4171 | ||
|
|
69b9ad27c3 | ||
|
|
432e9b6293 | ||
|
|
c831d1f1e0 | ||
|
|
f75ed7c7cc | ||
|
|
df7cfa025c | ||
|
|
e48f87468e | ||
|
|
acc55cae88 | ||
|
|
8fa37107be | ||
|
|
ad2238d7fb | ||
|
|
87c2352a1e | ||
|
|
e4743e7d79 | ||
|
|
2d65703547 | ||
|
|
be19818db7 | ||
|
|
bcb8d87108 | ||
|
|
22e741a281 | ||
|
|
b075101316 | ||
|
|
5e4ec25ace | ||
|
|
a8736a9b66 | ||
|
|
ad6095ad80 | ||
|
|
7fecad1473 | ||
|
|
230861e80f | ||
|
|
7b70f6e135 | ||
|
|
ad3b9a8002 | ||
|
|
25b1c57121 | ||
|
|
7d65b17898 | ||
|
|
03f9eedc27 | ||
|
|
8d5316ceb8 | ||
|
|
9ff972046b | ||
|
|
d3f5fd6eb6 | ||
|
|
b1d6217f5c | ||
|
|
81948262c8 | ||
|
|
06d7fd95d4 | ||
|
|
1f980ae982 | ||
|
|
8504a878f3 | ||
|
|
d04dacdaa1 | ||
|
|
7df150b3de | ||
|
|
f527010044 | ||
|
|
d359f88054 | ||
|
|
917510ea96 | ||
|
|
611c5a2496 | ||
|
|
69e784d07e | ||
|
|
b1017de2e6 | ||
|
|
dcfd5187ac | ||
|
|
7f51eb7e7c | ||
|
|
b979547b06 | ||
|
|
94e58eac30 | ||
|
|
9c4b96d63b | ||
|
|
4a14745b28 | ||
|
|
119ae77993 | ||
|
|
ab099369c8 | ||
|
|
3a628eb470 | ||
|
|
81e3035f4d | ||
|
|
c7fd71a893 | ||
|
|
d64553797c | ||
|
|
5c72bbcb3d | ||
|
|
7bb51e9a67 | ||
|
|
5bcb77fdca | ||
|
|
b19424d67e | ||
|
|
93a3a47440 | ||
|
|
422892d7b4 | ||
|
|
489fcf1b6c | ||
|
|
d8c3b4d646 | ||
|
|
b3c51e74c8 | ||
|
|
8a4bcdb563 | ||
|
|
187c5b893d | ||
|
|
17f9c7aaef | ||
|
|
fea5bdce86 | ||
|
|
1a3f5accda | ||
|
|
bdd329ff02 | ||
|
|
df9f101792 | ||
|
|
6957b4815a | ||
|
|
46388a0741 | ||
|
|
92c0c09514 | ||
|
|
29b6d229c1 | ||
|
|
021627754c | ||
|
|
aa89d67923 | ||
|
|
e0fc13b23d | ||
|
|
8536cf46a5 | ||
|
|
9928f44894 | ||
|
|
c6278acdf2 | ||
|
|
d29ab82bc9 | ||
|
|
ab8b292407 | ||
|
|
5b36459611 | ||
|
|
dfaf73c197 | ||
|
|
dd7826d456 | ||
|
|
8fee811d55 | ||
|
|
f178727aae | ||
|
|
5fc51252e9 | ||
|
|
22cd519375 | ||
|
|
72e4b5ac5b | ||
|
|
6357a37846 | ||
|
|
65cb65df1a | ||
|
|
78f4405c7c | ||
|
|
87514f4a2b | ||
|
|
84149f0974 | ||
|
|
a5a4718600 | ||
|
|
f1adc8efbe | ||
|
|
aa044f4a63 | ||
|
|
51e196ac93 | ||
|
|
87f8a0d5f1 | ||
|
|
df3e1405d5 | ||
|
|
8374e3b0ee | ||
|
|
5ebbe6aea7 | ||
|
|
2216d4d8f7 | ||
|
|
436eb37a8b | ||
|
|
3829ee1889 | ||
|
|
117b23a82a | ||
|
|
df62fbb6d0 | ||
|
|
a985402da1 | ||
|
|
5bad27d0d5 | ||
|
|
58bd27b713 | ||
|
|
a0f69c3499 | ||
|
|
8368bf3760 | ||
|
|
c56cf9d6fd | ||
|
|
49bd3f0795 | ||
|
|
e8196c0ff2 | ||
|
|
ab6b4a13db | ||
|
|
947e7909b9 | ||
|
|
f77e018256 | ||
|
|
53f20589a4 | ||
|
|
0b7ed763e4 | ||
|
|
045b38857d | ||
|
|
b9a96186fd | ||
|
|
9aa263c103 | ||
|
|
3afc31c0de | ||
|
|
b865a84661 | ||
|
|
4dc1801c7a | ||
|
|
677d6a8625 | ||
|
|
54b50ab4ac | ||
|
|
fbfef19982 | ||
|
|
cc2c92a7ab | ||
|
|
39f39ac53d | ||
|
|
cc3aeeb279 | ||
|
|
f9cf648afd | ||
|
|
fffc5ac658 | ||
|
|
c761f44d94 | ||
|
|
2cf554df6e | ||
|
|
0786d1a337 | ||
|
|
8a5c51d05b | ||
|
|
3bad4e3ca4 | ||
|
|
71f63df9d5 | ||
|
|
260bf53b52 | ||
|
|
fbc8ad0417 | ||
|
|
8a5f624801 | ||
|
|
9760352810 | ||
|
|
4bdcb9f5a9 | ||
|
|
be89be5a3f | ||
|
|
c6c7068776 | ||
|
|
7f1ab6d8d1 | ||
|
|
5548b3b71c | ||
|
|
f68da60831 | ||
|
|
f295efce12 | ||
|
|
33190700aa | ||
|
|
00c0c1fd45 | ||
|
|
b0060dc0a3 | ||
|
|
06f2f1c6b2 | ||
|
|
62c10b2a05 | ||
|
|
308b3e31a3 | ||
|
|
6dce875bf9 | ||
|
|
f7bb64e896 | ||
|
|
9138b9aff5 | ||
|
|
aabac43480 | ||
|
|
ade22c9072 | ||
|
|
d300a9cfe3 | ||
|
|
e383693ac2 | ||
|
|
3764b03734 | ||
|
|
b9c5ef1717 | ||
|
|
d6b5b0ab00 | ||
|
|
6e9d90d6e1 | ||
|
|
2a28ec3522 | ||
|
|
b957692888 | ||
|
|
c2f14e192e | ||
|
|
a28f9a6770 | ||
|
|
606d7e48d2 | ||
|
|
0bc2cb89e5 | ||
|
|
6993fbdbe8 | ||
|
|
74f4d07c3b | ||
|
|
5965ad859d | ||
|
|
f8d60e2008 | ||
|
|
d34f2e407b | ||
|
|
1dfe3570b4 | ||
|
|
9eba0ff6a6 | ||
|
|
3eceea7f5d | ||
|
|
2d1e1c50e8 | ||
|
|
78e8702963 | ||
|
|
aef7850157 | ||
|
|
04d2887493 | ||
|
|
9b2f6a2a77 | ||
|
|
04bea91b38 | ||
|
|
2b186e04d0 | ||
|
|
abacbb1d12 | ||
|
|
0818a8b4f1 | ||
|
|
f61b57e5e5 | ||
|
|
837d4637f5 | ||
|
|
154f54253c | ||
|
|
aaeecdf0e7 | ||
|
|
ab2148a390 | ||
|
|
ecfa3c96ba | ||
|
|
918d8fabcf | ||
|
|
d5a20a5a4f | ||
|
|
b0133c72a0 | ||
|
|
cc5e2107bb | ||
|
|
7467c68a17 | ||
|
|
143fb842a5 | ||
|
|
1738b905a7 | ||
|
|
df5f73e165 | ||
|
|
6dde759a99 | ||
|
|
7c0d99e68d | ||
|
|
8a7b2f326b | ||
|
|
6585626b62 | ||
|
|
e9cbf56d36 | ||
|
|
c33b260e7a | ||
|
|
19ddefeb5c | ||
|
|
65edf90e93 | ||
|
|
da6c5be6c1 | ||
|
|
f8ee842e8c | ||
|
|
e3b39381fd | ||
|
|
5e805d58a8 | ||
|
|
57efd94fea | ||
|
|
9abfa2c645 | ||
|
|
d581312451 | ||
|
|
7a4ed65769 | ||
|
|
31d1156c6d | ||
|
|
25c047d2fa | ||
|
|
0fed811a46 | ||
|
|
bd5176f108 | ||
|
|
39ab27d0cf | ||
|
|
2787237d38 | ||
|
|
7c9ef7466f | ||
|
|
97f8f1b0d6 | ||
|
|
eef3c878aa | ||
|
|
ad2652c1f4 | ||
|
|
f00a1bf164 | ||
|
|
e0777cbbd4 | ||
|
|
71f7d9a8f4 | ||
|
|
57d90c5cd6 | ||
|
|
641e86c1dc | ||
|
|
9d0fca67a9 | ||
|
|
0fd5c562bf | ||
|
|
9d79b70acf | ||
|
|
32e29580de | ||
|
|
3f63a4caee | ||
|
|
450b05a64a | ||
|
|
9844845214 | ||
|
|
778faeb7dd | ||
|
|
e9f47296a8 | ||
|
|
7dbfd01520 | ||
|
|
6c38e7c5de | ||
|
|
201ae7e0e7 | ||
|
|
4ab1fb9b2a | ||
|
|
683a98fbe3 | ||
|
|
0193aeffd6 | ||
|
|
9dac6b0643 | ||
|
|
9a0a697b27 | ||
|
|
3eb854c3ea | ||
|
|
e7db515b35 | ||
|
|
4d2674a7f4 | ||
|
|
37591f6a85 | ||
|
|
b62308c363 | ||
|
|
04f69192d2 | ||
|
|
91d7557579 | ||
|
|
564229c9a6 | ||
|
|
e26a2250a5 | ||
|
|
8e7b11f6d1 | ||
|
|
3d91e6d993 | ||
|
|
f976bb0ef8 | ||
|
|
bd598e36ea | ||
|
|
824552e9b4 | ||
|
|
3c0d892d43 | ||
|
|
6217ebd865 | ||
|
|
5ec8dcf937 | ||
|
|
c72c3fdb3c | ||
|
|
92331a8c62 | ||
|
|
bb9a13e328 | ||
|
|
b34c461d35 | ||
|
|
971d9b9436 | ||
|
|
6a2f9b21ec | ||
|
|
3a55b28ba9 | ||
|
|
c9940a3eed | ||
|
|
b812712757 | ||
|
|
a269df84e9 | ||
|
|
a7900f871f | ||
|
|
d4cc192782 | ||
|
|
8409e3bcbe | ||
|
|
d3b88a13e1 | ||
|
|
255da2605b | ||
|
|
1c18f28a4a | ||
|
|
44af11f38c | ||
|
|
4b73610eea | ||
|
|
2305b5f474 | ||
|
|
70936f4c92 | ||
|
|
9fb61791fe | ||
|
|
7a8c8f8576 | ||
|
|
1cae1fc18e | ||
|
|
0befb28237 | ||
|
|
f864e1ddbb | ||
|
|
6ebd748c75 | ||
|
|
4f19ef06fb | ||
|
|
4fe9b8c40f | ||
|
|
c38215cb2c | ||
|
|
f34a85dc31 | ||
|
|
a93e3dff25 | ||
|
|
f2d6cb7298 | ||
|
|
2ccf84cedf | ||
|
|
0855521014 | ||
|
|
9204605d98 | ||
|
|
fcd5e502a7 | ||
|
|
25c61606a1 | ||
|
|
a8260c9c77 | ||
|
|
ff42b70176 | ||
|
|
6f9e611725 | ||
|
|
cd0a66e0d9 | ||
|
|
c86c83ca4d | ||
|
|
6ed81a632c | ||
|
|
c00c3f74ae | ||
|
|
a8fd3ef48e | ||
|
|
12509dd0c1 | ||
|
|
8999626545 | ||
|
|
22fad5110c | ||
|
|
08aacb02f7 | ||
|
|
b1d346f682 | ||
|
|
6a57c4d5d5 | ||
|
|
710c1f2fad | ||
|
|
b01c197505 | ||
|
|
de5e0fa3bd | ||
|
|
d4f2e03e4a | ||
|
|
be520f975a | ||
|
|
2250da111e | ||
|
|
5f2fabb2b1 | ||
|
|
e335a16356 |
75
.github/workflows/docker.yml
vendored
Normal file
75
.github/workflows/docker.yml
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
name: docker
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'release/*'
|
||||
tags:
|
||||
- 'v*.*'
|
||||
|
||||
env:
|
||||
# Platforms to build the image for
|
||||
BUILD_PLATFORMS: linux/amd64,linux/arm64
|
||||
DOCKERHUB_REPO: ${{ github.repository_owner }}/idf
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
# Disable the job in forks
|
||||
if: ${{ github.repository_owner == 'espressif' }}
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Depending on the branch/tag, set CLONE_BRANCH_OR_TAG variable (used in the Dockerfile
|
||||
# as a build arg) and TAG_NAME (used when tagging the image).
|
||||
#
|
||||
# The following 3 steps cover the alternatives (tag, release branch, master branch):
|
||||
- name: Set variables (tags)
|
||||
if: ${{ github.ref_type == 'tag' }}
|
||||
run: |
|
||||
echo "CLONE_BRANCH_OR_TAG=$GITHUB_REF_NAME" >> $GITHUB_ENV
|
||||
echo "TAG_NAME=$GITHUB_REF_NAME" >> $GITHUB_ENV
|
||||
- name: Set variables (release branches)
|
||||
if: ${{ github.ref_type == 'branch' && startsWith(github.ref_name, 'release/') }}
|
||||
run: |
|
||||
echo "CLONE_BRANCH_OR_TAG=$GITHUB_REF_NAME" >> $GITHUB_ENV
|
||||
echo "TAG_NAME=release-${GITHUB_REF_NAME##release/}" >> $GITHUB_ENV
|
||||
- name: Set variables (main branch)
|
||||
if: ${{ github.ref_type == 'branch' && github.ref_name == 'master' }}
|
||||
run: |
|
||||
echo "CLONE_BRANCH_OR_TAG=master" >> $GITHUB_ENV
|
||||
echo "TAG_NAME=latest" >> $GITHUB_ENV
|
||||
|
||||
# Display the variables set above, just in case.
|
||||
- name: Check variables
|
||||
run: |
|
||||
echo "CLONE_BRANCH_OR_TAG: $CLONE_BRANCH_OR_TAG"
|
||||
echo "CHECKOUT_REF: $CHECKOUT_REF"
|
||||
echo "TAG_NAME: $TAG_NAME"
|
||||
|
||||
# The following steps are the standard boilerplate from
|
||||
# https://github.com/marketplace/actions/build-and-push-docker-images
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Set up QEMU for multiarch builds
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: tools/docker
|
||||
push: true
|
||||
tags: ${{ env.DOCKERHUB_REPO }}:${{ env.TAG_NAME }}
|
||||
platforms: ${{ env.BUILD_PLATFORMS }}
|
||||
build-args: |
|
||||
IDF_CLONE_URL=${{ github.server_url }}/${{ github.repository }}.git
|
||||
IDF_CLONE_BRANCH_OR_TAG=${{ env.CLONE_BRANCH_OR_TAG }}
|
||||
@@ -60,7 +60,7 @@ variables:
|
||||
# target test repo parameters
|
||||
TEST_ENV_CONFIG_REPO: "https://gitlab-ci-token:${BOT_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/qa/ci-test-runner-configs.git"
|
||||
CI_AUTO_TEST_SCRIPT_REPO_URL: "https://gitlab-ci-token:${BOT_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/qa/auto_test_script.git"
|
||||
CI_AUTO_TEST_SCRIPT_REPO_BRANCH: "ci/v3.1"
|
||||
CI_AUTO_TEST_SCRIPT_REPO_BRANCH: "ci/v4.1"
|
||||
|
||||
# Versioned esp-idf-doc env image to use for all document building jobs
|
||||
ESP_IDF_DOC_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-idf-doc-env:v10"
|
||||
@@ -70,7 +70,7 @@ variables:
|
||||
export IDF_MIRROR_PREFIX_MAP=
|
||||
fi
|
||||
if [[ "$SETUP_TOOLS" == "1" || "$CI_JOB_STAGE" != "target_test" ]]; then
|
||||
tools/idf_tools.py --non-interactive install && eval "$(tools/idf_tools.py --non-interactive export)" || exit 1
|
||||
tools/idf_tools.py --non-interactive install ${SETUP_TOOLS_LIST:-} && eval "$(tools/idf_tools.py --non-interactive export)" || exit 1
|
||||
fi
|
||||
|
||||
before_script:
|
||||
|
||||
@@ -6,7 +6,23 @@ set(srcs
|
||||
|
||||
set(include_dirs "include")
|
||||
|
||||
if(CONFIG_SYSVIEW_ENABLE)
|
||||
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
|
||||
sys_view/Config
|
||||
sys_view/SEGGER
|
||||
@@ -16,7 +32,7 @@ if(CONFIG_SYSVIEW_ENABLE)
|
||||
"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"
|
||||
"sys_view/esp/SEGGER_RTT_esp.c"
|
||||
"sys_view/ext/heap_trace_module.c"
|
||||
"sys_view/ext/logging.c")
|
||||
endif()
|
||||
@@ -30,7 +46,8 @@ endif()
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS "${include_dirs}"
|
||||
PRIV_REQUIRES soc esp_ipc
|
||||
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
|
||||
PRIV_REQUIRES soc
|
||||
LDFRAGMENTS linker.lf)
|
||||
|
||||
|
||||
|
||||
@@ -4,29 +4,44 @@ menu "Application Level Tracing"
|
||||
prompt "Data Destination"
|
||||
default APPTRACE_DEST_NONE
|
||||
help
|
||||
Select destination for application trace: trace memory or none (to disable).
|
||||
Select destination for application trace: JTAG or none (to disable).
|
||||
|
||||
config APPTRACE_DEST_TRAX
|
||||
bool "Trace memory"
|
||||
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 APPTRACE_DEST_NONE
|
||||
bool "None"
|
||||
endchoice
|
||||
|
||||
config APPTRACE_ENABLE
|
||||
config APPTRACE_DEST_TRAX
|
||||
bool
|
||||
depends on !ESP32_TRAX && !ESP32S2_TRAX
|
||||
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 APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE
|
||||
bool
|
||||
default n
|
||||
help
|
||||
Enables/disable swapping memory buffers tracing protocol.
|
||||
|
||||
config APPTRACE_ENABLE
|
||||
bool
|
||||
default n
|
||||
help
|
||||
Enables/disable application tracing module.
|
||||
|
||||
config APPTRACE_LOCK_ENABLE
|
||||
bool
|
||||
default !SYSVIEW_ENABLE
|
||||
default !APPTRACE_SV_ENABLE
|
||||
help
|
||||
Enables/disable application tracing module internal sync lock.
|
||||
|
||||
@@ -41,16 +56,23 @@ menu "Application Level Tracing"
|
||||
|
||||
config APPTRACE_POSTMORTEM_FLUSH_THRESH
|
||||
int "Threshold for flushing last trace data to host on panic"
|
||||
depends on APPTRACE_DEST_TRAX
|
||||
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.
|
||||
|
||||
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 APPTRACE_PENDING_DATA_SIZE_MAX
|
||||
int "Size of the pending data buffer"
|
||||
depends on APPTRACE_DEST_TRAX
|
||||
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
|
||||
@@ -59,151 +81,151 @@ menu "Application Level Tracing"
|
||||
|
||||
menu "FreeRTOS SystemView Tracing"
|
||||
depends on APPTRACE_ENABLE
|
||||
config SYSVIEW_ENABLE
|
||||
config APPTRACE_SV_ENABLE
|
||||
bool "SystemView Tracing Enable"
|
||||
depends on APPTRACE_ENABLE
|
||||
default n
|
||||
help
|
||||
Enables supporrt for SEGGER SystemView tracing functionality.
|
||||
|
||||
choice SYSVIEW_TS_SOURCE
|
||||
choice APPTRACE_SV_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
|
||||
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_CCOUNT
|
||||
config APPTRACE_SV_TS_SOURCE_CCOUNT
|
||||
bool "CPU cycle counter (CCOUNT)"
|
||||
depends on FREERTOS_UNICORE && !PM_ENABLE
|
||||
depends on FREERTOS_UNICORE && !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
|
||||
config SYSVIEW_TS_SOURCE_TIMER_00
|
||||
config APPTRACE_SV_TS_SOURCE_TIMER_00
|
||||
bool "Timer 0, Group 0"
|
||||
depends on !PM_ENABLE
|
||||
depends on !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
|
||||
config SYSVIEW_TS_SOURCE_TIMER_01
|
||||
config APPTRACE_SV_TS_SOURCE_TIMER_01
|
||||
bool "Timer 1, Group 0"
|
||||
depends on !PM_ENABLE
|
||||
depends on !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
|
||||
config SYSVIEW_TS_SOURCE_TIMER_10
|
||||
config APPTRACE_SV_TS_SOURCE_TIMER_10
|
||||
bool "Timer 0, Group 1"
|
||||
depends on !PM_ENABLE
|
||||
depends on !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
|
||||
config SYSVIEW_TS_SOURCE_TIMER_11
|
||||
config APPTRACE_SV_TS_SOURCE_TIMER_11
|
||||
bool "Timer 1, Group 1"
|
||||
depends on !PM_ENABLE
|
||||
depends on !PM_ENABLE && !IDF_TARGET_ESP32C3
|
||||
|
||||
config SYSVIEW_TS_SOURCE_ESP_TIMER
|
||||
config APPTRACE_SV_TS_SOURCE_ESP_TIMER
|
||||
bool "esp_timer high resolution timer"
|
||||
|
||||
endchoice
|
||||
|
||||
config SYSVIEW_MAX_TASKS
|
||||
config APPTRACE_SV_MAX_TASKS
|
||||
int "Maximum supported tasks"
|
||||
depends on SYSVIEW_ENABLE
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
range 1 64
|
||||
default 16
|
||||
help
|
||||
Configures maximum supported tasks in sysview debug
|
||||
|
||||
config SYSVIEW_BUF_WAIT_TMO
|
||||
config APPTRACE_SV_BUF_WAIT_TMO
|
||||
int "Trace buffer wait timeout"
|
||||
depends on SYSVIEW_ENABLE
|
||||
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_OVERFLOW_ENABLE
|
||||
config APPTRACE_SV_EVT_OVERFLOW_ENABLE
|
||||
bool "Trace Buffer Overflow Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Trace Buffer Overflow" event.
|
||||
|
||||
config SYSVIEW_EVT_ISR_ENTER_ENABLE
|
||||
config APPTRACE_SV_EVT_ISR_ENTER_ENABLE
|
||||
bool "ISR Enter Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR Enter" event.
|
||||
|
||||
config SYSVIEW_EVT_ISR_EXIT_ENABLE
|
||||
config APPTRACE_SV_EVT_ISR_EXIT_ENABLE
|
||||
bool "ISR Exit Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR Exit" event.
|
||||
|
||||
config SYSVIEW_EVT_ISR_TO_SCHEDULER_ENABLE
|
||||
config APPTRACE_SV_EVT_ISR_TO_SCHED_ENABLE
|
||||
bool "ISR Exit to Scheduler Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR to Scheduler" event.
|
||||
|
||||
config SYSVIEW_EVT_TASK_START_EXEC_ENABLE
|
||||
config APPTRACE_SV_EVT_TASK_START_EXEC_ENABLE
|
||||
bool "Task Start Execution Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Start Execution" event.
|
||||
|
||||
config SYSVIEW_EVT_TASK_STOP_EXEC_ENABLE
|
||||
config APPTRACE_SV_EVT_TASK_STOP_EXEC_ENABLE
|
||||
bool "Task Stop Execution Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Stop Execution" event.
|
||||
|
||||
config SYSVIEW_EVT_TASK_START_READY_ENABLE
|
||||
config APPTRACE_SV_EVT_TASK_START_READY_ENABLE
|
||||
bool "Task Start Ready State Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Start Ready State" event.
|
||||
|
||||
config SYSVIEW_EVT_TASK_STOP_READY_ENABLE
|
||||
config APPTRACE_SV_EVT_TASK_STOP_READY_ENABLE
|
||||
bool "Task Stop Ready State Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Stop Ready State" event.
|
||||
|
||||
config SYSVIEW_EVT_TASK_CREATE_ENABLE
|
||||
config APPTRACE_SV_EVT_TASK_CREATE_ENABLE
|
||||
bool "Task Create Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Create" event.
|
||||
|
||||
config SYSVIEW_EVT_TASK_TERMINATE_ENABLE
|
||||
config APPTRACE_SV_EVT_TASK_TERMINATE_ENABLE
|
||||
bool "Task Terminate Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Terminate" event.
|
||||
|
||||
config SYSVIEW_EVT_IDLE_ENABLE
|
||||
config APPTRACE_SV_EVT_IDLE_ENABLE
|
||||
bool "System Idle Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "System Idle" event.
|
||||
|
||||
config SYSVIEW_EVT_TIMER_ENTER_ENABLE
|
||||
config APPTRACE_SV_EVT_TIMER_ENTER_ENABLE
|
||||
bool "Timer Enter Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Timer Enter" event.
|
||||
|
||||
config SYSVIEW_EVT_TIMER_EXIT_ENABLE
|
||||
config APPTRACE_SV_EVT_TIMER_EXIT_ENABLE
|
||||
bool "Timer Exit Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
depends on APPTRACE_SV_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Timer Exit" event.
|
||||
@@ -212,7 +234,7 @@ menu "Application Level Tracing"
|
||||
|
||||
config APPTRACE_GCOV_ENABLE
|
||||
bool "GCOV to Host Enable"
|
||||
depends on APPTRACE_ENABLE && !SYSVIEW_ENABLE
|
||||
depends on APPTRACE_ENABLE && !APPTRACE_SV_ENABLE
|
||||
select ESP_DEBUG_STUBS_ENABLE
|
||||
default n
|
||||
help
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
364
components/app_trace/app_trace_membufs_proto.c
Normal file
364
components/app_trace/app_trace_membufs_proto.c
Normal file
@@ -0,0 +1,364 @@
|
||||
#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;
|
||||
}
|
||||
@@ -16,33 +16,42 @@
|
||||
#include "freertos/task.h"
|
||||
#include "esp_app_trace_util.h"
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/clk.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
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////// 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)
|
||||
{
|
||||
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->tmo != (int64_t)-1) {
|
||||
tmo->elapsed = esp_timer_get_time() - tmo->start;
|
||||
if (tmo->elapsed >= tmo->tmo) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
@@ -4,11 +4,19 @@
|
||||
|
||||
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
|
||||
|
||||
ifdef CONFIG_SYSVIEW_ENABLE
|
||||
ifdef CONFIG_APPTRACE_SV_ENABLE
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS += \
|
||||
sys_view/Config \
|
||||
sys_view/SEGGER \
|
||||
@@ -19,7 +27,7 @@ COMPONENT_SRCDIRS += \
|
||||
sys_view/SEGGER \
|
||||
sys_view/Sample/OS \
|
||||
sys_view/Sample/Config \
|
||||
sys_view/esp32 \
|
||||
sys_view/esp \
|
||||
sys_view/ext
|
||||
else
|
||||
ifdef CONFIG_APPTRACE_GCOV_ENABLE
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "esp_heap_trace.h"
|
||||
#undef HEAP_TRACE_SRCFILE
|
||||
|
||||
#if CONFIG_SYSVIEW_ENABLE
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_sysview_trace.h"
|
||||
#endif
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#ifdef CONFIG_HEAP_TRACING_TOHOST
|
||||
|
||||
#if !CONFIG_SYSVIEW_ENABLE
|
||||
#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
|
||||
|
||||
@@ -42,7 +42,7 @@ esp_err_t heap_trace_init_tohost(void)
|
||||
|
||||
esp_err_t heap_trace_start(heap_trace_mode_t mode_param)
|
||||
{
|
||||
#if CONFIG_SYSVIEW_ENABLE
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
esp_err_t ret = esp_sysview_heap_trace_start((uint32_t)-1);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
@@ -55,7 +55,7 @@ esp_err_t heap_trace_start(heap_trace_mode_t mode_param)
|
||||
esp_err_t heap_trace_stop(void)
|
||||
{
|
||||
esp_err_t ret = ESP_ERR_NOT_SUPPORTED;
|
||||
#if CONFIG_SYSVIEW_ENABLE
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
ret = esp_sysview_heap_trace_stop();
|
||||
#endif
|
||||
s_tracing = false;
|
||||
@@ -88,7 +88,7 @@ static IRAM_ATTR void record_allocation(const heap_trace_record_t *record)
|
||||
if (!s_tracing) {
|
||||
return;
|
||||
}
|
||||
#if CONFIG_SYSVIEW_ENABLE
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
esp_sysview_heap_trace_alloc(record->address, record->size, record->alloced_by);
|
||||
#endif
|
||||
}
|
||||
@@ -103,7 +103,7 @@ static IRAM_ATTR void record_free(void *p, void **callers)
|
||||
if (!s_tracing) {
|
||||
return;
|
||||
}
|
||||
#if CONFIG_SYSVIEW_ENABLE
|
||||
#if CONFIG_APPTRACE_SV_ENABLE
|
||||
esp_sysview_heap_trace_free(p, callers);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -26,8 +26,11 @@ extern "C" {
|
||||
* Application trace data destinations bits.
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_APPTRACE_DEST_TRAX = 0x1, ///< JTAG destination
|
||||
ESP_APPTRACE_DEST_UART0 = 0x2, ///< UART destination
|
||||
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_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,7 @@ extern "C" {
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_timer.h"
|
||||
|
||||
/** Infinite waiting timeout */
|
||||
#define ESP_APPTRACE_TMO_INFINITE ((uint32_t)-1)
|
||||
@@ -30,9 +31,9 @@ extern "C" {
|
||||
* periodically to check timeout for expiration.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t start; ///< time interval start (in CPU ticks)
|
||||
uint32_t tmo; ///< timeout value (in us)
|
||||
uint32_t elapsed; ///< elapsed time (in us)
|
||||
int64_t start; ///< time interval start (in us)
|
||||
int64_t tmo; ///< timeout value (in us)
|
||||
int64_t elapsed; ///< elapsed time (in us)
|
||||
} esp_apptrace_tmo_t;
|
||||
|
||||
/**
|
||||
@@ -43,23 +44,23 @@ typedef struct {
|
||||
*/
|
||||
static inline void esp_apptrace_tmo_init(esp_apptrace_tmo_t *tmo, uint32_t user_tmo)
|
||||
{
|
||||
tmo->start = portGET_RUN_TIME_COUNTER_VALUE();
|
||||
tmo->tmo = 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks timeout for expiration.
|
||||
*
|
||||
* @param tmo Pointer to timeout structure to be initialized.
|
||||
* @param tmo Pointer to timeout structure.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise \see esp_err_t
|
||||
* @return number of remaining us till tmo.
|
||||
*/
|
||||
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 != ESP_APPTRACE_TMO_INFINITE ? (tmo->elapsed - tmo->tmo) : ESP_APPTRACE_TMO_INFINITE;
|
||||
return tmo->tmo != (int64_t)-1 ? (tmo->elapsed - tmo->tmo) : ESP_APPTRACE_TMO_INFINITE;
|
||||
}
|
||||
|
||||
/** Tracing module synchronization lock */
|
||||
@@ -168,6 +169,30 @@ 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
|
||||
|
||||
@@ -20,7 +20,7 @@ extern "C" {
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "esp_err.h"
|
||||
#include "SEGGER_RTT.h" // SEGGER_RTT_ESP32_Flush
|
||||
#include "SEGGER_RTT.h" // SEGGER_RTT_ESP_Flush
|
||||
#include "esp_app_trace_util.h" // ESP_APPTRACE_TMO_INFINITE
|
||||
|
||||
/**
|
||||
@@ -32,7 +32,7 @@ extern "C" {
|
||||
*/
|
||||
static inline esp_err_t esp_sysview_flush(uint32_t tmo)
|
||||
{
|
||||
SEGGER_RTT_ESP32_Flush(0, tmo);
|
||||
SEGGER_RTT_ESP_Flush(0, tmo);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,17 +3,17 @@ archive: libapp_trace.a
|
||||
entries:
|
||||
app_trace (noflash)
|
||||
app_trace_util (noflash)
|
||||
if SYSVIEW_ENABLE = y:
|
||||
if APPTRACE_SV_ENABLE = y:
|
||||
SEGGER_SYSVIEW (noflash)
|
||||
SEGGER_RTT_esp32 (noflash)
|
||||
SEGGER_RTT_esp (noflash)
|
||||
SEGGER_SYSVIEW_Config_FreeRTOS (noflash)
|
||||
SEGGER_SYSVIEW_FreeRTOS (noflash)
|
||||
|
||||
[mapping:app_trace_driver]
|
||||
archive: libdriver.a
|
||||
entries:
|
||||
if SYSVIEW_TS_SOURCE_TIMER_00 = y || SYSVIEW_TS_SOURCE_TIMER_01 = y
|
||||
|| SYSVIEW_TS_SOURCE_TIMER_10 = y || SYSVIEW_TS_SOURCE_TIMER_11 = y:
|
||||
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)
|
||||
|
||||
43
components/app_trace/port/include/esp_app_trace_port.h
Normal file
43
components/app_trace/port/include/esp_app_trace_port.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// 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
|
||||
374
components/app_trace/port/riscv/port.c
Normal file
374
components/app_trace/port/riscv/port.c
Normal file
@@ -0,0 +1,374 @@
|
||||
#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;
|
||||
}
|
||||
543
components/app_trace/port/xtensa/port.c
Normal file
543
components/app_trace/port/xtensa/port.c
Normal file
@@ -0,0 +1,543 @@
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// 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
|
||||
@@ -3,10 +3,34 @@
|
||||
|
||||
CONFIG_ESP32_APPTRACE_DESTINATION CONFIG_APPTRACE_DESTINATION
|
||||
CONFIG_ESP32_APPTRACE_DEST_NONE CONFIG_APPTRACE_DEST_NONE
|
||||
CONFIG_ESP32_APPTRACE_DEST_TRAX CONFIG_APPTRACE_DEST_TRAX
|
||||
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
|
||||
|
||||
@@ -159,8 +159,8 @@ 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_ESP32_FlushNoLock (unsigned long min_sz, unsigned long tmo);
|
||||
void SEGGER_RTT_ESP32_Flush (unsigned long min_sz, unsigned long tmo);
|
||||
void SEGGER_RTT_ESP_FlushNoLock (unsigned long min_sz, unsigned long tmo);
|
||||
void SEGGER_RTT_ESP_Flush (unsigned long min_sz, unsigned long tmo);
|
||||
//
|
||||
// Function macro for performance optimization
|
||||
//
|
||||
|
||||
@@ -73,6 +73,8 @@ Revision: $Rev: 3734 $
|
||||
#include "esp32/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/clk.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -89,11 +91,17 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
|
||||
|
||||
// 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
|
||||
|
||||
// Determine which timer to use as timestamp source
|
||||
#if CONFIG_SYSVIEW_TS_SOURCE_CCOUNT
|
||||
#if CONFIG_APPTRACE_SV_TS_SOURCE_CCOUNT
|
||||
#define TS_USE_CCOUNT 1
|
||||
#elif CONFIG_SYSVIEW_TS_SOURCE_ESP_TIMER
|
||||
#elif CONFIG_APPTRACE_SV_TS_SOURCE_ESP_TIMER
|
||||
#define TS_USE_ESP_TIMER 1
|
||||
#else
|
||||
#define TS_USE_TIMERGROUP 1
|
||||
@@ -109,13 +117,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_SYSVIEW_TS_SOURCE_TIMER_00) || defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_01)
|
||||
#if defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00) || defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_01)
|
||||
#define TS_TIMER_ID 0
|
||||
#else
|
||||
#define TS_TIMER_ID 1
|
||||
#endif // TIMER_00 || TIMER_01
|
||||
|
||||
#if defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_00) || defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_10)
|
||||
#if defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_00) || defined(CONFIG_APPTRACE_SV_TS_SOURCE_TIMER_10)
|
||||
#define TS_TIMER_GROUP 0
|
||||
#else
|
||||
#define TS_TIMER_GROUP 1
|
||||
@@ -143,12 +151,16 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
|
||||
// The lowest RAM address used for IDs (pointers)
|
||||
#define SYSVIEW_RAM_BASE (SOC_DROM_LOW)
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
|
||||
#if CONFIG_FREERTOS_CORETIMER_0
|
||||
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER0_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
||||
#endif
|
||||
#if CONFIG_FREERTOS_CORETIMER_1
|
||||
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER1_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
||||
#endif
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#define SYSTICK_INTR_ID (ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
|
||||
#endif
|
||||
|
||||
// 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
|
||||
@@ -167,11 +179,13 @@ 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=Xtensa,O=FreeRTOS");
|
||||
SEGGER_SYSVIEW_SendSysDesc("N="SYSVIEW_APP_NAME",D="SYSVIEW_DEVICE_NAME",C="SYSVIEW_CORE_NAME",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]);
|
||||
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]);
|
||||
SEGGER_SYSVIEW_SendSysDesc(irq_str);
|
||||
}
|
||||
@@ -213,43 +227,43 @@ void SEGGER_SYSVIEW_Conf(void) {
|
||||
&SYSVIEW_X_OS_TraceAPI, _cbSendSystemDesc);
|
||||
SEGGER_SYSVIEW_SetRAMBase(SYSVIEW_RAM_BASE);
|
||||
|
||||
#if !CONFIG_SYSVIEW_EVT_OVERFLOW_ENABLE
|
||||
#if !CONFIG_APPTRACE_SV_EVT_OVERFLOW_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_OVERFLOW;
|
||||
#endif
|
||||
#if !CONFIG_SYSVIEW_EVT_ISR_ENTER_ENABLE
|
||||
#if !CONFIG_APPTRACE_SV_EVT_ISR_ENTER_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_ISR_ENTER;
|
||||
#endif
|
||||
#if !CONFIG_SYSVIEW_EVT_ISR_EXIT_ENABLE
|
||||
#if !CONFIG_APPTRACE_SV_EVT_ISR_EXIT_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_ISR_EXIT;
|
||||
#endif
|
||||
#if !CONFIG_SYSVIEW_EVT_TASK_START_EXEC_ENABLE
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TASK_START_EXEC_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TASK_START_EXEC;
|
||||
#endif
|
||||
#if !CONFIG_SYSVIEW_EVT_TASK_STOP_EXEC_ENABLE
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TASK_STOP_EXEC_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TASK_STOP_EXEC;
|
||||
#endif
|
||||
#if !CONFIG_SYSVIEW_EVT_TASK_START_READY_ENABLE
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TASK_START_READY_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TASK_START_READY;
|
||||
#endif
|
||||
#if !CONFIG_SYSVIEW_EVT_TASK_STOP_READY_ENABLE
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TASK_STOP_READY_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TASK_STOP_READY;
|
||||
#endif
|
||||
#if !CONFIG_SYSVIEW_EVT_TASK_CREATE_ENABLE
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TASK_CREATE_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TASK_CREATE;
|
||||
#endif
|
||||
#if !CONFIG_SYSVIEW_EVT_TASK_TERMINATE_ENABLE
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TASK_TERMINATE_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TASK_TERMINATE;
|
||||
#endif
|
||||
#if !CONFIG_SYSVIEW_EVT_IDLE_ENABLE
|
||||
#if !CONFIG_APPTRACE_SV_EVT_IDLE_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_IDLE;
|
||||
#endif
|
||||
#if !CONFIG_SYSVIEW_EVT_ISR_TO_SCHEDULER_ENABLE
|
||||
#if !CONFIG_APPTRACE_SV_EVT_ISR_TO_SCHED_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_ISR_TO_SCHEDULER;
|
||||
#endif
|
||||
#if !CONFIG_SYSVIEW_EVT_TIMER_ENTER_ENABLE
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TIMER_ENTER_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TIMER_ENTER;
|
||||
#endif
|
||||
#if !CONFIG_SYSVIEW_EVT_TIMER_EXIT_ENABLE
|
||||
#if !CONFIG_APPTRACE_SV_EVT_TIMER_EXIT_ENABLE
|
||||
disable_evts |= SYSVIEW_EVTMASK_TIMER_EXIT;
|
||||
#endif
|
||||
SEGGER_SYSVIEW_DisableEvents(disable_evts);
|
||||
|
||||
@@ -80,7 +80,7 @@ Notes:
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#endif
|
||||
|
||||
#define SYSVIEW_FREERTOS_MAX_NOF_TASKS CONFIG_SYSVIEW_MAX_TASKS
|
||||
#define SYSVIEW_FREERTOS_MAX_NOF_TASKS CONFIG_APPTRACE_SV_MAX_TASKS
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
@@ -290,12 +290,12 @@ Notes:
|
||||
#define traceTASK_SWITCHED_IN() if(prvGetTCBFromHandle(NULL) == xTaskGetIdleTaskHandle()) { \
|
||||
SEGGER_SYSVIEW_OnIdle(); \
|
||||
} else { \
|
||||
SEGGER_SYSVIEW_OnTaskStartExec((U32)pxCurrentTCB[xPortGetCoreID()]); \
|
||||
SEGGER_SYSVIEW_OnTaskStartExec((U32)pxCurrentTCB[cpu_hal_get_core_id()]); \
|
||||
}
|
||||
#else
|
||||
#define traceTASK_SWITCHED_IN() { \
|
||||
if (memcmp(pxCurrentTCB[xPortGetCoreID()]->pcTaskName, "IDLE", 5) != 0) { \
|
||||
SEGGER_SYSVIEW_OnTaskStartExec((U32)pxCurrentTCB[xPortGetCoreID()]); \
|
||||
if (memcmp(pxCurrentTCB[cpu_hal_get_core_id()]->pcTaskName, "IDLE", 5) != 0) { \
|
||||
SEGGER_SYSVIEW_OnTaskStartExec((U32)pxCurrentTCB[cpu_hal_get_core_id()]); \
|
||||
} else { \
|
||||
SEGGER_SYSVIEW_OnIdle(); \
|
||||
} \
|
||||
@@ -305,14 +305,15 @@ 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[xPortGetCoreID()], (1u << 2))
|
||||
#define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST() SEGGER_SYSVIEW_OnTaskStopReady((U32)pxCurrentTCB[xPortGetCoreID()], (1u << 2))
|
||||
#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_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
|
||||
|
||||
@@ -28,10 +28,10 @@ const static char *TAG = "segger_rtt";
|
||||
// size of down channel data buf
|
||||
#define SYSVIEW_DOWN_BUF_SIZE 32
|
||||
#define SEGGER_STOP_WAIT_TMO 1000000 //us
|
||||
#if CONFIG_SYSVIEW_BUF_WAIT_TMO == -1
|
||||
#if CONFIG_APPTRACE_SV_BUF_WAIT_TMO == -1
|
||||
#define SEGGER_HOST_WAIT_TMO ESP_APPTRACE_TMO_INFINITE
|
||||
#else
|
||||
#define SEGGER_HOST_WAIT_TMO CONFIG_SYSVIEW_BUF_WAIT_TMO
|
||||
#define SEGGER_HOST_WAIT_TMO CONFIG_APPTRACE_SV_BUF_WAIT_TMO
|
||||
#endif
|
||||
|
||||
static uint8_t s_events_buf[SYSVIEW_EVENTS_BUF_SZ];
|
||||
@@ -47,7 +47,7 @@ static uint8_t s_down_buf[SYSVIEW_DOWN_BUF_SIZE];
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_ESP32_FlushNoLock()
|
||||
* SEGGER_RTT_ESP_FlushNoLock()
|
||||
*
|
||||
* Function description
|
||||
* Flushes buffered events.
|
||||
@@ -59,7 +59,7 @@ static uint8_t s_down_buf[SYSVIEW_DOWN_BUF_SIZE];
|
||||
* Return value
|
||||
* None.
|
||||
*/
|
||||
void SEGGER_RTT_ESP32_FlushNoLock(unsigned long min_sz, unsigned long tmo)
|
||||
void SEGGER_RTT_ESP_FlushNoLock(unsigned long min_sz, unsigned long tmo)
|
||||
{
|
||||
esp_err_t res;
|
||||
if (s_events_buf_filled > 0) {
|
||||
@@ -78,7 +78,7 @@ void SEGGER_RTT_ESP32_FlushNoLock(unsigned long min_sz, unsigned long tmo)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SEGGER_RTT_ESP32_Flush()
|
||||
* SEGGER_RTT_ESP_Flush()
|
||||
*
|
||||
* Function description
|
||||
* Flushes buffered events.
|
||||
@@ -90,10 +90,10 @@ void SEGGER_RTT_ESP32_FlushNoLock(unsigned long min_sz, unsigned long tmo)
|
||||
* Return value
|
||||
* None.
|
||||
*/
|
||||
void SEGGER_RTT_ESP32_Flush(unsigned long min_sz, unsigned long tmo)
|
||||
void SEGGER_RTT_ESP_Flush(unsigned long min_sz, unsigned long tmo)
|
||||
{
|
||||
SEGGER_SYSVIEW_LOCK();
|
||||
SEGGER_RTT_ESP32_FlushNoLock(min_sz, tmo);
|
||||
SEGGER_RTT_ESP_FlushNoLock(min_sz, tmo);
|
||||
SEGGER_SYSVIEW_UNLOCK();
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u
|
||||
ESP_LOGE(TAG, "Too large event %u bytes!", NumBytes);
|
||||
return 0;
|
||||
}
|
||||
if (xPortGetCoreID()) { // dual core specific code
|
||||
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)
|
||||
@@ -175,7 +175,7 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u
|
||||
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);
|
||||
SEGGER_RTT_ESP_FlushNoLock(0, SEGGER_STOP_WAIT_TMO);
|
||||
}
|
||||
return NumBytes;
|
||||
}
|
||||
@@ -60,7 +60,7 @@ esp_err_t esp_sysview_heap_trace_start(uint32_t tmo)
|
||||
esp_err_t esp_sysview_heap_trace_stop(void)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __func__);
|
||||
SEGGER_RTT_ESP32_Flush(0, ESP_APPTRACE_TMO_INFINITE);
|
||||
SEGGER_RTT_ESP_Flush(0, ESP_APPTRACE_TMO_INFINITE);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ static void esp_apptrace_test_timer_init(int timer_group, int timer_idx, uint32_
|
||||
timer_enable_intr(timer_group, timer_idx);
|
||||
}
|
||||
|
||||
#if CONFIG_SYSVIEW_ENABLE == 0
|
||||
#if CONFIG_APPTRACE_SV_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)
|
||||
@@ -209,7 +209,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(), xPortGetCoreID(), i++);
|
||||
ESP_APPTRACE_TEST_LOGD("%x: dummy task work %d.%d", xTaskGetCurrentTaskHandle(), cpu_hal_get_core_id(), i++);
|
||||
if (tmo_ticks) {
|
||||
vTaskDelay(tmo_ticks);
|
||||
}
|
||||
@@ -254,7 +254,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) | (xPortGetCoreID() ? 0x1 : 0);
|
||||
*(uint32_t *)arg->timers[i].data.buf = ((uint32_t)inth[i]) | (1 << 31) | (cpu_hal_get_core_id() ? 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) {
|
||||
@@ -264,7 +264,7 @@ static void esp_apptrace_test_task(void *p)
|
||||
}
|
||||
}
|
||||
|
||||
*(uint32_t *)arg->data.buf = (uint32_t)xTaskGetCurrentTaskHandle() | (xPortGetCoreID() ? 0x1 : 0);
|
||||
*(uint32_t *)arg->data.buf = (uint32_t)xTaskGetCurrentTaskHandle() | (cpu_hal_get_core_id() ? 0x1 : 0);
|
||||
arg->data.wr_cnt = 0;
|
||||
arg->data.wr_err = 0;
|
||||
while (!arg->stop) {
|
||||
@@ -744,7 +744,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(), xPortGetCoreID(), i);
|
||||
ESP_LOGI(TAG, "%p: logtrace task work %d.%d", xTaskGetCurrentTaskHandle(), cpu_hal_get_core_id(), i);
|
||||
if (++i == 10000) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/*
|
||||
* Tests for switching between partitions: factory, OTAx, test.
|
||||
*/
|
||||
@@ -821,3 +826,25 @@ static void test_flow6(void)
|
||||
// 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);
|
||||
|
||||
TEST_CASE("Test bootloader_common_get_sha256_of_partition returns ESP_ERR_IMAGE_INVALID when image is ivalid", "[partitions]")
|
||||
{
|
||||
const esp_partition_t *cur_app = esp_ota_get_running_partition();
|
||||
ESP_LOGI(TAG, "copy current app to next part");
|
||||
const esp_partition_t *other_app = get_next_update_partition();
|
||||
copy_current_app_to_next_part(cur_app, other_app);
|
||||
erase_ota_data();
|
||||
|
||||
uint8_t sha_256_cur_app[32];
|
||||
uint8_t sha_256_other_app[32];
|
||||
TEST_ESP_OK(bootloader_common_get_sha256_of_partition(cur_app->address, cur_app->size, cur_app->type, sha_256_cur_app));
|
||||
TEST_ESP_OK(bootloader_common_get_sha256_of_partition(other_app->address, other_app->size, other_app->type, sha_256_other_app));
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha_256_cur_app, sha_256_other_app, sizeof(sha_256_cur_app), "must be the same");
|
||||
|
||||
uint32_t data = 0;
|
||||
bootloader_flash_write(other_app->address + 0x50, &data, sizeof(data), false);
|
||||
|
||||
TEST_ESP_ERR(ESP_ERR_IMAGE_INVALID, bootloader_common_get_sha256_of_partition(other_app->address, other_app->size, other_app->type, sha_256_other_app));
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha_256_cur_app, sha_256_other_app, sizeof(sha_256_cur_app), "must be the same");
|
||||
}
|
||||
|
||||
@@ -480,7 +480,7 @@ menu "Security features"
|
||||
config SECURE_BOOT
|
||||
bool "Enable hardware Secure Boot in bootloader (READ DOCS FIRST)"
|
||||
default n
|
||||
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || ESP32C3_REV_MIN_3
|
||||
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || ESP32C3_REV_MIN >= 3
|
||||
select ESPTOOLPY_NO_STUB if !IDF_TARGET_ESP32 && !IDF_TARGET_ESP32S2
|
||||
help
|
||||
Build a bootloader which enables Secure Boot on first boot.
|
||||
|
||||
@@ -104,9 +104,10 @@ void bootloader_atexit(void);
|
||||
esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Debug log contents of a buffer as hexadecimal
|
||||
* @brief Debug log contents of a buffer as hexadecimal.
|
||||
*
|
||||
* @note Only works if component log level is DEBUG or higher.
|
||||
* @note - Only works if component log level is DEBUG or higher.
|
||||
* - It will print at most 128 bytes from @c buffer.
|
||||
*
|
||||
* @param buffer Buffer to log
|
||||
* @param length Length of buffer in bytes. Maximum length 128 bytes.
|
||||
|
||||
@@ -169,6 +169,12 @@ esp_err_t bootloader_common_get_sha256_of_partition (uint32_t address, uint32_t
|
||||
}
|
||||
if (data.image.hash_appended) {
|
||||
memcpy(out_sha_256, data.image_digest, ESP_PARTITION_HASH_LEN);
|
||||
uint8_t calc_sha256[ESP_PARTITION_HASH_LEN];
|
||||
// The hash is verified before returning, if app content is invalid then the function returns ESP_ERR_IMAGE_INVALID.
|
||||
esp_err_t error = bootloader_sha256_flash_contents(address, data.image_len - ESP_PARTITION_HASH_LEN, calc_sha256);
|
||||
if (error || memcmp(data.image_digest, calc_sha256, ESP_PARTITION_HASH_LEN) != 0) {
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
// If image doesn't have a appended hash then hash calculates for entire image.
|
||||
|
||||
@@ -76,10 +76,12 @@ void bootloader_console_init(void)
|
||||
// Route GPIO signals to/from pins
|
||||
const uint32_t tx_idx = uart_periph_signal[uart_num].tx_sig;
|
||||
const uint32_t rx_idx = uart_periph_signal[uart_num].rx_sig;
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[uart_rx_gpio], PIN_FUNC_GPIO);
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[uart_rx_gpio]);
|
||||
esp_rom_gpio_pad_pullup_only(uart_rx_gpio);
|
||||
esp_rom_gpio_connect_out_signal(uart_tx_gpio, tx_idx, 0, 0);
|
||||
esp_rom_gpio_connect_in_signal(uart_rx_gpio, rx_idx, 0);
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[uart_tx_gpio], PIN_FUNC_GPIO);
|
||||
// Enable the peripheral
|
||||
periph_ll_enable_clk_clear_rst(PERIPH_UART0_MODULE + uart_num);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
uint8_t bootloader_common_get_chip_revision(void)
|
||||
{
|
||||
// should return the same value as esp_efuse_get_chip_ver()
|
||||
/* No other revisions for ESP32-S2 */
|
||||
return REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_3_REG, EFUSE_WAFER_VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,15 +43,15 @@
|
||||
|
||||
#define BYTESHIFT(VAR, IDX) (((VAR) >> ((IDX) * 8)) & 0xFF)
|
||||
#define ISSI_ID 0x9D
|
||||
#define MXIC_ID 0xC2
|
||||
#define GD_Q_ID_HIGH 0xC8
|
||||
#define GD_Q_ID_MID 0x40
|
||||
#define GD_Q_ID_LOW 0x16
|
||||
|
||||
#define ESP_BOOTLOADER_SPIFLASH_BP_MASK_ISSI (BIT7 | BIT5 | BIT4 | BIT3 | BIT2)
|
||||
#define ESP_BOOTLOADER_SPIFLASH_QE_16B BIT9 // QE position when you write 16 bits at one time.
|
||||
#define ESP_BOOTLOADER_SPIFLASH_QE_8B BIT1 // QE position when you write 8 bits(for SR2) at one time.
|
||||
#define ESP_BOOTLOADER_SPIFLASH_WRITE_8B (8)
|
||||
#define ESP_BOOTLOADER_SPIFLASH_WRITE_16B (16)
|
||||
#define ESP_BOOTLOADER_SPIFLASH_QE_GD_SR2 BIT1 // QE position when you write 8 bits(for SR2) at one time.
|
||||
#define ESP_BOOTLOADER_SPIFLASH_QE_SR1_2BYTE BIT9 // QE position when you write 16 bits at one time.
|
||||
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
/* Normal app version maps to esp_spi_flash.h operations...
|
||||
@@ -466,72 +466,77 @@ FORCE_INLINE_ATTR bool is_gd_q_chip(const esp_rom_spiflash_chip_t* chip)
|
||||
return BYTESHIFT(chip->device_id, 2) == GD_Q_ID_HIGH && BYTESHIFT(chip->device_id, 1) == GD_Q_ID_MID && BYTESHIFT(chip->device_id, 0) >= GD_Q_ID_LOW;
|
||||
}
|
||||
|
||||
FORCE_INLINE_ATTR bool is_mxic_chip(const esp_rom_spiflash_chip_t* chip)
|
||||
{
|
||||
return BYTESHIFT(chip->device_id, 2) == MXIC_ID;
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR __attribute__((weak)) bootloader_flash_unlock(void)
|
||||
{
|
||||
// At the beginning status == new_status == status_sr2 == new_status_sr2 == 0.
|
||||
// If the register doesn't need to be updated, keep them the same (0), so that no command will be actually sent.
|
||||
uint16_t status = 0; // status for SR1 or SR1+SR2 if writing SR with 01H + 2Bytes.
|
||||
uint16_t new_status = 0;
|
||||
uint8_t status_sr2 = 0; // status_sr2 for SR2.
|
||||
uint8_t new_status_sr2 = 0;
|
||||
uint8_t write_sr_bit = 0;
|
||||
uint8_t sr1_bit_num = 0;
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
if (is_issi_chip(&g_rom_flashchip)) {
|
||||
write_sr_bit = ESP_BOOTLOADER_SPIFLASH_WRITE_8B;
|
||||
// ISSI chips have different QE position
|
||||
|
||||
if (is_issi_chip(&g_rom_flashchip) || is_mxic_chip(&g_rom_flashchip)) {
|
||||
// Currently ISSI & MXIC share the same command and register layout, which is different from the default model.
|
||||
// If any code here needs to be modified, check both chips.
|
||||
status = bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8);
|
||||
|
||||
/* Clear all bits in the mask.
|
||||
(This is different from ROM esp_rom_spiflash_unlock, which keeps all bits as-is.)
|
||||
*/
|
||||
sr1_bit_num = 8;
|
||||
new_status = status & (~ESP_BOOTLOADER_SPIFLASH_BP_MASK_ISSI);
|
||||
// Skip if nothing needs to be cleared. Otherwise will waste time waiting for the flash to clear nothing.
|
||||
} else if (is_gd_q_chip(&g_rom_flashchip)) {
|
||||
/* The GD chips behaviour is to clear all bits in SR1 and clear bits in SR2 except QE bit.
|
||||
Use 01H to write SR1 and 31H to write SR2.
|
||||
*/
|
||||
write_sr_bit = ESP_BOOTLOADER_SPIFLASH_WRITE_8B;
|
||||
|
||||
status = bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8);
|
||||
sr1_bit_num = 8;
|
||||
new_status = 0;
|
||||
|
||||
status_sr2 = bootloader_execute_flash_command(CMD_RDSR2, 0, 0, 8);
|
||||
new_status_sr2 = status_sr2 & ESP_BOOTLOADER_SPIFLASH_QE_8B;
|
||||
new_status_sr2 = status_sr2 & ESP_BOOTLOADER_SPIFLASH_QE_GD_SR2;
|
||||
} else {
|
||||
/* For common behaviour, like XMC chips, Use 01H+2Bytes to write both SR1 and SR2*/
|
||||
write_sr_bit = ESP_BOOTLOADER_SPIFLASH_WRITE_16B;
|
||||
status = bootloader_execute_flash_command(CMD_RDSR, 0, 0, 8) | (bootloader_execute_flash_command(CMD_RDSR2, 0, 0, 8) << 8);
|
||||
|
||||
/* Clear all bits except QE, if it is set.
|
||||
(This is different from ROM esp_rom_spiflash_unlock, which keeps all bits as-is.)
|
||||
*/
|
||||
new_status = status & ESP_BOOTLOADER_SPIFLASH_QE_16B;
|
||||
sr1_bit_num = 16;
|
||||
new_status = status & ESP_BOOTLOADER_SPIFLASH_QE_SR1_2BYTE;
|
||||
}
|
||||
|
||||
// When SR is written, set to true to indicate that WRDI need to be sent to ensure the protection is ON before return.
|
||||
bool status_written = false;
|
||||
// Skip if nothing needs to be changed. Meaningless writing to SR increases the risk during write and wastes time.
|
||||
if (status != new_status) {
|
||||
/* if the status in SR not equal to the ideal status, the status need to be updated */
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
bootloader_execute_flash_command(CMD_WREN, 0, 0, 0);
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
bootloader_execute_flash_command(CMD_WRSR, new_status, write_sr_bit, 0);
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
bootloader_execute_flash_command(CMD_WRSR, new_status, sr1_bit_num, 0);
|
||||
status_written = true;
|
||||
}
|
||||
|
||||
if (status_sr2 != new_status_sr2) {
|
||||
/* If the status in SR2 not equal to the ideal status, the status need to be updated.
|
||||
It doesn't need to be updated if status in SR2 is 0.
|
||||
Note: if we need to update both SR1 and SR2, the `CMD_WREN` needs to be sent again.
|
||||
*/
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
bootloader_execute_flash_command(CMD_WREN, 0, 0, 0);
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
bootloader_execute_flash_command(CMD_WRSR2, new_status_sr2, write_sr_bit, 0);
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
bootloader_execute_flash_command(CMD_WRSR2, new_status_sr2, 8, 0);
|
||||
status_written = true;
|
||||
}
|
||||
|
||||
if (status_written) {
|
||||
//Call esp_rom_spiflash_wait_idle to make sure previous WRSR is completed.
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
bootloader_execute_flash_command(CMD_WRDI, 0, 0, 0);
|
||||
}
|
||||
|
||||
bootloader_execute_flash_command(CMD_WRDI, 0, 0, 0);
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#include "bootloader_console.h"
|
||||
#include "bootloader_soc.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_fault.h"
|
||||
|
||||
static const char *TAG = "boot";
|
||||
|
||||
@@ -270,9 +271,16 @@ static esp_err_t write_otadata(esp_ota_select_entry_t *otadata, uint32_t offset,
|
||||
static bool check_anti_rollback(const esp_partition_pos_t *partition)
|
||||
{
|
||||
#ifdef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
|
||||
esp_app_desc_t app_desc;
|
||||
esp_app_desc_t app_desc = {};
|
||||
esp_err_t err = bootloader_common_get_partition_description(partition, &app_desc);
|
||||
return err == ESP_OK && esp_efuse_check_secure_version(app_desc.secure_version) == true;
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to get partition description %d", err);
|
||||
return false;
|
||||
}
|
||||
bool sec_ver = esp_efuse_check_secure_version(app_desc.secure_version);
|
||||
/* Anti FI check */
|
||||
ESP_FAULT_ASSERT(sec_ver == esp_efuse_check_secure_version(app_desc.secure_version));
|
||||
return sec_ver;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
@@ -285,6 +293,8 @@ static void update_anti_rollback(const esp_partition_pos_t *partition)
|
||||
esp_err_t err = bootloader_common_get_partition_description(partition, &app_desc);
|
||||
if (err == ESP_OK) {
|
||||
esp_efuse_update_secure_version(app_desc.secure_version);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to get partition description %d", err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -850,22 +860,19 @@ esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_he
|
||||
|
||||
void bootloader_debug_buffer(const void *buffer, size_t length, const char *label)
|
||||
{
|
||||
#if BOOT_LOG_LEVEL >= LOG_LEVEL_DEBUG
|
||||
assert(length <= 128); // Avoid unbounded VLA size
|
||||
#if CONFIG_BOOTLOADER_LOG_LEVEL >= 4
|
||||
const uint8_t *bytes = (const uint8_t *)buffer;
|
||||
char hexbuf[length * 2 + 1];
|
||||
hexbuf[length * 2] = 0;
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
for (int shift = 0; shift < 2; shift++) {
|
||||
uint8_t nibble = (bytes[i] >> (shift ? 0 : 4)) & 0x0F;
|
||||
if (nibble < 10) {
|
||||
hexbuf[i * 2 + shift] = '0' + nibble;
|
||||
} else {
|
||||
hexbuf[i * 2 + shift] = 'a' + nibble - 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
const size_t output_len = MIN(length, 128);
|
||||
char hexbuf[128 * 2 + 1];
|
||||
|
||||
bootloader_sha256_hex_to_str(hexbuf, bytes, output_len);
|
||||
|
||||
hexbuf[output_len * 2] = '\0';
|
||||
ESP_LOGD(TAG, "%s: %s", label, hexbuf);
|
||||
#else
|
||||
(void) buffer;
|
||||
(void) length;
|
||||
(void) label;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -436,7 +436,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling ROM Download mode - SECURITY COMPROMISED");
|
||||
ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS
|
||||
|
||||
@@ -150,7 +150,7 @@ static esp_err_t initialise_flash_encryption(void)
|
||||
ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT);
|
||||
|
||||
#if defined(CONFIG_SECURE_BOOT_V2_ENABLED) && !defined(CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS)
|
||||
// This bit is set when enabling Secure Boot V2, but we can't enable it until this later point in the first boot
|
||||
|
||||
@@ -256,13 +256,25 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
|
||||
return key_state;
|
||||
}
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT);
|
||||
|
||||
esp_err_t err = ESP_FAIL;
|
||||
#ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE
|
||||
ESP_LOGI(TAG, "Enabling Security download mode...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD);
|
||||
err = esp_efuse_enable_rom_secure_download_mode();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not enable Security download mode...");
|
||||
return err;
|
||||
}
|
||||
#elif CONFIG_SECURE_DISABLE_ROM_DL_MODE
|
||||
ESP_LOGI(TAG, "Disable ROM Download mode...");
|
||||
err = esp_efuse_disable_rom_download_mode();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not disable ROM Download mode...");
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not enabling Security download mode - SECURITY COMPROMISED");
|
||||
ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
|
||||
@@ -295,7 +307,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
|
||||
ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
esp_err_t err = esp_efuse_batch_write_commit();
|
||||
err = esp_efuse_batch_write_commit();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
|
||||
return err;
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "esp32s2/rom/efuse.h"
|
||||
#include "esp32s2/rom/secure_boot.h"
|
||||
|
||||
#include "esp_flash_encrypt.h"
|
||||
|
||||
static const char *TAG = "secure_boot_v2";
|
||||
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
|
||||
|
||||
@@ -261,11 +263,23 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_BOOT_REMAP);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
|
||||
|
||||
esp_err_t err = ESP_FAIL;
|
||||
#ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE
|
||||
ESP_LOGI(TAG, "Enabling Security download mode...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD);
|
||||
err = esp_efuse_enable_rom_secure_download_mode();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not enable Security download mode...");
|
||||
return err;
|
||||
}
|
||||
#elif CONFIG_SECURE_DISABLE_ROM_DL_MODE
|
||||
ESP_LOGI(TAG, "Disable ROM Download mode...");
|
||||
err = esp_efuse_disable_rom_download_mode();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not disable ROM Download mode...");
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not enabling Security download mode - SECURITY COMPROMISED");
|
||||
ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
|
||||
@@ -297,7 +311,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
|
||||
ESP_LOGW(TAG, "Allowing read disabling of additional efuses - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
esp_err_t err = esp_efuse_batch_write_commit();
|
||||
err = esp_efuse_batch_write_commit();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
|
||||
return err;
|
||||
|
||||
@@ -172,7 +172,7 @@ static esp_err_t initialise_flash_encryption(void)
|
||||
ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT);
|
||||
|
||||
esp_err_t err = esp_efuse_batch_write_commit();
|
||||
if (err != ESP_OK) {
|
||||
|
||||
@@ -258,13 +258,25 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
|
||||
|
||||
__attribute__((unused)) static const uint8_t enable = 1;
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT);
|
||||
|
||||
esp_err_t err = ESP_FAIL;
|
||||
#ifdef CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE
|
||||
ESP_LOGI(TAG, "Enabling Security download mode...");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD);
|
||||
err = esp_efuse_enable_rom_secure_download_mode();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not enable Security download mode...");
|
||||
return err;
|
||||
}
|
||||
#elif CONFIG_SECURE_DISABLE_ROM_DL_MODE
|
||||
ESP_LOGI(TAG, "Disable ROM Download mode...");
|
||||
err = esp_efuse_disable_rom_download_mode();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not disable ROM Download mode...");
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not enabling Security download mode - SECURITY COMPROMISED");
|
||||
ESP_LOGW(TAG, "UART ROM Download mode kept enabled - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
|
||||
@@ -281,7 +293,7 @@ esp_err_t esp_secure_boot_v2_permanently_enable(const esp_image_metadata_t *imag
|
||||
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN);
|
||||
|
||||
esp_err_t err = esp_efuse_batch_write_commit();
|
||||
err = esp_efuse_batch_write_commit();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error programming security eFuses (err=0x%x).", err);
|
||||
return err;
|
||||
|
||||
@@ -88,6 +88,7 @@ const static qio_info_t chip_data[] = {
|
||||
{ "WinBond", 0xEF, 0x4000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 },
|
||||
{ "GD", 0xC8, 0x6000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 },
|
||||
{ "XM25QU64A", 0x20, 0x3817, 0xFFFF, read_status_8b_xmc25qu64a, write_status_8b_xmc25qu64a, 6 },
|
||||
{ "TH", 0xcd, 0x6000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 },
|
||||
|
||||
/* Final entry is default entry, if no other IDs have matched.
|
||||
|
||||
|
||||
@@ -7,42 +7,16 @@ menu "Bluetooth"
|
||||
help
|
||||
Select this option to enable Bluetooth and show the submenu with Bluetooth configuration choices.
|
||||
|
||||
config BT_CTRL_ESP32
|
||||
bool
|
||||
depends on BT_ENABLED && IDF_TARGET_ESP32
|
||||
default y
|
||||
|
||||
config BT_CTRL_ESP32C3
|
||||
bool
|
||||
depends on BT_ENABLED && IDF_TARGET_ESP32C3
|
||||
default y
|
||||
config BT_CTRL_ESP32S3
|
||||
bool
|
||||
depends on BT_ENABLED && IDF_TARGET_ESP32S3
|
||||
default y
|
||||
|
||||
config BT_SOC_SUPPORT_5_0
|
||||
bool
|
||||
depends on BT_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3)
|
||||
default y if BT_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3)
|
||||
default n
|
||||
|
||||
menu "Bluetooth controller(ESP32 Dual Mode Bluetooth)"
|
||||
visible if BT_CTRL_ESP32
|
||||
menu "Bluetooth controller"
|
||||
depends on BT_ENABLED
|
||||
|
||||
source "$IDF_PATH/components/bt/controller/esp32/Kconfig.in"
|
||||
endmenu
|
||||
|
||||
menu "Bluetooth controller(ESP32C3 Bluetooth Low Energy)"
|
||||
visible if BT_CTRL_ESP32C3
|
||||
|
||||
source "$IDF_PATH/components/bt/controller/esp32c3/Kconfig.in"
|
||||
endmenu
|
||||
|
||||
menu "Bluetooth controller(ESP32S3 Bluetooth Low Energy)"
|
||||
visible if BT_CTRL_ESP32S3
|
||||
|
||||
source "$IDF_PATH/components/bt/controller/esp32s3/Kconfig.in"
|
||||
source "$IDF_PATH/components/bt/controller/$IDF_TARGET/Kconfig.in"
|
||||
endmenu
|
||||
|
||||
choice BT_HOST
|
||||
@@ -73,12 +47,12 @@ menu "Bluetooth"
|
||||
endchoice
|
||||
|
||||
menu "Bluedroid Options"
|
||||
visible if BT_BLUEDROID_ENABLED
|
||||
depends on BT_BLUEDROID_ENABLED
|
||||
|
||||
source "$IDF_PATH/components/bt/host/bluedroid/Kconfig.in"
|
||||
endmenu
|
||||
menu "NimBLE Options"
|
||||
visible if BT_NIMBLE_ENABLED
|
||||
depends on BT_NIMBLE_ENABLED
|
||||
|
||||
source "$IDF_PATH/components/bt/host/nimble/Kconfig.in"
|
||||
endmenu
|
||||
|
||||
@@ -324,6 +324,12 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
|
||||
blufi_env.conn_id = p_data->conn.conn_id;
|
||||
blufi_env.recv_seq = blufi_env.send_seq = 0;
|
||||
blufi_env.sec_mode = 0x0;
|
||||
blufi_env.offset = 0;
|
||||
|
||||
if (blufi_env.aggr_buf != NULL) {
|
||||
osi_free(blufi_env.aggr_buf);
|
||||
blufi_env.aggr_buf = NULL;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
|
||||
@@ -274,6 +274,13 @@ esp_blufi_gap_event(struct ble_gap_event *event, void *arg)
|
||||
blufi_env.is_connected = false;
|
||||
blufi_env.recv_seq = blufi_env.send_seq = 0;
|
||||
blufi_env.sec_mode = 0x0;
|
||||
blufi_env.offset = 0;
|
||||
|
||||
if (blufi_env.aggr_buf != NULL) {
|
||||
osi_free(blufi_env.aggr_buf);
|
||||
blufi_env.aggr_buf = NULL;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
esp_blufi_cb_param_t param;
|
||||
|
||||
|
||||
@@ -550,10 +550,12 @@ static void config_parse(nvs_handle_t fp, config_t *config)
|
||||
const size_t keyname_bufsz = sizeof(CONFIG_KEY) + 5 + 1; // including log10(sizeof(i))
|
||||
char *keyname = osi_calloc(keyname_bufsz);
|
||||
int buf_size = get_config_size_from_flash(fp);
|
||||
char *buf = osi_calloc(buf_size);
|
||||
char *buf = NULL;
|
||||
|
||||
if(buf_size == 0) { //First use nvs
|
||||
goto error;
|
||||
}
|
||||
buf = osi_calloc(buf_size);
|
||||
if (!line || !section || !buf || !keyname) {
|
||||
err_code |= 0x01;
|
||||
goto error;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
choice BTDM_CTRL_MODE
|
||||
prompt "Bluetooth controller mode (BR/EDR/BLE/DUALMODE)"
|
||||
depends on BT_CTRL_ESP32
|
||||
help
|
||||
Specify the bluetooth controller mode (BR/EDR, BLE or dual mode).
|
||||
|
||||
@@ -152,7 +151,7 @@ config BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF
|
||||
|
||||
choice BTDM_CTRL_PINNED_TO_CORE_CHOICE
|
||||
prompt "The cpu core which bluetooth controller run"
|
||||
depends on BT_CTRL_ESP32 && !FREERTOS_UNICORE
|
||||
depends on !FREERTOS_UNICORE
|
||||
help
|
||||
Specify the cpu core to run bluetooth controller.
|
||||
Can not specify no-affinity.
|
||||
@@ -172,7 +171,6 @@ config BTDM_CTRL_PINNED_TO_CORE
|
||||
|
||||
choice BTDM_CTRL_HCI_MODE_CHOICE
|
||||
prompt "HCI mode"
|
||||
depends on BT_CTRL_ESP32
|
||||
help
|
||||
Speicify HCI mode as VHCI or UART(H4)
|
||||
|
||||
@@ -210,11 +208,8 @@ menu "HCI UART(H4) Options"
|
||||
endmenu
|
||||
|
||||
menu "MODEM SLEEP Options"
|
||||
visible if BT_CTRL_ESP32
|
||||
|
||||
config BTDM_CTRL_MODEM_SLEEP
|
||||
bool "Bluetooth modem sleep"
|
||||
depends on BT_CTRL_ESP32
|
||||
default y
|
||||
help
|
||||
Enable/disable bluetooth controller low power mode.
|
||||
@@ -413,5 +408,10 @@ config BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD
|
||||
help
|
||||
When adv report flow control is enabled, The ADV lost event will be generated when the number
|
||||
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value.
|
||||
If you set `BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it
|
||||
If you set it to a small value or printf every adv lost event, it
|
||||
may cause adv packets lost more.
|
||||
|
||||
config BTDM_RESERVE_DRAM
|
||||
hex
|
||||
default 0xdb5c if BT_ENABLED
|
||||
default 0
|
||||
|
||||
@@ -97,7 +97,7 @@ do{\
|
||||
|
||||
/* SPIRAM Configuration */
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
#define BTDM_MAX_QUEUE_NUM (5)
|
||||
#define BTDM_MAX_QUEUE_NUM (6)
|
||||
#endif
|
||||
|
||||
/* Types definition
|
||||
|
||||
@@ -66,6 +66,13 @@ config BT_CTRL_HW_CCA
|
||||
help
|
||||
It enables HW CCA feature in controller
|
||||
|
||||
config BT_CTRL_HW_CCA_VAL
|
||||
int "CCA threshold value"
|
||||
range 20 60
|
||||
default 20
|
||||
help
|
||||
It is the threshold value of HW CCA, if the value is 30, it means CCA threshold is -30 dBm.
|
||||
|
||||
config BT_CTRL_HW_CCA_EFF
|
||||
int
|
||||
default 1 if BT_CTRL_HW_CCA
|
||||
|
||||
@@ -246,6 +246,7 @@ extern bool btdm_deep_sleep_mem_init(void);
|
||||
extern void btdm_deep_sleep_mem_deinit(void);
|
||||
extern void btdm_ble_power_down_dma_copy(bool copy);
|
||||
extern uint8_t btdm_sleep_clock_sync(void);
|
||||
extern void sdk_config_extend_set_pll_track(bool enable);
|
||||
|
||||
#if CONFIG_MAC_BB_PD
|
||||
extern void esp_mac_bb_power_down(void);
|
||||
@@ -894,25 +895,21 @@ void esp_release_wifi_and_coex_mem(void)
|
||||
ESP_ERROR_CHECK(try_heap_caps_add_region((intptr_t)ets_rom_layout_p->data_start_interface_coexist,(intptr_t)ets_rom_layout_p->bss_end_interface_pp));
|
||||
}
|
||||
|
||||
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||
#if CONFIG_MAC_BB_PD
|
||||
static void IRAM_ATTR btdm_mac_bb_power_down_cb(void)
|
||||
{
|
||||
if (s_lp_cntl.mac_bb_pd && s_lp_stat.mac_bb_pd == 0) {
|
||||
#if (CONFIG_MAC_BB_PD)
|
||||
btdm_ble_power_down_dma_copy(true);
|
||||
#endif
|
||||
s_lp_stat.mac_bb_pd = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void IRAM_ATTR btdm_mac_bb_power_up_cb(void)
|
||||
{
|
||||
#if (CONFIG_MAC_BB_PD)
|
||||
if (s_lp_cntl.mac_bb_pd && s_lp_stat.mac_bb_pd) {
|
||||
btdm_ble_power_down_dma_copy(false);
|
||||
s_lp_stat.mac_bb_pd = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -956,6 +953,8 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
// overwrite some parameters
|
||||
cfg->magic = ESP_BT_CTRL_CONFIG_MAGIC_VAL;
|
||||
|
||||
sdk_config_extend_set_pll_track(false);
|
||||
|
||||
btdm_controller_mem_init();
|
||||
|
||||
#if CONFIG_MAC_BB_PD
|
||||
@@ -995,7 +994,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
s_lp_cntl.no_light_sleep = 1;
|
||||
|
||||
if (s_lp_cntl.enable) {
|
||||
#if (CONFIG_MAC_BB_PD)
|
||||
#if CONFIG_MAC_BB_PD
|
||||
if (!btdm_deep_sleep_mem_init()) {
|
||||
err = ESP_ERR_NO_MEM;
|
||||
goto error;
|
||||
@@ -1040,7 +1039,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
|
||||
ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock\n"
|
||||
"light sleep mode will not be able to apply when bluetooth is enabled");
|
||||
}
|
||||
#elif (CONFIG_BT_CTRL_LPCLK_SEL_RTC_SLOW)
|
||||
#elif CONFIG_BT_CTRL_LPCLK_SEL_RTC_SLOW
|
||||
// check whether or not EXT_CRYS is working
|
||||
if (rtc_clk_slow_freq_get() == RTC_SLOW_FREQ_RTC) {
|
||||
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_RTC_SLOW; // Internal 150 kHz RC oscillator
|
||||
@@ -1141,7 +1140,7 @@ error:
|
||||
s_btdm_slp_tmr = NULL;
|
||||
}
|
||||
|
||||
#if (CONFIG_MAC_BB_PD)
|
||||
#if CONFIG_MAC_BB_PD
|
||||
if (s_lp_cntl.mac_bb_pd) {
|
||||
btdm_deep_sleep_mem_deinit();
|
||||
s_lp_cntl.mac_bb_pd = 0;
|
||||
@@ -1187,7 +1186,7 @@ esp_err_t esp_bt_controller_deinit(void)
|
||||
|
||||
// deinit low power control resources
|
||||
do {
|
||||
#if (CONFIG_MAC_BB_PD)
|
||||
#if CONFIG_MAC_BB_PD
|
||||
btdm_deep_sleep_mem_deinit();
|
||||
#endif
|
||||
|
||||
|
||||
0
components/bt/controller/esp32h2/Kconfig.in
Normal file
0
components/bt/controller/esp32h2/Kconfig.in
Normal file
0
components/bt/controller/esp32s2/Kconfig.in
Normal file
0
components/bt/controller/esp32s2/Kconfig.in
Normal file
Submodule components/bt/controller/lib_esp32 updated: 54a69e5361...b877f7e1fc
Submodule components/bt/controller/lib_esp32c3_family updated: a8099f0c7f...fa1c191006
@@ -9,10 +9,10 @@ if BLE_MESH
|
||||
config BLE_MESH_USE_DUPLICATE_SCAN
|
||||
bool "Support Duplicate Scan in BLE Mesh"
|
||||
depends on BT_BLUEDROID_ENABLED
|
||||
select BTDM_BLE_SCAN_DUPL if BT_CTRL_ESP32
|
||||
select BTDM_BLE_MESH_SCAN_DUPL_EN if BT_CTRL_ESP32
|
||||
select BT_CTRL_BLE_SCAN_DUPL if BT_CTRL_ESP32C3
|
||||
select BT_CTRL_BLE_MESH_SCAN_DUPL_EN if BT_CTRL_ESP32C3
|
||||
select BTDM_BLE_SCAN_DUPL if IDF_TARGET_ESP32
|
||||
select BTDM_BLE_MESH_SCAN_DUPL_EN if IDF_TARGET_ESP32
|
||||
select BT_CTRL_BLE_SCAN_DUPL if IDF_TARGET_ESP32C3
|
||||
select BT_CTRL_BLE_MESH_SCAN_DUPL_EN if IDF_TARGET_ESP32C3
|
||||
default y
|
||||
help
|
||||
Enable this option to allow using specific duplicate scan filter
|
||||
|
||||
@@ -885,6 +885,8 @@ typedef enum {
|
||||
ESP_BLE_MESH_PROXY_CLIENT_SET_FILTER_TYPE_COMP_EVT, /*!< Proxy Client set filter type completion event */
|
||||
ESP_BLE_MESH_PROXY_CLIENT_ADD_FILTER_ADDR_COMP_EVT, /*!< Proxy Client add filter address completion event */
|
||||
ESP_BLE_MESH_PROXY_CLIENT_REMOVE_FILTER_ADDR_COMP_EVT, /*!< Proxy Client remove filter address completion event */
|
||||
ESP_BLE_MESH_PROXY_SERVER_CONNECTED_EVT, /*!< Proxy Server establishes connection successfully event */
|
||||
ESP_BLE_MESH_PROXY_SERVER_DISCONNECTED_EVT, /*!< Proxy Server terminates connection successfully event */
|
||||
ESP_BLE_MESH_MODEL_SUBSCRIBE_GROUP_ADDR_COMP_EVT, /*!< Local model subscribes group address completion event */
|
||||
ESP_BLE_MESH_MODEL_UNSUBSCRIBE_GROUP_ADDR_COMP_EVT, /*!< Local model unsubscribes group address completion event */
|
||||
ESP_BLE_MESH_DEINIT_MESH_COMP_EVT, /*!< De-initialize BLE Mesh stack completion event */
|
||||
@@ -1467,6 +1469,19 @@ typedef union {
|
||||
uint8_t conn_handle; /*!< Proxy connection handle */
|
||||
uint16_t net_idx; /*!< Corresponding NetKey Index */
|
||||
} proxy_client_remove_filter_addr_comp; /*!< Event parameter of ESP_BLE_MESH_PROXY_CLIENT_REMOVE_FILTER_ADDR_COMP_EVT */
|
||||
/**
|
||||
* @brief ESP_BLE_MESH_PROXY_SERVER_CONNECTED_EVT
|
||||
*/
|
||||
struct ble_mesh_proxy_server_connected_param {
|
||||
uint8_t conn_handle; /*!< Proxy connection handle */
|
||||
} proxy_server_connected; /*!< Event parameter of ESP_BLE_MESH_PROXY_SERVER_CONNECTED_EVT */
|
||||
/**
|
||||
* @brief ESP_BLE_MESH_PROXY_SERVER_DISCONNECTED_EVT
|
||||
*/
|
||||
struct ble_mesh_proxy_server_disconnected_param {
|
||||
uint8_t conn_handle; /*!< Proxy connection handle */
|
||||
uint8_t reason; /*!< Proxy disconnect reason */
|
||||
} proxy_server_disconnected; /*!< Event parameter of ESP_BLE_MESH_PROXY_SERVER_DISCONNECTED_EVT */
|
||||
/**
|
||||
* @brief ESP_BLE_MESH_MODEL_SUBSCRIBE_GROUP_ADDR_COMP_EVT
|
||||
*/
|
||||
|
||||
@@ -1010,6 +1010,41 @@ static void btc_ble_mesh_proxy_client_filter_status_recv_cb(uint8_t conn_handle,
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
|
||||
|
||||
#if CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||
static void btc_ble_mesh_proxy_server_connect_cb(uint8_t conn_handle)
|
||||
{
|
||||
esp_ble_mesh_prov_cb_param_t mesh_param = {0};
|
||||
|
||||
if (conn_handle >= BLE_MESH_MAX_CONN) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
BT_DBG("%s", __func__);
|
||||
|
||||
mesh_param.proxy_server_connected.conn_handle = conn_handle;
|
||||
|
||||
btc_ble_mesh_prov_callback(&mesh_param, ESP_BLE_MESH_PROXY_SERVER_CONNECTED_EVT);
|
||||
}
|
||||
|
||||
static void btc_ble_mesh_proxy_server_disconnect_cb(uint8_t conn_handle, uint8_t reason)
|
||||
{
|
||||
esp_ble_mesh_prov_cb_param_t mesh_param = {0};
|
||||
|
||||
if (conn_handle >= BLE_MESH_MAX_CONN) {
|
||||
BT_ERR("%s, Invalid parameter", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
BT_DBG("%s", __func__);
|
||||
|
||||
mesh_param.proxy_server_disconnected.conn_handle = conn_handle;
|
||||
mesh_param.proxy_server_disconnected.reason = reason;
|
||||
|
||||
btc_ble_mesh_prov_callback(&mesh_param, ESP_BLE_MESH_PROXY_SERVER_DISCONNECTED_EVT);
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */
|
||||
|
||||
int btc_ble_mesh_client_model_init(esp_ble_mesh_model_t *model)
|
||||
{
|
||||
if (!bt_mesh_is_initialized()) {
|
||||
@@ -1777,6 +1812,10 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
|
||||
bt_mesh_proxy_client_set_disconn_cb(btc_ble_mesh_proxy_client_disconnect_cb);
|
||||
bt_mesh_proxy_client_set_filter_status_cb(btc_ble_mesh_proxy_client_filter_status_recv_cb);
|
||||
#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
|
||||
#if CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||
bt_mesh_proxy_server_set_conn_cb(btc_ble_mesh_proxy_server_connect_cb);
|
||||
bt_mesh_proxy_server_set_disconn_cb(btc_ble_mesh_proxy_server_disconnect_cb);
|
||||
#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */
|
||||
int err_code = bt_mesh_init((struct bt_mesh_prov *)arg->mesh_init.prov,
|
||||
(struct bt_mesh_comp *)arg->mesh_init.comp);
|
||||
/* Give the semaphore when BLE Mesh initialization is finished. */
|
||||
|
||||
@@ -539,7 +539,8 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
|
||||
}
|
||||
}
|
||||
} else if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROXY_VAL) {
|
||||
if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->proxy_notify != NULL) {
|
||||
if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->proxy_notify != NULL &&
|
||||
bt_mesh_gattc_info[i].wr_desc_done) {
|
||||
len = bt_mesh_gattc_conn_cb->proxy_notify(&bt_mesh_gattc_info[i].conn,
|
||||
notif_data, notif_len);
|
||||
if (len < 0) {
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
|
||||
#define START_PAYLOAD_MAX 20
|
||||
#define CONT_PAYLOAD_MAX 23
|
||||
#define START_LAST_SEG_MAX 2
|
||||
|
||||
#define START_LAST_SEG(gpc) (gpc >> 2)
|
||||
#define CONT_SEG_INDEX(gpc) (gpc >> 2)
|
||||
@@ -1563,6 +1564,12 @@ static void gen_prov_start(struct prov_rx *rx, struct net_buf_simple *buf)
|
||||
return;
|
||||
}
|
||||
|
||||
if (START_LAST_SEG(rx->gpc) > START_LAST_SEG_MAX) {
|
||||
BT_ERR("Invalid SegN 0x%02x", START_LAST_SEG(rx->gpc));
|
||||
prov_send_fail_msg(PROV_ERR_UNEXP_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (link.rx.buf->len > link.rx.buf->size) {
|
||||
BT_ERR("Too large provisioning PDU (%u bytes)",
|
||||
link.rx.buf->len);
|
||||
|
||||
@@ -82,6 +82,7 @@ _Static_assert(BLE_MESH_MAX_CONN >= CONFIG_BLE_MESH_PBG_SAME_TIME,
|
||||
|
||||
#define START_PAYLOAD_MAX 20
|
||||
#define CONT_PAYLOAD_MAX 23
|
||||
#define START_LAST_SEG_MAX 2
|
||||
|
||||
#define START_LAST_SEG(gpc) (gpc >> 2)
|
||||
#define CONT_SEG_INDEX(gpc) (gpc >> 2)
|
||||
@@ -2988,6 +2989,12 @@ static void gen_prov_start(const uint8_t idx, struct prov_rx *rx, struct net_buf
|
||||
return;
|
||||
}
|
||||
|
||||
if (START_LAST_SEG(rx->gpc) > START_LAST_SEG_MAX) {
|
||||
BT_ERR("Invalid SegN 0x%02x", START_LAST_SEG(rx->gpc));
|
||||
close_link(idx, CLOSE_REASON_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (link[idx].rx.buf->len > link[idx].rx.buf->size) {
|
||||
BT_ERR("Too large provisioning PDU (%u bytes)",
|
||||
link[idx].rx.buf->len);
|
||||
|
||||
@@ -159,6 +159,23 @@ static void proxy_sar_timeout(struct k_work *work)
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
|
||||
/**
|
||||
* The following callbacks are used to notify proper information
|
||||
* to the application layer.
|
||||
*/
|
||||
static proxy_server_connect_cb_t proxy_server_connect_cb;
|
||||
static proxy_server_disconnect_cb_t proxy_server_disconnect_cb;
|
||||
|
||||
void bt_mesh_proxy_server_set_conn_cb(proxy_server_connect_cb_t cb)
|
||||
{
|
||||
proxy_server_connect_cb = cb;
|
||||
}
|
||||
|
||||
void bt_mesh_proxy_server_set_disconn_cb(proxy_server_disconnect_cb_t cb)
|
||||
{
|
||||
proxy_server_disconnect_cb = cb;
|
||||
}
|
||||
|
||||
/* Next subnet in queue to be advertised */
|
||||
static int next_idx;
|
||||
|
||||
@@ -605,6 +622,10 @@ static void proxy_connected(struct bt_mesh_conn *conn, uint8_t err)
|
||||
client->filter_type = NONE;
|
||||
#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
|
||||
(void)memset(client->filter, 0, sizeof(client->filter));
|
||||
|
||||
if (proxy_server_connect_cb) {
|
||||
proxy_server_connect_cb(conn->handle);
|
||||
}
|
||||
#endif
|
||||
net_buf_simple_reset(&client->buf);
|
||||
}
|
||||
@@ -621,6 +642,11 @@ static void proxy_disconnected(struct bt_mesh_conn *conn, uint8_t reason)
|
||||
struct bt_mesh_proxy_client *client = &clients[i];
|
||||
|
||||
if (client->conn == conn) {
|
||||
#if CONFIG_BLE_MESH_GATT_PROXY_SERVER
|
||||
if (proxy_server_disconnect_cb) {
|
||||
proxy_server_disconnect_cb(conn->handle, reason);
|
||||
}
|
||||
#endif
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
|
||||
client->filter_type == PROV) {
|
||||
bt_mesh_pb_gatt_close(conn);
|
||||
|
||||
@@ -38,6 +38,9 @@ extern "C" {
|
||||
#define DEVICE_NAME_SIZE (BLE_MESH_GAP_ADV_MAX_LEN - 2)
|
||||
#endif
|
||||
|
||||
typedef void (*proxy_server_connect_cb_t)(uint8_t conn_handle);
|
||||
typedef void (*proxy_server_disconnect_cb_t)(uint8_t conn_handle, uint8_t reason);
|
||||
|
||||
int bt_mesh_set_device_name(const char *name);
|
||||
|
||||
int bt_mesh_proxy_server_send(struct bt_mesh_conn *conn, uint8_t type,
|
||||
@@ -46,6 +49,9 @@ int bt_mesh_proxy_server_send(struct bt_mesh_conn *conn, uint8_t type,
|
||||
int bt_mesh_proxy_server_prov_enable(void);
|
||||
int bt_mesh_proxy_server_prov_disable(bool disconnect);
|
||||
|
||||
void bt_mesh_proxy_server_set_conn_cb(proxy_server_connect_cb_t cb);
|
||||
void bt_mesh_proxy_server_set_disconn_cb(proxy_server_disconnect_cb_t cb);
|
||||
|
||||
int bt_mesh_proxy_server_gatt_enable(void);
|
||||
int bt_mesh_proxy_server_gatt_disable(void);
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ config BT_BLUEDROID_MEM_DEBUG
|
||||
|
||||
config BT_CLASSIC_ENABLED
|
||||
bool "Classic Bluetooth"
|
||||
depends on BT_BLUEDROID_ENABLED && BT_CTRL_ESP32
|
||||
depends on BT_BLUEDROID_ENABLED && IDF_TARGET_ESP32
|
||||
default n
|
||||
help
|
||||
For now this option needs "SMP_ENABLE" to be set to yes
|
||||
@@ -1066,8 +1066,3 @@ config BT_BLE_42_FEATURES_SUPPORTED
|
||||
default n
|
||||
help
|
||||
This enables BLE 4.2 features.
|
||||
|
||||
config BT_RESERVE_DRAM
|
||||
hex
|
||||
default 0xdb5c if BT_ENABLED
|
||||
default 0
|
||||
|
||||
@@ -236,7 +236,7 @@ typedef enum {
|
||||
#define ESP_BT_GAP_MIN_INQ_LEN (0x01) /*!< Minimum inquiry duration, unit is 1.28s */
|
||||
#define ESP_BT_GAP_MAX_INQ_LEN (0x30) /*!< Maximum inquiry duration, unit is 1.28s */
|
||||
|
||||
/// A2DP state callback parameters
|
||||
/// GAP state callback parameters
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_BT_GAP_DISC_RES_EVT
|
||||
|
||||
@@ -60,6 +60,9 @@ typedef enum {
|
||||
#define ESP_HF_CLIENT_PEER_FEAT_ECC 0x80 /* Enhanced Call Control */
|
||||
#define ESP_HF_CLIENT_PEER_FEAT_EXTERR 0x100 /* Extended error codes */
|
||||
#define ESP_HF_CLIENT_PEER_FEAT_CODEC 0x200 /* Codec Negotiation */
|
||||
/* HFP 1.7+ */
|
||||
#define ESP_HF_CLIENT_PEER_FEAT_HF_IND 0x400 /* HF Indicators */
|
||||
#define ESP_HF_CLIENT_PEER_FEAT_ESCO_S4 0x800 /* eSCO S4 Setting Supported */
|
||||
|
||||
/* CHLD feature masks of AG */
|
||||
#define ESP_HF_CLIENT_CHLD_FEAT_REL 0x01 /* 0 Release waiting call or held calls */
|
||||
|
||||
@@ -491,14 +491,14 @@ void bta_ag_rfc_acp_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
|
||||
UINT16 lcid;
|
||||
int i;
|
||||
tBTA_AG_SCB *ag_scb, *other_scb;
|
||||
BD_ADDR dev_addr;
|
||||
BD_ADDR dev_addr = {0};
|
||||
int status;
|
||||
/* set role */
|
||||
p_scb->role = BTA_AG_ACP;
|
||||
APPL_TRACE_DEBUG ("bta_ag_rfc_acp_open: serv_handle0 = %d serv_handle1 = %d",
|
||||
p_scb->serv_handle[0], p_scb->serv_handle[1]);
|
||||
/* get bd addr of peer */
|
||||
if (PORT_SUCCESS != (status=PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid))) {
|
||||
if (PORT_SUCCESS != (status = PORT_CheckConnection(p_data->rfc.port_handle, FALSE, dev_addr, &lcid))) {
|
||||
APPL_TRACE_DEBUG ("bta_ag_rfc_acp_open error PORT_CheckConnection returned status %d", status);
|
||||
}
|
||||
/* Collision Handling */
|
||||
|
||||
@@ -47,9 +47,9 @@ void bta_ag_port_cback_1(UINT32 code, UINT16 port_handle);
|
||||
void bta_ag_port_cback_2(UINT32 code, UINT16 port_handle);
|
||||
void bta_ag_port_cback_3(UINT32 code, UINT16 port_handle);
|
||||
|
||||
void bta_ag_mgmt_cback_1(UINT32 code, UINT16 port_handle);
|
||||
void bta_ag_mgmt_cback_2(UINT32 code, UINT16 port_handle);
|
||||
void bta_ag_mgmt_cback_3(UINT32 code, UINT16 port_handle);
|
||||
void bta_ag_mgmt_cback_1(UINT32 code, UINT16 port_handle, void* data);
|
||||
void bta_ag_mgmt_cback_2(UINT32 code, UINT16 port_handle, void* data);
|
||||
void bta_ag_mgmt_cback_3(UINT32 code, UINT16 port_handle, void* data);
|
||||
|
||||
int bta_ag_data_cback_1(UINT16 port_handle, void *p_data, UINT16 len);
|
||||
int bta_ag_data_cback_2(UINT16 port_handle, void *p_data, UINT16 len);
|
||||
@@ -64,7 +64,8 @@ const tBTA_AG_PORT_CBACK bta_ag_port_cback_tbl[] =
|
||||
bta_ag_port_cback_3
|
||||
};
|
||||
|
||||
const tBTA_AG_PORT_CBACK bta_ag_mgmt_cback_tbl[] =
|
||||
typedef tPORT_MGMT_CALLBACK *tBTA_AG_MGMT_CBACK;
|
||||
const tBTA_AG_MGMT_CBACK bta_ag_mgmt_cback_tbl[] =
|
||||
{
|
||||
bta_ag_mgmt_cback_1,
|
||||
bta_ag_mgmt_cback_2,
|
||||
@@ -206,9 +207,9 @@ static int bta_ag_data_cback(UINT16 port_handle, void *p_data, UINT16 len, UINT1
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_ag_mgmt_cback_1(UINT32 code, UINT16 handle) {bta_ag_mgmt_cback(code, handle, 1);}
|
||||
void bta_ag_mgmt_cback_2(UINT32 code, UINT16 handle) {bta_ag_mgmt_cback(code, handle, 2);}
|
||||
void bta_ag_mgmt_cback_3(UINT32 code, UINT16 handle) {bta_ag_mgmt_cback(code, handle, 3);}
|
||||
void bta_ag_mgmt_cback_1(UINT32 code, UINT16 handle, void* data) {bta_ag_mgmt_cback(code, handle, 1);}
|
||||
void bta_ag_mgmt_cback_2(UINT32 code, UINT16 handle, void* data) {bta_ag_mgmt_cback(code, handle, 2);}
|
||||
void bta_ag_mgmt_cback_3(UINT32 code, UINT16 handle, void* data) {bta_ag_mgmt_cback(code, handle, 3);}
|
||||
void bta_ag_port_cback_1(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 1);}
|
||||
void bta_ag_port_cback_2(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 2);}
|
||||
void bta_ag_port_cback_3(UINT32 code, UINT16 handle) {bta_ag_port_cback(code, handle, 3);}
|
||||
|
||||
@@ -267,7 +267,7 @@ void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA *p_data)
|
||||
void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA *p_data)
|
||||
{
|
||||
UINT16 lcid;
|
||||
BD_ADDR dev_addr;
|
||||
BD_ADDR dev_addr = {0};
|
||||
int status;
|
||||
|
||||
/* set role */
|
||||
@@ -277,7 +277,7 @@ void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA *p_data)
|
||||
bta_hf_client_cb.scb.serv_handle, p_data->rfc.port_handle);
|
||||
|
||||
/* get bd addr of peer */
|
||||
if (PORT_SUCCESS != (status = PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid))) {
|
||||
if (PORT_SUCCESS != (status = PORT_CheckConnection(p_data->rfc.port_handle, FALSE, dev_addr, &lcid))) {
|
||||
APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open error PORT_CheckConnection returned status %d", status);
|
||||
}
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@ const tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = {
|
||||
bta_hf_client_st_closing
|
||||
};
|
||||
|
||||
const char *bta_hf_client_version = "1.6";
|
||||
const int bta_hf_client_version = HFP_HF_VERSION_1_7;
|
||||
|
||||
/* HF Client control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
@@ -387,7 +387,7 @@ static void bta_hf_client_api_enable(tBTA_HF_CLIENT_DATA *p_data)
|
||||
bta_hf_client_cb.p_cback = p_data->api_enable.p_cback;
|
||||
|
||||
/* check if mSBC support enabled */
|
||||
if (strcmp(bta_hf_client_version, "1.6") == 0) {
|
||||
if (bta_hf_client_version >= HFP_HF_VERSION_1_6) {
|
||||
bta_hf_client_cb.msbc_enabled = TRUE;
|
||||
} else{
|
||||
bta_hf_client_cb.msbc_enabled = FALSE;
|
||||
|
||||
@@ -70,7 +70,7 @@ static void bta_hf_client_port_cback(UINT32 code, UINT16 port_handle)
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_hf_client_mgmt_cback(UINT32 code, UINT16 port_handle)
|
||||
static void bta_hf_client_mgmt_cback(UINT32 code, UINT16 port_handle, void* data)
|
||||
{
|
||||
tBTA_HF_CLIENT_RFC *p_buf;
|
||||
UINT16 event;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "bta_hf_client_int.h"
|
||||
#include "bta/bta_hf_client_api.h"
|
||||
#include "common/bt_trace.h"
|
||||
#include <string.h>
|
||||
#include "common/bt_defs.h"
|
||||
@@ -34,6 +35,11 @@
|
||||
BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | \
|
||||
BTM_SCO_PKT_TYPES_MASK_NO_3_EV5)
|
||||
|
||||
#define BTA_HF_CLIENT_SCO_PARAM_IDX_CVSD 0 /* SCO setting for CVSD */
|
||||
#define BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S3 1 /* eSCO setting for CVSD S3 */
|
||||
#define BTA_HF_CLIENT_ESCO_PARAM_IDX_MSBC_T2 2 /* eSCO setting for mSBC T2 */
|
||||
#define BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S4 3 /* eSCO setting for CVSD S4 */
|
||||
|
||||
static const tBTM_ESCO_PARAMS bta_hf_client_esco_params[] = {
|
||||
/* SCO CVSD */
|
||||
{
|
||||
@@ -72,6 +78,19 @@ static const tBTM_ESCO_PARAMS bta_hf_client_esco_params[] = {
|
||||
BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
|
||||
BTM_SCO_PKT_TYPES_MASK_NO_3_EV5),
|
||||
.retrans_effort = BTM_ESCO_RETRANS_QUALITY,
|
||||
},
|
||||
/* HFP 1.7+ */
|
||||
/* ESCO CVSD S4 */
|
||||
{
|
||||
.rx_bw = BTM_64KBITS_RATE,
|
||||
.tx_bw = BTM_64KBITS_RATE,
|
||||
.max_latency = 12,
|
||||
.voice_contfmt = BTM_VOICE_SETTING_CVSD,
|
||||
/* Allow controller to use all types available except 5-slot EDR */
|
||||
.packet_types = (BTM_SCO_LINK_ALL_PKT_MASK |
|
||||
BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
|
||||
BTM_SCO_PKT_TYPES_MASK_NO_3_EV5),
|
||||
.retrans_effort = BTM_ESCO_RETRANS_QUALITY,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -178,18 +197,27 @@ static void bta_hf_client_sco_conn_rsp(tBTM_ESCO_CONN_REQ_EVT_DATA *p_data)
|
||||
{
|
||||
tBTM_ESCO_PARAMS resp;
|
||||
UINT8 hci_status = HCI_SUCCESS;
|
||||
UINT8 index = BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S3;
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE )
|
||||
tBTA_HFP_CODEC_INFO codec_info = {BTA_HFP_SCO_CODEC_PCM};
|
||||
UINT32 pcm_sample_rate;
|
||||
#endif
|
||||
APPL_TRACE_DEBUG("%s", __FUNCTION__);
|
||||
|
||||
APPL_TRACE_DEBUG("%s: negotiated codec = %d", __FUNCTION__, bta_hf_client_cb.scb.negotiated_codec);
|
||||
|
||||
if (bta_hf_client_cb.scb.sco_state == BTA_HF_CLIENT_SCO_LISTEN_ST) {
|
||||
if (p_data->link_type == BTM_LINK_TYPE_SCO) {
|
||||
resp = bta_hf_client_esco_params[0];
|
||||
index = BTA_HF_CLIENT_SCO_PARAM_IDX_CVSD;
|
||||
} else {
|
||||
resp = bta_hf_client_esco_params[bta_hf_client_cb.scb.negotiated_codec];
|
||||
if ((bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_CVSD) &&
|
||||
(bta_hf_client_cb.scb.features && BTA_HF_CLIENT_FEAT_ESCO_S4) &&
|
||||
(bta_hf_client_cb.scb.peer_features && BTA_HF_CLIENT_PEER_ESCO_S4)) {
|
||||
index = BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S4;
|
||||
} else if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_MSBC) {
|
||||
index = BTA_HF_CLIENT_ESCO_PARAM_IDX_MSBC_T2;
|
||||
}
|
||||
}
|
||||
resp = bta_hf_client_esco_params[index];
|
||||
|
||||
/* tell sys to stop av if any */
|
||||
bta_sys_sco_use(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
|
||||
@@ -350,6 +378,7 @@ static void bta_hf_client_sco_create(BOOLEAN is_orig)
|
||||
tBTM_STATUS status;
|
||||
UINT8 *p_bd_addr = NULL;
|
||||
tBTM_ESCO_PARAMS params;
|
||||
UINT8 index = BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S3;
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE )
|
||||
tBTM_SCO_ROUTE_TYPE sco_route;
|
||||
tBTA_HFP_CODEC_INFO codec_info = {BTA_HFP_SCO_CODEC_PCM};
|
||||
@@ -364,7 +393,15 @@ static void bta_hf_client_sco_create(BOOLEAN is_orig)
|
||||
return;
|
||||
}
|
||||
|
||||
params = bta_hf_client_esco_params[1];
|
||||
if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_CVSD) {
|
||||
if ((bta_hf_client_cb.scb.features && BTA_HF_CLIENT_FEAT_ESCO_S4) &&
|
||||
(bta_hf_client_cb.scb.peer_features && BTA_HF_CLIENT_PEER_ESCO_S4)) {
|
||||
index = BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S4;
|
||||
}
|
||||
} else if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_MSBC) {
|
||||
index = BTA_HF_CLIENT_ESCO_PARAM_IDX_MSBC_T2;
|
||||
}
|
||||
params = bta_hf_client_esco_params[index];
|
||||
|
||||
/* if initiating set current scb and peer bd addr */
|
||||
if (is_orig) {
|
||||
|
||||
@@ -114,7 +114,7 @@ BOOLEAN bta_hf_client_add_record(char *p_service_name, UINT8 scn,
|
||||
|
||||
/* add profile descriptor list */
|
||||
profile_uuid = UUID_SERVCLASS_HF_HANDSFREE;
|
||||
version = HFP_VERSION_1_6;
|
||||
version = HFP_VERSION_1_7;
|
||||
|
||||
result &= SDP_AddProfileDescriptorList(sdp_handle, profile_uuid, version);
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#define HFP_VERSION_1_1 0x0101
|
||||
#define HFP_VERSION_1_5 0x0105
|
||||
#define HFP_VERSION_1_6 0x0106
|
||||
#define HFP_VERSION_1_7 0x0107
|
||||
|
||||
/* RFCOMM MTU SIZE */
|
||||
#define BTA_HF_CLIENT_MTU 256
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
** Constants and data types
|
||||
*****************************************************************************/
|
||||
|
||||
/* Hands-Free unit(HF) version */
|
||||
#define HFP_HF_VERSION_1_6 0x0106 /* v1.6 */
|
||||
#define HFP_HF_VERSION_1_7 0x0107 /* v1.7 */
|
||||
|
||||
/* HFP peer (AG) features*/
|
||||
#define BTA_HF_CLIENT_PEER_FEAT_3WAY 0x00000001 /* Three-way calling */
|
||||
#define BTA_HF_CLIENT_PEER_FEAT_ECNR 0x00000002 /* Echo cancellation and/or noise reduction */
|
||||
@@ -44,6 +48,9 @@
|
||||
#define BTA_HF_CLIENT_PEER_ECC 0x00000080 /* Enhanced Call Control */
|
||||
#define BTA_HF_CLIENT_PEER_EXTERR 0x00000100 /* Extended error codes */
|
||||
#define BTA_HF_CLIENT_PEER_CODEC 0x00000200 /* Codec Negotiation */
|
||||
/* HFP 1.7+ */
|
||||
#define BTA_HF_CLIENT_PEER_HF_IND 0x00000400 /* HF Indicators */
|
||||
#define BTA_HF_CLIENT_PEER_ESCO_S4 0x00000800 /* eSCO S4 Setting Supported */
|
||||
|
||||
typedef UINT16 tBTA_HF_CLIENT_PEER_FEAT;
|
||||
|
||||
@@ -56,6 +63,8 @@ typedef UINT16 tBTA_HF_CLIENT_PEER_FEAT;
|
||||
#define BTA_HF_CLIENT_FEAT_ECS 0x00000020 /* Enhanced Call Status */
|
||||
#define BTA_HF_CLIENT_FEAT_ECC 0x00000040 /* Enhanced Call Control */
|
||||
#define BTA_HF_CLIENT_FEAT_CODEC 0x00000080 /* Codec Negotiation */
|
||||
#define BTA_HF_CLIENT_FEAT_HF_IND 0x00000100 /* HF indicators */
|
||||
#define BTA_HF_CLIENT_FEAT_ESCO_S4 0x00000200 /* eSCO S4 Setting Supported */
|
||||
|
||||
/* HFP HF extended call handling - masks not related to any spec */
|
||||
#define BTA_HF_CLIENT_CHLD_REL 0x00000001 /* 0 Release waiting call or held calls */
|
||||
|
||||
@@ -299,6 +299,7 @@ typedef struct {
|
||||
UINT32 port_status; /* PORT status */
|
||||
UINT32 handle; /* The connection handle */
|
||||
BOOLEAN async; /* FALSE, if local initiates disconnect */
|
||||
void * user_data; /* piggyback caller's private data */
|
||||
} tBTA_JV_RFCOMM_CLOSE;
|
||||
|
||||
/* data associated with BTA_JV_RFCOMM_START_EVT */
|
||||
|
||||
@@ -115,7 +115,7 @@ static void bta_jv_pm_state_change(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE
|
||||
tBTA_JV_STATUS bta_jv_set_pm_conn_state(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE new_st);
|
||||
|
||||
static int find_rfc_pcb(void *user_data, tBTA_JV_RFC_CB **cb, tBTA_JV_PCB **pcb);
|
||||
static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle);
|
||||
static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void* data);
|
||||
static void bta_jv_port_event_sr_cback(UINT32 code, UINT16 port_handle);
|
||||
static int bta_jv_port_data_co_cback(UINT16 port_handle, UINT8 *buf, UINT16 len, int type);
|
||||
/*******************************************************************************
|
||||
@@ -285,7 +285,7 @@ tBTA_JV_RFC_CB *bta_jv_rfc_port_to_cb(UINT16 port_handle)
|
||||
return p_cb;
|
||||
}
|
||||
|
||||
static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb)
|
||||
static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb, BOOLEAN close_server)
|
||||
{
|
||||
tBTA_JV_STATUS status = BTA_JV_SUCCESS;
|
||||
BOOLEAN remove_server = FALSE;
|
||||
@@ -295,7 +295,7 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pc
|
||||
tPORT_STATE port_state;
|
||||
UINT32 event_mask = BTA_JV_RFC_EV_MASK;
|
||||
UINT32 scn_num = (UINT32)p_cb->scn;
|
||||
tBTA_JV evt_data;
|
||||
tBTA_JV evt_data = {0};
|
||||
|
||||
if (!p_cb || !p_pcb) {
|
||||
APPL_TRACE_ERROR("bta_jv_free_sr_rfc_cb, p_cb or p_pcb cannot be null");
|
||||
@@ -373,10 +373,8 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pc
|
||||
p_pcb->handle = 0;
|
||||
p_cb->curr_sess--;
|
||||
|
||||
if ((p_cb->max_sess > 1) &&
|
||||
(p_cb->scn != 0) &&
|
||||
(p_cb->curr_sess == p_cb->max_sess - 1)) {
|
||||
|
||||
/* only needs a listening port when has a server */
|
||||
if (!close_server && (p_cb->max_sess > 1) && (p_cb->scn != 0)) {
|
||||
for (i = 0; i < p_cb->max_sess; i++) {
|
||||
if (p_cb->rfc_hdl[i] != 0) {
|
||||
p_pcb = &bta_jv_cb.port_cb[p_cb->rfc_hdl[i] - 1];
|
||||
@@ -386,8 +384,8 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pc
|
||||
used++;
|
||||
}
|
||||
}
|
||||
APPL_TRACE_DEBUG("%s max_sess=%d used:%d curr_sess:%d, listen:%d si:%d",
|
||||
__func__, p_cb->max_sess, used, p_cb->curr_sess, listen, si);
|
||||
APPL_TRACE_DEBUG("%s max_sess=%d used:%d curr_sess:%d, listen:%d si:%d", __func__, p_cb->max_sess, used,
|
||||
p_cb->curr_sess, listen, si);
|
||||
if (used < p_cb->max_sess &&
|
||||
listen == 0 &&
|
||||
0 <= si &&
|
||||
@@ -430,9 +428,6 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pc
|
||||
p_cb->handle = 0;
|
||||
p_cb->curr_sess = -1;
|
||||
}
|
||||
if (remove_server) {
|
||||
bta_jv_free_sec_id(&p_cb->sec_id);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@@ -592,8 +587,8 @@ static tBTA_JV_PM_CB *bta_jv_alloc_set_pm_profile_cb(UINT32 jv_handle, tBTA_JV_P
|
||||
for (j = 0; j < BTA_JV_MAX_RFC_CONN; j++) {
|
||||
if (jv_handle == bta_jv_cb.port_cb[j].handle) {
|
||||
pp_cb = &bta_jv_cb.port_cb[j].p_pm_cb;
|
||||
if (PORT_SUCCESS != PORT_CheckConnection(
|
||||
bta_jv_cb.port_cb[j].port_handle, peer_bd_addr, NULL)) {
|
||||
if (PORT_SUCCESS !=
|
||||
PORT_CheckConnection(bta_jv_cb.port_cb[j].port_handle, FALSE, peer_bd_addr, NULL)) {
|
||||
i = BTA_JV_PM_MAX_NUM;
|
||||
}
|
||||
break;
|
||||
@@ -1205,7 +1200,7 @@ void bta_jv_delete_record(tBTA_JV_MSG *p_data)
|
||||
static void bta_jv_l2cap_client_cback(UINT16 gap_handle, UINT16 event)
|
||||
{
|
||||
tBTA_JV_L2C_CB *p_cb = &bta_jv_cb.l2c_cb[gap_handle];
|
||||
tBTA_JV evt_data;
|
||||
tBTA_JV evt_data = {0};
|
||||
|
||||
if (gap_handle >= BTA_JV_MAX_L2C_CONN && !p_cb->p_cback) {
|
||||
return;
|
||||
@@ -1360,7 +1355,7 @@ void bta_jv_l2cap_close(tBTA_JV_MSG *p_data)
|
||||
static void bta_jv_l2cap_server_cback(UINT16 gap_handle, UINT16 event)
|
||||
{
|
||||
tBTA_JV_L2C_CB *p_cb = &bta_jv_cb.l2c_cb[gap_handle];
|
||||
tBTA_JV evt_data;
|
||||
tBTA_JV evt_data = {0};
|
||||
tBTA_JV_L2CAP_CBACK *p_cback;
|
||||
void *user_data;
|
||||
|
||||
@@ -1666,12 +1661,12 @@ static int bta_jv_port_data_co_cback(UINT16 port_handle, UINT8 *buf, UINT16 len,
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle)
|
||||
static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle, void* data)
|
||||
{
|
||||
tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle);
|
||||
tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
|
||||
tBTA_JV evt_data;
|
||||
BD_ADDR rem_bda;
|
||||
tBTA_JV evt_data = {0};
|
||||
BD_ADDR rem_bda = {0};
|
||||
UINT16 lcid;
|
||||
tBTA_JV_RFCOMM_CBACK *p_cback; /* the callback function */
|
||||
|
||||
@@ -1683,7 +1678,7 @@ static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle)
|
||||
APPL_TRACE_DEBUG( "bta_jv_port_mgmt_cl_cback code=%d port_handle:%d handle:%d",
|
||||
code, port_handle, p_cb->handle);
|
||||
|
||||
PORT_CheckConnection(port_handle, rem_bda, &lcid);
|
||||
PORT_CheckConnection(port_handle, FALSE, rem_bda, &lcid);
|
||||
|
||||
if (code == PORT_SUCCESS) {
|
||||
evt_data.rfc_open.handle = p_pcb->handle;
|
||||
@@ -1722,7 +1717,7 @@ static void bta_jv_port_event_cl_cback(UINT32 code, UINT16 port_handle)
|
||||
{
|
||||
tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle);
|
||||
tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
|
||||
tBTA_JV evt_data;
|
||||
tBTA_JV evt_data = {0};
|
||||
|
||||
APPL_TRACE_DEBUG( "bta_jv_port_event_cl_cback:%d", port_handle);
|
||||
if (NULL == p_cb || NULL == p_cb->p_cback) {
|
||||
@@ -1863,7 +1858,7 @@ void bta_jv_rfcomm_close(tBTA_JV_MSG *p_data)
|
||||
tBTA_JV_API_RFCOMM_CLOSE *cc = &(p_data->rfcomm_close);
|
||||
tBTA_JV_RFC_CB *p_cb = NULL;
|
||||
tBTA_JV_PCB *p_pcb = NULL;
|
||||
tBTA_JV evt_data;
|
||||
tBTA_JV evt_data = {0};
|
||||
APPL_TRACE_DEBUG("%s, rfc handle:%d",__func__, cc->handle);
|
||||
if (!cc->handle) {
|
||||
APPL_TRACE_ERROR("%s, rfc handle is null", __func__);
|
||||
@@ -1887,7 +1882,7 @@ void bta_jv_rfcomm_close(tBTA_JV_MSG *p_data)
|
||||
}
|
||||
cc->p_cback(BTA_JV_RFCOMM_CLOSE_EVT, (tBTA_JV *)&evt_data, user_data);
|
||||
}
|
||||
bta_jv_free_rfc_cb(p_cb, p_pcb);
|
||||
bta_jv_free_rfc_cb(p_cb, p_pcb, FALSE);
|
||||
APPL_TRACE_DEBUG("%s: sec id in use:%d, rfc_cb in use:%d",__func__,
|
||||
get_sec_id_used(), get_rfc_cb_used());
|
||||
}
|
||||
@@ -1930,39 +1925,89 @@ static UINT8 __attribute__((unused)) bta_jv_get_num_rfc_listen(tBTA_JV_RFC_CB *p
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle)
|
||||
static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void *data)
|
||||
{
|
||||
tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
|
||||
tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle);
|
||||
tBTA_JV evt_data;
|
||||
BD_ADDR rem_bda;
|
||||
tBTA_JV evt_data = {0};
|
||||
BD_ADDR rem_bda = {0};
|
||||
UINT16 lcid;
|
||||
tPORT_MGMT_SR_CALLBACK_ARG *p_mgmt_cb_arg = (tPORT_MGMT_SR_CALLBACK_ARG *)data;
|
||||
void *user_data = NULL;
|
||||
void *new_user_data = NULL;
|
||||
int status;
|
||||
int failed = TRUE;
|
||||
|
||||
// APPL_TRACE_DEBUG("bta_jv_port_mgmt_sr_cback, code:0x%x, port_handle:%d", code, (uint16_t)port_handle);
|
||||
if (NULL == p_cb || NULL == p_cb->p_cback) {
|
||||
// APPL_TRACE_ERROR("bta_jv_port_mgmt_sr_cback, p_cb:%p, p_cb->p_cback%p",
|
||||
// p_cb, p_cb ? p_cb->p_cback : NULL);
|
||||
return;
|
||||
}
|
||||
void *user_data = p_pcb->user_data;
|
||||
user_data = p_pcb->user_data;
|
||||
// APPL_TRACE_DEBUG( "bta_jv_port_mgmt_sr_cback code=%p port_handle:0x%x handle:0x%x, p_pcb:%p, user:%p",
|
||||
// code, port_handle, p_cb->handle, p_pcb, p_pcb->user_data);
|
||||
|
||||
PORT_CheckConnection(port_handle, rem_bda, &lcid);
|
||||
int failed = TRUE;
|
||||
if (p_mgmt_cb_arg) {
|
||||
if ((status = PORT_CheckConnection(port_handle, p_mgmt_cb_arg->ignore_rfc_state, rem_bda, &lcid)) !=
|
||||
PORT_SUCCESS) {
|
||||
APPL_TRACE_WARNING("PORT_CheckConnection status:%d", status);
|
||||
}
|
||||
} else {
|
||||
PORT_CheckConnection(port_handle, FALSE, rem_bda, &lcid);
|
||||
}
|
||||
|
||||
if (code == PORT_SUCCESS) {
|
||||
failed = FALSE;
|
||||
/* accept the connection defaulted */
|
||||
if (p_mgmt_cb_arg) {
|
||||
p_mgmt_cb_arg->accept = TRUE;
|
||||
}
|
||||
evt_data.rfc_srv_open.handle = p_pcb->handle;
|
||||
evt_data.rfc_srv_open.status = BTA_JV_SUCCESS;
|
||||
bdcpy(evt_data.rfc_srv_open.rem_bda, rem_bda);
|
||||
tBTA_JV_PCB *p_pcb_new_listen = bta_jv_add_rfc_port(p_cb, p_pcb);
|
||||
if (p_pcb_new_listen) {
|
||||
evt_data.rfc_srv_open.new_listen_handle = p_pcb_new_listen->handle;
|
||||
p_pcb_new_listen->user_data = p_cb->p_cback(BTA_JV_RFCOMM_SRV_OPEN_EVT, &evt_data, user_data);
|
||||
APPL_TRACE_DEBUG("PORT_SUCCESS: curr_sess:%d, max_sess:%d", p_cb->curr_sess, p_cb->max_sess);
|
||||
failed = FALSE;
|
||||
new_user_data = p_cb->p_cback(BTA_JV_RFCOMM_SRV_OPEN_EVT, &evt_data, user_data);
|
||||
if (new_user_data) {
|
||||
p_pcb_new_listen->user_data = new_user_data;
|
||||
APPL_TRACE_DEBUG("PORT_SUCCESS: curr_sess:%d, max_sess:%d", p_cb->curr_sess,
|
||||
p_cb->max_sess);
|
||||
} else {
|
||||
/**
|
||||
* new_user_data is NULL, which means the upper layer runs out of slot source.
|
||||
* Tells the caller to reject this connection.
|
||||
*/
|
||||
APPL_TRACE_ERROR("create new listen port, but upper layer reject connection");
|
||||
p_pcb_new_listen->user_data = NULL;
|
||||
p_pcb->state = BTA_JV_ST_SR_LISTEN;
|
||||
bta_jv_free_rfc_cb(p_cb, p_pcb_new_listen, FALSE);
|
||||
if (p_mgmt_cb_arg) {
|
||||
p_mgmt_cb_arg->accept = FALSE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
evt_data.rfc_srv_open.new_listen_handle = 0;
|
||||
new_user_data = p_cb->p_cback(BTA_JV_RFCOMM_SRV_OPEN_EVT, &evt_data, user_data);
|
||||
if (new_user_data) {
|
||||
APPL_TRACE_DEBUG("PORT_SUCCESS: curr_sess:%d, max_sess:%d", p_cb->curr_sess,
|
||||
p_cb->max_sess);
|
||||
} else {
|
||||
/**
|
||||
* new_user_data is NULL, which means the upper layer runs out of slot source.
|
||||
* Tells the caller to reject this connection.
|
||||
*/
|
||||
APPL_TRACE_ERROR("no listen port, and upper layer reject connection");
|
||||
p_pcb->state = BTA_JV_ST_SR_LISTEN;
|
||||
if (p_mgmt_cb_arg) {
|
||||
p_mgmt_cb_arg->accept = FALSE;
|
||||
}
|
||||
}
|
||||
APPL_TRACE_ERROR("bta_jv_add_rfc_port failed to create new listen port");
|
||||
}
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
evt_data.rfc_close.handle = p_pcb->handle;
|
||||
evt_data.rfc_close.status = BTA_JV_FAILURE;
|
||||
@@ -1999,7 +2044,7 @@ static void bta_jv_port_event_sr_cback(UINT32 code, UINT16 port_handle)
|
||||
{
|
||||
tBTA_JV_PCB *p_pcb = bta_jv_rfc_port_to_pcb(port_handle);
|
||||
tBTA_JV_RFC_CB *p_cb = bta_jv_rfc_port_to_cb(port_handle);
|
||||
tBTA_JV evt_data;
|
||||
tBTA_JV evt_data = {0};
|
||||
|
||||
if (NULL == p_cb || NULL == p_cb->p_cback) {
|
||||
return;
|
||||
@@ -2067,6 +2112,7 @@ static tBTA_JV_PCB *bta_jv_add_rfc_port(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb
|
||||
}
|
||||
}
|
||||
|
||||
p_pcb = NULL;
|
||||
APPL_TRACE_DEBUG("bta_jv_add_rfc_port max_sess=%d used:%d curr_sess:%d, listen:%d si:%d",
|
||||
p_cb->max_sess, used, p_cb->curr_sess, listen, si);
|
||||
if (used < p_cb->max_sess && listen == 1 && si) {
|
||||
@@ -2094,7 +2140,6 @@ static tBTA_JV_PCB *bta_jv_add_rfc_port(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb
|
||||
}
|
||||
} else {
|
||||
/* avoid p_pcb always points to the last element of rfc_hdl */
|
||||
p_pcb = p_pcb_open;
|
||||
APPL_TRACE_ERROR("bta_jv_add_rfc_port, cannot create new rfc listen port");
|
||||
}
|
||||
}
|
||||
@@ -2214,7 +2259,7 @@ void bta_jv_rfcomm_stop_server(tBTA_JV_MSG *p_data)
|
||||
}
|
||||
APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: p_pcb:%p, p_pcb->port_handle:%d",
|
||||
p_pcb, p_pcb->port_handle);
|
||||
bta_jv_free_rfc_cb(p_cb, p_pcb);
|
||||
bta_jv_free_rfc_cb(p_cb, p_pcb, TRUE);
|
||||
APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: sec id in use:%d, rfc_cb in use:%d",
|
||||
get_sec_id_used(), get_rfc_cb_used());
|
||||
}
|
||||
@@ -2750,7 +2795,7 @@ static void fcchan_conn_chng_cbk(UINT16 chan, BD_ADDR bd_addr, BOOLEAN connected
|
||||
|
||||
static void fcchan_data_cbk(UINT16 chan, BD_ADDR bd_addr, BT_HDR *p_buf)
|
||||
{
|
||||
tBTA_JV evt_data;
|
||||
tBTA_JV evt_data = {0};
|
||||
// tBTA_JV evt_open;
|
||||
struct fc_channel *tc;
|
||||
struct fc_client *t = NULL;
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
@@ -33,7 +25,7 @@
|
||||
#if BTC_AV_INCLUDED
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN data_channel_open;
|
||||
BOOLEAN data_channel_open; /* used only by A2DP sink */
|
||||
UINT8 a2dp_cmd_pending; /* we can have max one command pending */
|
||||
} tBTC_AA_CTRL_CB;
|
||||
|
||||
@@ -83,7 +75,9 @@ static void btc_a2dp_datapath_open(void)
|
||||
btc_a2dp_source_encoder_update();
|
||||
}
|
||||
#endif
|
||||
#if (BTC_AV_SINK_INCLUDED == TRUE)
|
||||
btc_aa_ctrl_cb.data_channel_open = TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOLEAN btc_a2dp_control_get_datachnl_stat(void)
|
||||
@@ -96,22 +90,6 @@ void btc_a2dp_control_set_datachnl_stat(BOOLEAN open)
|
||||
btc_aa_ctrl_cb.data_channel_open = open;
|
||||
}
|
||||
|
||||
static void btc_a2dp_dispatch_datapath_evt(uint32_t dp_evt)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_DATAPATH_CTRL_EVT;
|
||||
|
||||
btc_av_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_av_args_t));
|
||||
arg.dp_evt = dp_evt;
|
||||
|
||||
/* Switch to BTC context */
|
||||
APPL_TRACE_DEBUG("%s sig %u act %u, dp_evt %u\n", __func__, msg.sig, msg.act, arg.dp_evt);
|
||||
btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
|
||||
}
|
||||
|
||||
void btc_a2dp_control_media_ctrl(esp_a2d_media_ctrl_t ctrl)
|
||||
{
|
||||
APPL_TRACE_DEBUG("BTC MEDIA (A2DP-DATA) EVENT %u", ctrl);
|
||||
@@ -146,17 +124,14 @@ void btc_a2dp_control_media_ctrl(esp_a2d_media_ctrl_t ctrl)
|
||||
break;
|
||||
case ESP_A2D_MEDIA_CTRL_START:
|
||||
if (btc_av_stream_ready() == TRUE ) {
|
||||
/* post start event and wait for audio path to open */
|
||||
/* post start event */
|
||||
btc_dispatch_sm_event(BTC_AV_START_STREAM_REQ_EVT, NULL, 0);
|
||||
|
||||
btc_a2dp_dispatch_datapath_evt(BTC_AV_DATAPATH_OPEN_EVT);
|
||||
#if (BTC_AV_SINK_INCLUDED == TRUE)
|
||||
if (btc_av_get_peer_sep() == AVDT_TSEP_SRC && btc_av_get_service_id() == BTA_A2DP_SINK_SERVICE_ID) {
|
||||
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
} else if (btc_av_stream_started_ready()) {
|
||||
btc_a2dp_dispatch_datapath_evt(BTC_AV_DATAPATH_OPEN_EVT);
|
||||
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS);
|
||||
} else {
|
||||
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
|
||||
|
||||
@@ -110,12 +110,18 @@ typedef struct {
|
||||
UINT32 sample_rate;
|
||||
} tBTC_A2DP_SINK_CB;
|
||||
|
||||
typedef struct {
|
||||
uint16_t expected_seq_num;
|
||||
bool seq_num_recount;
|
||||
} a2dp_sink_media_pkt_seq_num_t;
|
||||
|
||||
typedef struct {
|
||||
tBTC_A2DP_SINK_CB btc_aa_snk_cb;
|
||||
osi_thread_t *btc_aa_snk_task_hdl;
|
||||
OI_CODEC_SBC_DECODER_CONTEXT context;
|
||||
OI_UINT32 contextData[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)];
|
||||
OI_INT16 pcmData[15 * SBC_MAX_SAMPLES_PER_FRAME * SBC_MAX_CHANNELS];
|
||||
a2dp_sink_media_pkt_seq_num_t media_pkt_seq_num;
|
||||
} a2dp_sink_local_param_t;
|
||||
|
||||
static void btc_a2dp_sink_thread_init(UNUSED_ATTR void *context);
|
||||
@@ -319,6 +325,10 @@ static BOOLEAN btc_a2dp_sink_clear_track(void)
|
||||
void btc_a2dp_sink_set_rx_flush(BOOLEAN enable)
|
||||
{
|
||||
APPL_TRACE_EVENT("## DROP RX %d ##\n", enable);
|
||||
if (enable == FALSE) {
|
||||
a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num = 0x1;
|
||||
a2dp_sink_local_param.media_pkt_seq_num.seq_num_recount = true;
|
||||
}
|
||||
a2dp_sink_local_param.btc_aa_snk_cb.rx_flush = enable;
|
||||
}
|
||||
|
||||
@@ -549,6 +559,18 @@ static void btc_a2dp_sink_handle_inc_media(tBT_SBC_HDR *p_msg)
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_msg->layer_specific != a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num) {
|
||||
/* Because the sequence number of some devices is not recounted */
|
||||
if (!a2dp_sink_local_param.media_pkt_seq_num.seq_num_recount ||
|
||||
a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num != 0x1) {
|
||||
APPL_TRACE_WARNING("Sequence numbers error, recv:0x%x, expect:0x%x, recount:0x%x",
|
||||
p_msg->layer_specific, a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num,
|
||||
a2dp_sink_local_param.media_pkt_seq_num.seq_num_recount);
|
||||
}
|
||||
}
|
||||
a2dp_sink_local_param.media_pkt_seq_num.expected_seq_num = p_msg->layer_specific + 1;
|
||||
a2dp_sink_local_param.media_pkt_seq_num.seq_num_recount = false;
|
||||
|
||||
APPL_TRACE_DEBUG("Number of sbc frames %d, frame_len %d\n", num_sbc_frames, sbc_frame_len);
|
||||
|
||||
for (count = 0; count < num_sbc_frames && sbc_frame_len != 0; count ++) {
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
**
|
||||
@@ -1579,7 +1571,6 @@ static void btc_a2dp_source_thread_init(UNUSED_ATTR void *context)
|
||||
|
||||
static void btc_a2dp_source_thread_cleanup(UNUSED_ATTR void *context)
|
||||
{
|
||||
btc_a2dp_control_set_datachnl_stat(FALSE);
|
||||
/* Clear media task flag */
|
||||
btc_a2dp_source_state = BTC_A2DP_SOURCE_STATE_OFF;
|
||||
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
@@ -681,6 +673,9 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data)
|
||||
/* pending start flag will be cleared when exit current state */
|
||||
}
|
||||
#endif /* BTC_AV_SRC_INCLUDED */
|
||||
/* wait for audio path to open */
|
||||
btc_a2dp_control_datapath_ctrl(BTC_AV_DATAPATH_OPEN_EVT);
|
||||
|
||||
btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_STARTED);
|
||||
|
||||
} break;
|
||||
@@ -1509,10 +1504,6 @@ void btc_a2dp_call_handler(btc_msg_t *msg)
|
||||
btc_a2dp_control_media_ctrl(arg->ctrl);
|
||||
break;
|
||||
}
|
||||
case BTC_AV_DATAPATH_CTRL_EVT: {
|
||||
btc_a2dp_control_datapath_ctrl(arg->dp_evt);
|
||||
break;
|
||||
}
|
||||
case BTC_AV_CONNECT_REQ_EVT:
|
||||
btc_sm_dispatch(btc_av_cb.sm_handle, msg->act, (char *)msg->arg);
|
||||
break;
|
||||
|
||||
@@ -51,13 +51,13 @@
|
||||
#endif
|
||||
|
||||
#ifndef BTC_HF_CLIENT_FEATURES
|
||||
#define BTC_HF_CLIENT_FEATURES ( BTA_HF_CLIENT_FEAT_ECNR | \
|
||||
BTA_HF_CLIENT_FEAT_3WAY | \
|
||||
BTA_HF_CLIENT_FEAT_CLI | \
|
||||
BTA_HF_CLIENT_FEAT_VREC | \
|
||||
BTA_HF_CLIENT_FEAT_VOL | \
|
||||
BTA_HF_CLIENT_FEAT_ECS | \
|
||||
BTA_HF_CLIENT_FEAT_ECC | \
|
||||
#define BTC_HF_CLIENT_FEATURES ( BTA_HF_CLIENT_FEAT_ECNR | \
|
||||
BTA_HF_CLIENT_FEAT_3WAY | \
|
||||
BTA_HF_CLIENT_FEAT_CLI | \
|
||||
BTA_HF_CLIENT_FEAT_VREC | \
|
||||
BTA_HF_CLIENT_FEAT_VOL | \
|
||||
BTA_HF_CLIENT_FEAT_ECS | \
|
||||
BTA_HF_CLIENT_FEAT_ECC | \
|
||||
BTA_HF_CLIENT_FEAT_CODEC)
|
||||
#endif
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
/************************************************************************************
|
||||
** Static variables
|
||||
************************************************************************************/
|
||||
const char *btc_hf_client_version = "1.6";
|
||||
const int btc_hf_client_version = HFP_HF_VERSION_1_7;
|
||||
|
||||
#if HFP_DYNAMIC_MEMORY == FALSE
|
||||
static hf_client_local_param_t hf_client_local_param;
|
||||
@@ -200,7 +200,7 @@ static bt_status_t connect_int( bt_bdaddr_t *bd_addr, uint16_t uuid )
|
||||
|
||||
bt_status_t btc_hf_client_connect( bt_bdaddr_t *bd_addr )
|
||||
{
|
||||
BTC_TRACE_EVENT("HFP Client version is %s", btc_hf_client_version);
|
||||
BTC_TRACE_EVENT("HFP Client version is 0x%04x", btc_hf_client_version);
|
||||
CHECK_HF_CLIENT_INIT();
|
||||
return btc_queue_connect(UUID_SERVCLASS_HF_HANDSFREE, bd_addr, connect_int);
|
||||
}
|
||||
@@ -690,33 +690,36 @@ bt_status_t btc_hf_client_execute_service(BOOLEAN b_enable)
|
||||
{
|
||||
BTC_TRACE_EVENT("%s enable:%d", __FUNCTION__, b_enable);
|
||||
|
||||
if (b_enable)
|
||||
{
|
||||
/* Enable and register with BTA-HFClient */
|
||||
BTA_HfClientEnable(bte_hf_client_evt);
|
||||
if (strcmp(btc_hf_client_version, "1.6") == 0)
|
||||
{
|
||||
BTC_TRACE_EVENT("Support Codec Nego. %d ", BTC_HF_CLIENT_FEATURES);
|
||||
BTA_HfClientRegister(BTC_HF_CLIENT_SECURITY, BTC_HF_CLIENT_FEATURES,
|
||||
BTC_HF_CLIENT_SERVICE_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
BTC_TRACE_EVENT("No Codec Nego Supported");
|
||||
hf_client_local_param.btc_hf_client_features = BTC_HF_CLIENT_FEATURES;
|
||||
hf_client_local_param.btc_hf_client_features = hf_client_local_param.btc_hf_client_features & (~BTA_HF_CLIENT_FEAT_CODEC);
|
||||
BTC_TRACE_EVENT("hf_client_local_param.btc_hf_client_features is %d", hf_client_local_param.btc_hf_client_features);
|
||||
BTA_HfClientRegister(BTC_HF_CLIENT_SECURITY, hf_client_local_param.btc_hf_client_features,
|
||||
BTC_HF_CLIENT_SERVICE_NAME);
|
||||
}
|
||||
if (b_enable)
|
||||
{
|
||||
/* Enable and register with BTA-HFClient */
|
||||
BTA_HfClientEnable(bte_hf_client_evt);
|
||||
hf_client_local_param.btc_hf_client_features = BTC_HF_CLIENT_FEATURES;
|
||||
if (btc_hf_client_version >= HFP_HF_VERSION_1_7)
|
||||
{
|
||||
hf_client_local_param.btc_hf_client_features |= BTA_HF_CLIENT_FEAT_ESCO_S4;
|
||||
BTC_TRACE_EVENT("eSCO S4 Setting Supported");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
BTA_HfClientDeregister(hf_client_local_param.btc_hf_client_cb.handle);
|
||||
BTA_HfClientDisable();
|
||||
}
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
else if (btc_hf_client_version >= HFP_HF_VERSION_1_6)
|
||||
{
|
||||
BTC_TRACE_EVENT("No eSCO S4 Setting Supported");
|
||||
}
|
||||
else
|
||||
{
|
||||
BTC_TRACE_EVENT("No Codec Nego Supported");
|
||||
hf_client_local_param.btc_hf_client_features = hf_client_local_param.btc_hf_client_features & (~BTA_HF_CLIENT_FEAT_CODEC);
|
||||
}
|
||||
BTC_TRACE_EVENT("hf_client_local_param.btc_hf_client_features is %d", hf_client_local_param.btc_hf_client_features);
|
||||
BTA_HfClientRegister(BTC_HF_CLIENT_SECURITY, hf_client_local_param.btc_hf_client_features,
|
||||
BTC_HF_CLIENT_SERVICE_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
BTA_HfClientDeregister(hf_client_local_param.btc_hf_client_cb.handle);
|
||||
BTA_HfClientDisable();
|
||||
}
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void process_ind_evt(tBTA_HF_CLIENT_IND *ind)
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -79,7 +71,6 @@ typedef enum {
|
||||
BTC_AV_SRC_API_REG_DATA_CB_EVT,
|
||||
#endif /* BTC_AV_SRC_INCLUDED */
|
||||
BTC_AV_API_MEDIA_CTRL_EVT,
|
||||
BTC_AV_DATAPATH_CTRL_EVT,
|
||||
} btc_av_act_t;
|
||||
|
||||
/* btc_av_args_t */
|
||||
@@ -104,8 +95,6 @@ typedef union {
|
||||
#endif /* BTC_AV_SRC_INCLUDED */
|
||||
// BTC_AV_API_MEDIA_CTRL_EVT
|
||||
esp_a2d_media_ctrl_t ctrl;
|
||||
// BTC_AV_DATAPATH_CTRL_EVT
|
||||
uint32_t dp_evt;
|
||||
} btc_av_args_t;
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -55,8 +47,9 @@ typedef struct {
|
||||
} slot_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t serial;
|
||||
bool connected;
|
||||
bool is_server;
|
||||
uint8_t serial;
|
||||
uint8_t scn;
|
||||
uint8_t max_session;
|
||||
uint32_t id;
|
||||
@@ -137,29 +130,39 @@ static spp_slot_t *spp_malloc_slot(void)
|
||||
(*slot)->sdp_handle = 0;
|
||||
(*slot)->rfc_handle = 0;
|
||||
(*slot)->rfc_port_handle = 0;
|
||||
(*slot)->connected = FALSE;
|
||||
(*slot)->fd = -1;
|
||||
(*slot)->connected = false;
|
||||
(*slot)->is_server = false;
|
||||
(*slot)->write_data = NULL;
|
||||
(*slot)->close_alarm = NULL;
|
||||
/* clear the old event bits */
|
||||
if (spp_local_param.tx_event_group) {
|
||||
xEventGroupClearBits(spp_local_param.tx_event_group, SLOT_WRITE_BIT(i) | SLOT_CLOSE_BIT(i));
|
||||
}
|
||||
|
||||
if (init_slot_data(&(*slot)->rx, QUEUE_SIZE_MAX)) {
|
||||
BTC_TRACE_ERROR("%s unable to malloc rx queue!", __func__);
|
||||
err_no = 1;
|
||||
break;
|
||||
goto err;
|
||||
}
|
||||
if (init_slot_data(&(*slot)->tx, SLOT_TX_QUEUE_SIZE)) {
|
||||
BTC_TRACE_ERROR("%s unable to malloc tx queue!", __func__);
|
||||
err_no = 2;
|
||||
break;
|
||||
goto err;
|
||||
}
|
||||
if (spp_local_param.spp_mode == ESP_SPP_MODE_VFS) {
|
||||
if (esp_vfs_register_fd(spp_local_param.spp_vfs_id, &(*slot)->fd) != ESP_OK) {
|
||||
BTC_TRACE_ERROR("%s unable to register fd!", __func__);
|
||||
err_no = 3;
|
||||
break;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return (*slot);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
err:
|
||||
switch (err_no) {
|
||||
case 3:
|
||||
free_slot_data(&(*slot)->tx);
|
||||
@@ -177,9 +180,11 @@ static spp_slot_t *spp_malloc_slot(void)
|
||||
|
||||
static spp_slot_t *spp_find_slot_by_id(uint32_t id)
|
||||
{
|
||||
spp_slot_t *slot = NULL;
|
||||
for (size_t i = 1; i <= MAX_RFC_PORTS; i++) {
|
||||
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->id == id) {
|
||||
return spp_local_param.spp_slots[i];
|
||||
slot = spp_local_param.spp_slots[i];
|
||||
if (slot != NULL && slot->id == id) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@@ -187,9 +192,11 @@ static spp_slot_t *spp_find_slot_by_id(uint32_t id)
|
||||
|
||||
static spp_slot_t *spp_find_slot_by_handle(uint32_t handle)
|
||||
{
|
||||
spp_slot_t *slot = NULL;
|
||||
for (size_t i = 1; i <= MAX_RFC_PORTS; i++) {
|
||||
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->rfc_handle == handle) {
|
||||
return spp_local_param.spp_slots[i];
|
||||
slot = spp_local_param.spp_slots[i];
|
||||
if (slot != NULL && slot->rfc_handle == handle) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@@ -197,9 +204,11 @@ static spp_slot_t *spp_find_slot_by_handle(uint32_t handle)
|
||||
|
||||
static spp_slot_t *spp_find_slot_by_fd(int fd)
|
||||
{
|
||||
spp_slot_t *slot = NULL;
|
||||
for (size_t i = 1; i <= MAX_RFC_PORTS; i++) {
|
||||
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->fd == fd) {
|
||||
return spp_local_param.spp_slots[i];
|
||||
slot = spp_local_param.spp_slots[i];
|
||||
if (slot != NULL && slot->fd == fd) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@@ -207,9 +216,11 @@ static spp_slot_t *spp_find_slot_by_fd(int fd)
|
||||
|
||||
static spp_slot_t *spp_find_slot_by_scn(uint32_t scn)
|
||||
{
|
||||
spp_slot_t *slot = NULL;
|
||||
for (size_t i = 1; i <= MAX_RFC_PORTS; i++) {
|
||||
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->scn == (uint8_t)scn) {
|
||||
return spp_local_param.spp_slots[i];
|
||||
slot = spp_local_param.spp_slots[i];
|
||||
if (slot != NULL && slot->is_server && slot->scn == (uint8_t)scn) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@@ -277,9 +288,9 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u
|
||||
bt_status_t status;
|
||||
btc_msg_t msg;
|
||||
void *new_user_data = NULL;
|
||||
|
||||
uint32_t id = (uintptr_t)user_data;
|
||||
uint32_t id = (uintptr_t)user_data, id_temp = 0;
|
||||
spp_slot_t *slot = NULL, *slot_new = NULL;
|
||||
|
||||
if (!is_spp_init()) {
|
||||
BTC_TRACE_WARNING("%s SPP have been deinit, incoming events ignore!\n", __func__);
|
||||
return new_user_data;
|
||||
@@ -289,7 +300,7 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u
|
||||
case BTA_JV_RFCOMM_START_EVT:
|
||||
slot = spp_find_slot_by_id(id);
|
||||
if (!slot) {
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
p_data->rfc_start.status = ESP_SPP_NO_CONNECTION;
|
||||
break;
|
||||
}
|
||||
@@ -299,46 +310,70 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u
|
||||
case BTA_JV_RFCOMM_SRV_OPEN_EVT:
|
||||
slot = p_data->rfc_srv_open.handle ? spp_find_slot_by_id(id) : spp_find_slot_by_scn((uint32_t)user_data);
|
||||
if (!slot) {
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
p_data->rfc_srv_open.status = ESP_SPP_NO_CONNECTION;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p_data->rfc_srv_open.handle) {
|
||||
new_user_data = (void *)(uintptr_t)slot->id;
|
||||
memcpy(slot->addr, p_data->rfc_srv_open.rem_bda, ESP_BD_ADDR_LEN);
|
||||
slot->connected = TRUE;
|
||||
slot->rfc_handle = p_data->rfc_srv_open.handle;
|
||||
slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_srv_open.handle);
|
||||
BTA_JvSetPmProfile(p_data->rfc_srv_open.handle, BTA_JV_PM_ALL, BTA_JV_CONN_OPEN);
|
||||
}
|
||||
|
||||
if (p_data->rfc_srv_open.handle != p_data->rfc_srv_open.new_listen_handle) {
|
||||
if (!p_data->rfc_srv_open.handle) {
|
||||
/* match with the exist server solt */
|
||||
slot->rfc_handle = p_data->rfc_srv_open.new_listen_handle;
|
||||
slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(slot->rfc_handle);
|
||||
} else {
|
||||
slot_new = spp_malloc_slot();
|
||||
if (!slot_new) {
|
||||
BTC_TRACE_ERROR("%s unable to malloc RFCOMM slot!", __func__);
|
||||
p_data->rfc_srv_open.status = ESP_SPP_NO_RESOURCE;
|
||||
break;
|
||||
}
|
||||
new_user_data = (void *)(uintptr_t)slot_new->id;
|
||||
slot_new->connected = true;
|
||||
slot_new->security = slot->security;
|
||||
slot_new->role = slot->role;
|
||||
slot_new->scn = slot->scn;
|
||||
slot_new->max_session = slot->max_session;
|
||||
strcpy(slot_new->service_name, slot->service_name);
|
||||
slot_new->sdp_handle = slot->sdp_handle;
|
||||
slot_new->rfc_handle = p_data->rfc_srv_open.new_listen_handle;
|
||||
slot_new->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_srv_open.new_listen_handle);
|
||||
slot_new->rfc_handle = p_data->rfc_srv_open.handle;
|
||||
slot_new->rfc_port_handle = BTA_JvRfcommGetPortHdl(slot_new->rfc_handle);
|
||||
BTA_JvSetPmProfile(p_data->rfc_srv_open.handle, BTA_JV_PM_ALL, BTA_JV_CONN_OPEN);
|
||||
|
||||
if (p_data->rfc_srv_open.new_listen_handle) {
|
||||
slot->rfc_handle = p_data->rfc_srv_open.new_listen_handle;
|
||||
slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(slot->rfc_handle);
|
||||
} else {
|
||||
/* means lower layer can alloc port */
|
||||
slot->rfc_handle = 0;
|
||||
slot->rfc_port_handle = 0;
|
||||
}
|
||||
/* swap slot id */
|
||||
id_temp = slot->id;
|
||||
slot->id = slot_new->id;
|
||||
slot_new->id = id_temp;
|
||||
}
|
||||
new_user_data = (void *)(uintptr_t)slot->id;
|
||||
break;
|
||||
case BTA_JV_RFCOMM_CL_INIT_EVT:
|
||||
slot = spp_find_slot_by_id(id);
|
||||
if (!slot) {
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
p_data->rfc_cl_init.status = ESP_SPP_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p_data->rfc_cl_init.status == BTA_JV_SUCCESS) {
|
||||
slot->rfc_handle = p_data->rfc_cl_init.handle;
|
||||
} else {
|
||||
spp_free_slot(slot);
|
||||
}
|
||||
break;
|
||||
case BTA_JV_RFCOMM_OPEN_EVT:
|
||||
slot = spp_find_slot_by_id(id);
|
||||
if (!slot) {
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
p_data->rfc_open.status = ESP_SPP_NO_CONNECTION;
|
||||
break;
|
||||
}
|
||||
slot->connected = TRUE;
|
||||
slot->connected = true;
|
||||
slot->rfc_handle = p_data->rfc_open.handle;
|
||||
slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_open.handle);
|
||||
BTA_JvSetPmProfile(p_data->rfc_open.handle, BTA_JV_PM_ID_1, BTA_JV_CONN_OPEN);
|
||||
@@ -346,14 +381,15 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u
|
||||
case BTA_JV_RFCOMM_CLOSE_EVT:
|
||||
slot = spp_find_slot_by_id(id);
|
||||
if (!slot) {
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
p_data->rfc_close.status = ESP_SPP_NO_CONNECTION;
|
||||
break;
|
||||
}
|
||||
if (slot->connected && p_data->rfc_close.port_status != PORT_LOCAL_CLOSED) {
|
||||
if (slot->rfc_handle && p_data->rfc_close.port_status != PORT_LOCAL_CLOSED) {
|
||||
BTA_JvRfcommClose(slot->rfc_handle, NULL, (void *)slot->id);
|
||||
}
|
||||
p_data->rfc_close.status = BTA_JV_SUCCESS;
|
||||
p_data->rfc_close.user_data = (void *)(uintptr_t)slot->id;
|
||||
break;
|
||||
case BTA_JV_RFCOMM_DATA_IND_EVT:
|
||||
break;
|
||||
@@ -364,7 +400,7 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u
|
||||
if (slot) {
|
||||
spp_free_slot(slot);
|
||||
} else {
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
p_data->free_scn.status = ESP_SPP_NO_CONNECTION;
|
||||
}
|
||||
osi_free(user_data);
|
||||
@@ -401,7 +437,7 @@ static void btc_spp_dm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d
|
||||
slot = spp_find_slot_by_id(id);
|
||||
if (!slot) {
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
break;
|
||||
}
|
||||
if (p_data->scn == 0) {
|
||||
@@ -421,7 +457,7 @@ static void btc_spp_dm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d
|
||||
slot = spp_find_slot_by_id(id);
|
||||
if (!slot) {
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
break;
|
||||
}
|
||||
if (p_data->create_rec.status == BTA_JV_SUCCESS) {
|
||||
@@ -483,6 +519,7 @@ static void btc_spp_init(btc_spp_args_t *arg)
|
||||
}
|
||||
if ((spp_local_param.tx_event_group = xEventGroupCreate()) == NULL) {
|
||||
BTC_TRACE_ERROR("%s create tx_event_group failed\n", __func__);
|
||||
osi_mutex_free(&spp_local_param.spp_slot_mutex);
|
||||
ret = ESP_SPP_NO_RESOURCE;
|
||||
break;
|
||||
}
|
||||
@@ -510,14 +547,14 @@ static void btc_spp_uninit(void)
|
||||
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
|
||||
// first, remove all connection
|
||||
for (size_t i = 1; i <= MAX_RFC_PORTS; i++) {
|
||||
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->connected) {
|
||||
if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->is_server) {
|
||||
BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle, (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb,
|
||||
(void *)spp_local_param.spp_slots[i]->id);
|
||||
}
|
||||
}
|
||||
// second, remove all server
|
||||
for (size_t i = 1; i <= MAX_RFC_PORTS; i++) {
|
||||
if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->connected) {
|
||||
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->is_server) {
|
||||
if (spp_local_param.spp_slots[i]->sdp_handle > 0) {
|
||||
BTA_JvDeleteRecord(spp_local_param.spp_slots[i]->sdp_handle);
|
||||
}
|
||||
@@ -546,11 +583,6 @@ static void btc_spp_uninit(void)
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
} while(0);
|
||||
|
||||
if (spp_local_param.tx_event_group) {
|
||||
vEventGroupDelete(spp_local_param.tx_event_group);
|
||||
spp_local_param.tx_event_group = NULL;
|
||||
}
|
||||
|
||||
if (ret != ESP_SPP_SUCCESS) {
|
||||
esp_spp_cb_param_t param;
|
||||
param.uninit.status = ret;
|
||||
@@ -669,6 +701,10 @@ static void btc_spp_start_srv(btc_spp_args_t *arg)
|
||||
ret = ESP_SPP_NO_RESOURCE;
|
||||
break;
|
||||
}
|
||||
/**
|
||||
* make this slot become a listening slot
|
||||
*/
|
||||
slot->is_server = true;
|
||||
slot->security = arg->start_srv.sec_mask;
|
||||
slot->role = arg->start_srv.role;
|
||||
slot->scn = arg->start_srv.local_scn;
|
||||
@@ -738,7 +774,7 @@ static void btc_spp_stop_srv(btc_spp_args_t *arg)
|
||||
// [2] remove all local related connection
|
||||
for (j = 0; j < srv_cnt; j++) {
|
||||
for (i = 1; i <= MAX_RFC_PORTS; i++) {
|
||||
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->connected &&
|
||||
if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->is_server &&
|
||||
spp_local_param.spp_slots[i]->sdp_handle > 0 &&
|
||||
spp_local_param.spp_slots[i]->scn == srv_scn_arr[j]) {
|
||||
BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle,
|
||||
@@ -751,7 +787,7 @@ static void btc_spp_stop_srv(btc_spp_args_t *arg)
|
||||
// [3] remove all server
|
||||
for (j = 0; j < srv_cnt; j++) {
|
||||
for (i = 1; i <= MAX_RFC_PORTS; i++) {
|
||||
if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->connected &&
|
||||
if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->is_server &&
|
||||
spp_local_param.spp_slots[i]->sdp_handle > 0 &&
|
||||
spp_local_param.spp_slots[i]->scn == srv_scn_arr[j]) {
|
||||
if (spp_local_param.spp_slots[i]->sdp_handle > 0) {
|
||||
@@ -933,7 +969,9 @@ void btc_spp_cb_handler(btc_msg_t *msg)
|
||||
tBTA_JV *p_data = (tBTA_JV *)msg->arg;
|
||||
spp_slot_t *slot = NULL;
|
||||
uint8_t serial = 0;
|
||||
switch (msg->act) {
|
||||
uint8_t event = msg->act;
|
||||
|
||||
switch (event) {
|
||||
case BTA_JV_ENABLE_EVT:
|
||||
param.init.status = p_data->status;
|
||||
btc_spp_cb_to_app(ESP_SPP_INIT_EVT, ¶m);
|
||||
@@ -960,12 +998,14 @@ void btc_spp_cb_handler(btc_msg_t *msg)
|
||||
slot = spp_find_slot_by_handle(p_data->rfc_open.handle);
|
||||
if (!slot) {
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
param.open.status = ESP_SPP_NO_CONNECTION;
|
||||
break;
|
||||
}
|
||||
param.open.fd = slot->fd;
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
} else {
|
||||
param.open.fd = -1;
|
||||
}
|
||||
param.open.status = p_data->rfc_open.status;
|
||||
} while (0);
|
||||
@@ -989,12 +1029,14 @@ void btc_spp_cb_handler(btc_msg_t *msg)
|
||||
slot = spp_find_slot_by_handle(p_data->rfc_srv_open.handle);
|
||||
if (!slot) {
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
param.srv_open.status = ESP_SPP_NO_CONNECTION;
|
||||
break;
|
||||
}
|
||||
param.srv_open.fd = slot->fd;
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
} else {
|
||||
param.srv_open.fd = -1;
|
||||
}
|
||||
param.srv_open.status = p_data->rfc_srv_open.status;
|
||||
} while (0);
|
||||
@@ -1024,6 +1066,7 @@ void btc_spp_cb_handler(btc_msg_t *msg)
|
||||
BT_HDR *p_buf;
|
||||
serial = slot->serial;
|
||||
if ((p_buf = fixed_queue_try_peek_first(slot->tx.queue)) == NULL) {
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
break;
|
||||
}
|
||||
if (p_data->rfc_write.status == BTA_JV_SUCCESS) {
|
||||
@@ -1065,10 +1108,11 @@ void btc_spp_cb_handler(btc_msg_t *msg)
|
||||
if (spp_local_param.spp_mode == ESP_SPP_MODE_CB) {
|
||||
btc_spp_cb_to_app(ESP_SPP_CLOSE_EVT, ¶m);
|
||||
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
|
||||
slot = spp_find_slot_by_handle(p_data->rfc_close.handle);
|
||||
uint32_t id = (uintptr_t)p_data->rfc_close.user_data;
|
||||
slot = spp_find_slot_by_id(id);
|
||||
if (!slot) {
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
break;
|
||||
}
|
||||
spp_free_slot(slot);
|
||||
@@ -1077,11 +1121,12 @@ void btc_spp_cb_handler(btc_msg_t *msg)
|
||||
bool need_call = true;
|
||||
do {
|
||||
osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
|
||||
slot = spp_find_slot_by_handle(p_data->rfc_close.handle);
|
||||
uint32_t id = (uintptr_t)p_data->rfc_close.user_data;
|
||||
slot = spp_find_slot_by_id(id);
|
||||
if (!slot) {
|
||||
param.close.status = ESP_SPP_NO_CONNECTION;
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
break;
|
||||
}
|
||||
// if rx still has data, delay free slot
|
||||
@@ -1110,8 +1155,8 @@ void btc_spp_cb_handler(btc_msg_t *msg)
|
||||
BTC_TRACE_ERROR("%s set slot close_alarm failed!", __func__);
|
||||
break;
|
||||
}
|
||||
BTC_TRACE_WARNING("%s slot rx data will be discard in %d seconds!", __func__,
|
||||
VFS_CLOSE_TIMEOUT / 1000);
|
||||
BTC_TRACE_WARNING("%s slot rx data will be discard in %d milliseconds!",
|
||||
__func__, VFS_CLOSE_TIMEOUT);
|
||||
slot->connected = false;
|
||||
need_call = false;
|
||||
}
|
||||
@@ -1137,7 +1182,7 @@ void btc_spp_cb_handler(btc_msg_t *msg)
|
||||
slot = spp_find_slot_by_handle(p_data->rfc_cong.handle);
|
||||
if (!slot) {
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
break;
|
||||
}
|
||||
if (!p_data->rfc_cong.cong) {
|
||||
@@ -1159,7 +1204,7 @@ void btc_spp_cb_handler(btc_msg_t *msg)
|
||||
slot = spp_find_slot_by_handle(p_data->data_ind.handle);
|
||||
if (!slot) {
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event);
|
||||
break;
|
||||
}
|
||||
serial = slot->serial;
|
||||
@@ -1207,6 +1252,10 @@ void btc_spp_cb_handler(btc_msg_t *msg)
|
||||
param.uninit.status = ESP_SPP_SUCCESS;
|
||||
BTA_JvFree();
|
||||
osi_mutex_free(&spp_local_param.spp_slot_mutex);
|
||||
if (spp_local_param.tx_event_group) {
|
||||
vEventGroupDelete(spp_local_param.tx_event_group);
|
||||
spp_local_param.tx_event_group = NULL;
|
||||
}
|
||||
#if SPP_DYNAMIC_MEMORY == TRUE
|
||||
osi_free(spp_local_param_ptr);
|
||||
spp_local_param_ptr = NULL;
|
||||
@@ -1416,7 +1465,7 @@ static ssize_t spp_vfs_read(int fd, void * dst, size_t size)
|
||||
slot = spp_find_slot_by_fd(fd);
|
||||
if (!slot) {
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!\n", __func__);
|
||||
BTC_TRACE_ERROR("%s unable to find RFCOMM slot!", __func__);
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
@@ -1441,6 +1490,14 @@ static ssize_t spp_vfs_read(int fd, void * dst, size_t size)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* If close_alarm is not NULL, it means that we have received the BTA_JV_RFCOMM_CLOSE_EVT.
|
||||
* And we can trigger close_alarm immediately.
|
||||
*/
|
||||
if (slot->close_alarm && osi_alarm_is_active(slot->close_alarm)) {
|
||||
osi_alarm_cancel(slot->close_alarm);
|
||||
osi_alarm_set(slot->close_alarm, 0);
|
||||
}
|
||||
osi_mutex_unlock(&spp_local_param.spp_slot_mutex);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -178,9 +178,9 @@
|
||||
#define UC_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD 20
|
||||
#endif
|
||||
|
||||
#endif //CONFIG_BT_CTRL_ESP32
|
||||
#endif //CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
#if (CONFIG_BT_CTRL_ESP32C3 || CONFIG_BT_CTRL_ESP32S3)
|
||||
#if (CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3)
|
||||
//BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
#ifdef CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
#define UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
@@ -202,7 +202,7 @@
|
||||
#define UC_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD 20
|
||||
#endif
|
||||
|
||||
#endif //(CONFIG_BT_CTRL_ESP32C3 || CONFIG_BT_CTRL_ESP32S3)
|
||||
#endif //(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3)
|
||||
|
||||
//BT ACL CONNECTIONS
|
||||
#ifdef CONFIG_BT_ACL_CONNECTIONS
|
||||
|
||||
@@ -209,7 +209,8 @@ static void parse_ble_read_adv_max_len_response(
|
||||
{
|
||||
|
||||
uint8_t *stream = read_command_complete_header(response, HCI_BLE_RD_MAX_ADV_DATA_LEN, 1 /* bytes after */);
|
||||
STREAM_TO_UINT8(*adv_max_len_ptr, stream);
|
||||
// Size: 2 Octets ; Value: 0x001F – 0x0672 ; Maximum supported advertising data length
|
||||
STREAM_TO_UINT16(*adv_max_len_ptr, stream);
|
||||
|
||||
osi_free(response);
|
||||
}
|
||||
|
||||
@@ -689,23 +689,16 @@ tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data
|
||||
{
|
||||
tBTM_STATUS status = BTM_SUCCESS;
|
||||
tHCI_STATUS err = HCI_SUCCESS;
|
||||
uint16_t rem_len;
|
||||
uint16_t rem_len = len;
|
||||
UINT8 operation = 0;
|
||||
UINT16 data_offset = 0;
|
||||
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
|
||||
|
||||
if ((status = btm_ble_ext_adv_set_data_validate(instance, len, data)) != BTM_SUCCESS) {
|
||||
BTM_TRACE_ERROR("%s, invalid extend adv data.", __func__);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (len > controller_get_interface()->ble_get_ext_adv_data_max_len()) {
|
||||
BTM_TRACE_ERROR("%s, The adv data len(%d) is longer then the controller adv max len(%d)",
|
||||
__func__, len, controller_get_interface()->ble_get_ext_adv_data_max_len());
|
||||
status = BTM_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
rem_len = len;
|
||||
|
||||
do {
|
||||
UINT8 send_data_len = (rem_len > BTM_BLE_PERIODIC_ADV_DATA_LEN_MAX) ? BTM_BLE_PERIODIC_ADV_DATA_LEN_MAX : rem_len;
|
||||
|
||||
@@ -729,8 +722,8 @@ tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data
|
||||
data_offset += send_data_len;
|
||||
} while(rem_len);
|
||||
|
||||
end:
|
||||
cb_params.status = status;
|
||||
|
||||
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, &cb_params);
|
||||
|
||||
return status;
|
||||
@@ -1108,6 +1101,12 @@ static tBTM_STATUS btm_ble_ext_adv_set_data_validate(UINT8 instance, UINT16 len,
|
||||
BTM_TRACE_ERROR("%s, for the legacy adv, the adv data length can't exceed 31. line %d", __func__, __LINE__);
|
||||
return BTM_ILLEGAL_VALUE;
|
||||
}
|
||||
} else {
|
||||
if (len > controller_get_interface()->ble_get_ext_adv_data_max_len()) {
|
||||
BTM_TRACE_ERROR("%s, The adv data len(%d) is longer then the controller adv max len(%d)",
|
||||
__func__, len, controller_get_interface()->ble_get_ext_adv_data_max_len());
|
||||
return BTM_ILLEGAL_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
return BTM_SUCCESS;
|
||||
|
||||
@@ -108,7 +108,7 @@ const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] = {
|
||||
{HCI_SUPP_LE_STATES_INIT_MASK, HCI_SUPP_LE_STATES_INIT_OFF}, /* init */
|
||||
{HCI_SUPP_LE_STATES_INIT_MASK, HCI_SUPP_LE_STATES_INIT_OFF}, /* master */
|
||||
{HCI_SUPP_LE_STATES_SLAVE_MASK, HCI_SUPP_LE_STATES_SLAVE_OFF}, /* slave */
|
||||
{0, 0}, /* todo: lo du dir adv, not covered ? */
|
||||
{HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_OFF}, /* lo du dir adv */
|
||||
{HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF}, /* hi duty dir adv */
|
||||
{HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF}, /* non connectable adv */
|
||||
{HCI_SUPP_LE_STATES_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_OFF}, /* passive scan */
|
||||
@@ -174,8 +174,8 @@ const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] = {
|
||||
{0, 0}, /* lo duty cycle adv 40 */
|
||||
{0, 0}, /* hi duty cycle adv 39 */
|
||||
{0, 0}, /* non connectable adv */
|
||||
{0, 0}, /* TODO: passive scan, not covered? */
|
||||
{0, 0}, /* TODO: active scan, not covered? */
|
||||
{HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_PASS_SCAN_OFF}, /* passive scan */
|
||||
{HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_ACTIVE_SCAN_OFF}, /* active scan */
|
||||
{0, 0} /* scanable adv */
|
||||
},
|
||||
{ /* hi duty cycle adv */
|
||||
|
||||
@@ -314,25 +314,60 @@ BOOLEAN btm_find_sec_dev_in_list (void *p_node_data, void *context)
|
||||
tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr)
|
||||
{
|
||||
tBTM_SEC_DEV_REC *p_dev_rec = NULL;
|
||||
tBTM_SEC_DEV_REC *p_dev_new_rec = NULL;
|
||||
tBTM_SEC_DEV_REC *p_dev_old_rec = NULL;
|
||||
tBTM_INQ_INFO *p_inq_info;
|
||||
list_node_t *p_node = NULL;
|
||||
BOOLEAN new_entry_found = FALSE;
|
||||
BOOLEAN old_entry_found = FALSE;
|
||||
BOOLEAN malloc_new_entry = FALSE;
|
||||
BTM_TRACE_EVENT ("btm_sec_alloc_dev\n");
|
||||
|
||||
/* Old devices which are not in use are deleted already */
|
||||
/* Allocate new device or reuse the oldest device */
|
||||
if (list_length(btm_cb.p_sec_dev_rec_list) < BTM_SEC_MAX_DEVICE_RECORDS) {
|
||||
//Max number of devices is not exceeded, allocate new device
|
||||
p_dev_rec = (tBTM_SEC_DEV_REC *)osi_malloc(sizeof(tBTM_SEC_DEV_REC));
|
||||
if (p_dev_rec) {
|
||||
list_append(btm_cb.p_sec_dev_rec_list, p_dev_rec);
|
||||
} else {
|
||||
return NULL;
|
||||
for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) {
|
||||
p_dev_old_rec = list_node(p_node);
|
||||
/* look for old entry which match the bd_addr and the BTM_SEC_IN_USE is cleared */
|
||||
if (!(p_dev_old_rec->sec_flags & BTM_SEC_IN_USE) &&
|
||||
(!memcmp (p_dev_old_rec->bd_addr, bd_addr, BD_ADDR_LEN))) {
|
||||
old_entry_found = TRUE;
|
||||
BTM_TRACE_EVENT ("btm_sec_alloc_dev old device found\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//Find and reuse the oldest device
|
||||
p_dev_rec = btm_find_oldest_dev();
|
||||
for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) {
|
||||
p_dev_new_rec = list_node(p_node);
|
||||
/* find the first entry whose BTM_SEC_IN_USE is cleared */
|
||||
if (!(p_dev_new_rec->sec_flags & BTM_SEC_IN_USE)) {
|
||||
new_entry_found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!new_entry_found) {
|
||||
/* We can not find new device. We need malloc a new one if p_sec_dev_rec_list is not full */
|
||||
if (list_length(btm_cb.p_sec_dev_rec_list) < BTM_SEC_MAX_DEVICE_RECORDS){
|
||||
p_dev_new_rec = (tBTM_SEC_DEV_REC *)osi_malloc(sizeof(tBTM_SEC_DEV_REC));
|
||||
if (p_dev_new_rec) {
|
||||
new_entry_found = TRUE;
|
||||
malloc_new_entry = TRUE;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!new_entry_found) {
|
||||
p_dev_rec = btm_find_oldest_dev();
|
||||
} else {
|
||||
/* if the old device entry not present go with new entry */
|
||||
if (old_entry_found) {
|
||||
p_dev_rec = p_dev_old_rec;
|
||||
if (malloc_new_entry) {
|
||||
osi_free(p_dev_new_rec);
|
||||
}
|
||||
} else {
|
||||
if (malloc_new_entry) {
|
||||
list_append(btm_cb.p_sec_dev_rec_list, p_dev_new_rec);
|
||||
}
|
||||
p_dev_rec = p_dev_new_rec;
|
||||
}
|
||||
}
|
||||
|
||||
memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC));
|
||||
|
||||
p_dev_rec->bond_type = BOND_TYPE_UNKNOWN; /* Default value */
|
||||
|
||||
@@ -111,12 +111,15 @@ static void btu_hcif_rem_oob_request_evt (UINT8 *p);
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
static void btu_hcif_simple_pair_complete_evt (UINT8 *p);
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
static void btu_hcif_link_supv_to_changed_evt (UINT8 *p);
|
||||
#if L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE
|
||||
static void btu_hcif_enhanced_flush_complete_evt (void);
|
||||
#endif
|
||||
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
static void btu_hcif_ssr_evt (UINT8 *p, UINT16 evt_len);
|
||||
#else
|
||||
static void btu_hcif_ssr_evt_dump (UINT8 *p, UINT16 evt_len);
|
||||
#endif /* BTM_SSR_INCLUDED == TRUE */
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
@@ -300,11 +303,13 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
|
||||
case HCI_ESCO_CONNECTION_CHANGED_EVT:
|
||||
btu_hcif_esco_connection_chg_evt (p);
|
||||
break;
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
case HCI_SNIFF_SUB_RATE_EVT:
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
btu_hcif_ssr_evt (p, hci_evt_len);
|
||||
break;
|
||||
#else
|
||||
btu_hcif_ssr_evt_dump (p, hci_evt_len);
|
||||
#endif /* BTM_SSR_INCLUDED == TRUE */
|
||||
break;
|
||||
case HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT:
|
||||
btu_hcif_host_support_evt (p);
|
||||
break;
|
||||
@@ -338,6 +343,9 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
|
||||
btu_hcif_keypress_notif_evt (p);
|
||||
break;
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
case HCI_LINK_SUPER_TOUT_CHANGED_EVT:
|
||||
btu_hcif_link_supv_to_changed_evt (p);
|
||||
break;
|
||||
#if L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE
|
||||
case HCI_ENHANCED_FLUSH_COMPLETE_EVT:
|
||||
btu_hcif_enhanced_flush_complete_evt ();
|
||||
@@ -651,6 +659,7 @@ static void btu_hcif_connection_comp_evt (UINT8 *p)
|
||||
btm_sco_connected (status, bda, handle, &esco_data);
|
||||
}
|
||||
#endif /* BTM_SCO_INCLUDED */
|
||||
HCI_TRACE_WARNING("hcif conn complete: hdl 0x%x, st 0x%x", handle, status);
|
||||
}
|
||||
|
||||
|
||||
@@ -707,9 +716,7 @@ static void btu_hcif_disconnection_comp_evt (UINT8 *p)
|
||||
|
||||
handle = HCID_GET_HANDLE (handle);
|
||||
|
||||
if (reason != HCI_ERR_PEER_USER && reason != HCI_ERR_CONN_CAUSE_LOCAL_HOST) {
|
||||
HCI_TRACE_WARNING("DiscCmpl evt: hdl=%d, rsn=0x%x", handle, reason);
|
||||
}
|
||||
HCI_TRACE_WARNING("hcif disc complete: hdl 0x%x, rsn 0x%x", handle, reason);
|
||||
|
||||
#if BTM_SCO_INCLUDED == TRUE
|
||||
/* If L2CAP doesn't know about it, send it to SCO */
|
||||
@@ -1554,6 +1561,8 @@ static void btu_hcif_mode_change_evt (UINT8 *p)
|
||||
btm_sco_chk_pend_unpark (status, handle);
|
||||
#endif
|
||||
btm_pm_proc_mode_change (status, handle, current_mode, interval);
|
||||
HCI_TRACE_WARNING("hcif mode change: hdl 0x%x, mode %d, intv %d, status 0x%x",
|
||||
handle, current_mode, interval, status);
|
||||
|
||||
/*
|
||||
#if (HID_DEV_INCLUDED == TRUE) && (HID_DEV_PM_INCLUDED == TRUE)
|
||||
@@ -1576,6 +1585,26 @@ static void btu_hcif_ssr_evt (UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
btm_pm_proc_ssr_evt(p, evt_len);
|
||||
}
|
||||
#else
|
||||
static void btu_hcif_ssr_evt_dump (UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
UINT8 status;
|
||||
UINT16 handle;
|
||||
UINT16 max_tx_lat;
|
||||
UINT16 max_rx_lat;
|
||||
|
||||
STREAM_TO_UINT8 (status, p);
|
||||
STREAM_TO_UINT16 (handle, p);
|
||||
STREAM_TO_UINT16 (max_tx_lat, p);
|
||||
STREAM_TO_UINT16 (max_rx_lat, p);
|
||||
|
||||
UNUSED(status);
|
||||
UNUSED(handle);
|
||||
UNUSED(max_tx_lat);
|
||||
UNUSED(max_rx_lat);
|
||||
|
||||
HCI_TRACE_WARNING("hcif ssr evt: st 0x%x, hdl 0x%x, tx_lat %d rx_lat %d", status, handle, max_tx_lat, max_rx_lat);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -1920,6 +1949,30 @@ static void btu_hcif_simple_pair_complete_evt (UINT8 *p)
|
||||
btm_simple_pair_complete(p);
|
||||
}
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function btu_hcif_link_supv_to_changed_evt
|
||||
**
|
||||
** Description Process event HCI_LINK_SUPER_TOUT_CHANGED_EVT
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void btu_hcif_link_supv_to_changed_evt (UINT8 *p)
|
||||
{
|
||||
UINT16 handle;
|
||||
UINT16 supv_to;
|
||||
|
||||
STREAM_TO_UINT16(handle, p);
|
||||
STREAM_TO_UINT16(supv_to, p);
|
||||
|
||||
UNUSED(handle);
|
||||
UNUSED(supv_to);
|
||||
|
||||
HCI_TRACE_WARNING("hcif link supv_to changed: hdl 0x%x, supv_to %d", handle, supv_to);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function btu_hcif_enhanced_flush_complete_evt
|
||||
@@ -2065,14 +2118,41 @@ static void btu_ble_phy_update_complete_evt(UINT8 *p)
|
||||
btm_ble_update_phy_evt(&update_phy);
|
||||
}
|
||||
|
||||
#if BLE_PRIVACY_SPT == TRUE
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function btm_ble_resolve_random_addr_adv_ext
|
||||
**
|
||||
** Description resolve random address complete callback.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void btm_ble_resolve_random_addr_adv_ext(void *p_rec, void *p)
|
||||
{
|
||||
tBTM_SEC_DEV_REC *match_rec = (tBTM_SEC_DEV_REC *) p_rec;
|
||||
BD_ADDR bda;
|
||||
UINT8 *pp = (UINT8 *)p+4; //jump to the location of bd addr
|
||||
if (match_rec) {
|
||||
// Assign the original address to be the current report address
|
||||
memcpy(bda, match_rec->ble.pseudo_addr, BD_ADDR_LEN);
|
||||
BDADDR_TO_STREAM(pp,bda);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len)
|
||||
{
|
||||
tBTM_BLE_EXT_ADV_REPORT ext_adv_report = {0};
|
||||
UINT8 num_reports = {0};
|
||||
UINT8 *pp = p;
|
||||
//UINT8 legacy_event_type = 0;
|
||||
UINT16 evt_type = 0;
|
||||
uint8_t addr_type;
|
||||
BD_ADDR bda;
|
||||
#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
|
||||
BOOLEAN match = FALSE;
|
||||
#endif
|
||||
|
||||
if (!p) {
|
||||
HCI_TRACE_ERROR("%s, Invalid params.", __func__);
|
||||
@@ -2106,12 +2186,17 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len)
|
||||
|
||||
STREAM_TO_UINT8(addr_type, p);
|
||||
STREAM_TO_BDADDR(bda, p);
|
||||
// If it is an anonymous adv, skip address resolution
|
||||
if(addr_type != 0xFF) {
|
||||
#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
|
||||
btm_identity_addr_to_random_pseudo(bda, &addr_type, FALSE);
|
||||
#endif
|
||||
if(addr_type != 0xFF) {
|
||||
match = btm_identity_addr_to_random_pseudo(bda, &addr_type, FALSE);
|
||||
if (!match && BTM_BLE_IS_RESOLVE_BDA(bda)) {
|
||||
btm_ble_resolve_random_addr(bda, btm_ble_resolve_random_addr_adv_ext, pp);
|
||||
//the BDADDR may be updated, so read it again
|
||||
p = p - sizeof(bda);
|
||||
STREAM_TO_BDADDR(bda, p);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ext_adv_report.addr_type = addr_type;
|
||||
memcpy(ext_adv_report.addr, bda, 6);
|
||||
STREAM_TO_UINT8(ext_adv_report.primary_phy, p);
|
||||
|
||||
@@ -191,6 +191,7 @@ BOOLEAN btsnd_hcic_disconnect (UINT16 handle, UINT8 reason)
|
||||
UINT8_TO_STREAM (pp, reason);
|
||||
|
||||
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
|
||||
HCI_TRACE_WARNING("hci cmd send: disconnect: hdl 0x%x, rsn:0x%x", handle, reason);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
@@ -776,6 +777,8 @@ BOOLEAN btsnd_hcic_sniff_mode (UINT16 handle, UINT16 max_sniff_period,
|
||||
UINT16_TO_STREAM (pp, sniff_timeout);
|
||||
|
||||
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
|
||||
HCI_TRACE_WARNING("hci cmd send: sniff: hdl 0x%x, intv(%d %d)",
|
||||
handle, min_sniff_period, max_sniff_period);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
@@ -799,6 +802,7 @@ BOOLEAN btsnd_hcic_exit_sniff_mode (UINT16 handle)
|
||||
UINT16_TO_STREAM (pp, handle);
|
||||
|
||||
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
|
||||
HCI_TRACE_WARNING("hci cmd send: unsniff: hdl 0x%x", handle);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +105,16 @@ typedef int (tPORT_DATA_CO_CALLBACK) (UINT16 port_handle, UINT8 *p_buf, UINT16
|
||||
|
||||
typedef void (tPORT_CALLBACK) (UINT32 code, UINT16 port_handle);
|
||||
|
||||
typedef void (tPORT_MGMT_CALLBACK) (UINT32 code, UINT16 port_handle, void* data);
|
||||
|
||||
/**
|
||||
* Define the server port manage callback function argument
|
||||
*/
|
||||
typedef struct {
|
||||
BOOLEAN accept; /* If upper layer accepts the incoming connection */
|
||||
BOOLEAN ignore_rfc_state; /* If need to ignore rfc state for PORT_CheckConnection */
|
||||
} tPORT_MGMT_SR_CALLBACK_ARG;
|
||||
|
||||
/*
|
||||
** Define events that registered application can receive in the callback
|
||||
*/
|
||||
@@ -219,7 +229,7 @@ extern "C"
|
||||
extern int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn,
|
||||
BOOLEAN is_server, UINT16 mtu,
|
||||
BD_ADDR bd_addr, UINT16 *p_handle,
|
||||
tPORT_CALLBACK *p_mgmt_cb);
|
||||
tPORT_MGMT_CALLBACK *p_mgmt_cb);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -310,11 +320,12 @@ extern int PORT_SetEventMask (UINT16 port_handle, UINT32 mask);
|
||||
** by handle is up and running
|
||||
**
|
||||
** Parameters: handle - Handle of the port returned in the Open
|
||||
** ignore_rfc_state - If need to ignore rfc state
|
||||
** bd_addr - OUT bd_addr of the peer
|
||||
** p_lcid - OUT L2CAP's LCID
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern int PORT_CheckConnection (UINT16 handle, BD_ADDR bd_addr,
|
||||
extern int PORT_CheckConnection (UINT16 handle, BOOLEAN ignore_rfc_state, BD_ADDR bd_addr,
|
||||
UINT16 *p_lcid);
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
@@ -363,7 +363,10 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason)
|
||||
/* If we don't have one, maybe an SCO link. Send to MM */
|
||||
if (!p_lcb) {
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
BTM_Recovery_Pre_State();
|
||||
/* The Directed Advertising Timeout error code indicates that directed advertising completed */
|
||||
if (reason != HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT) {
|
||||
BTM_Recovery_Pre_State();
|
||||
}
|
||||
#endif ///BLE_INCLUDED == TRUE
|
||||
status = FALSE;
|
||||
} else {
|
||||
|
||||
@@ -188,7 +188,7 @@ struct t_port_info {
|
||||
|
||||
UINT32 ev_mask; /* Event mask for the callback */
|
||||
tPORT_CALLBACK *p_callback; /* Pointer to users callback function */
|
||||
tPORT_CALLBACK *p_mgmt_callback; /* Callback function to receive connection up/down */
|
||||
tPORT_MGMT_CALLBACK *p_mgmt_callback; /* Callback function to receive connection up/down */
|
||||
tPORT_DATA_CALLBACK *p_data_callback; /* Callback function to receive data indications */
|
||||
tPORT_DATA_CO_CALLBACK *p_data_co_callback; /* Callback function with callouts and flowctrl */
|
||||
UINT16 credit_tx; /* Flow control credits for tx path */
|
||||
|
||||
@@ -103,7 +103,7 @@ static const char *result_code_strings[] = {
|
||||
*******************************************************************************/
|
||||
int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, BOOLEAN is_server,
|
||||
UINT16 mtu, BD_ADDR bd_addr, UINT16 *p_handle,
|
||||
tPORT_CALLBACK *p_mgmt_cb)
|
||||
tPORT_MGMT_CALLBACK *p_mgmt_cb)
|
||||
{
|
||||
tPORT *p_port;
|
||||
int i;
|
||||
@@ -464,11 +464,12 @@ int PORT_SetEventMask (UINT16 port_handle, UINT32 mask)
|
||||
** by handle is up and running
|
||||
**
|
||||
** Parameters: handle - Handle returned in the RFCOMM_CreateConnection
|
||||
** ignore_rfc_state - If need to ignore rfc state
|
||||
** bd_addr - OUT bd_addr of the peer
|
||||
** p_lcid - OUT L2CAP's LCID
|
||||
**
|
||||
*******************************************************************************/
|
||||
int PORT_CheckConnection (UINT16 handle, BD_ADDR bd_addr, UINT16 *p_lcid)
|
||||
int PORT_CheckConnection(UINT16 handle, BOOLEAN ignore_rfc_state, BD_ADDR bd_addr, UINT16 *p_lcid)
|
||||
{
|
||||
tPORT *p_port;
|
||||
|
||||
@@ -485,9 +486,8 @@ int PORT_CheckConnection (UINT16 handle, BD_ADDR bd_addr, UINT16 *p_lcid)
|
||||
return (PORT_NOT_OPENED);
|
||||
}
|
||||
|
||||
if (!p_port->rfc.p_mcb
|
||||
|| !p_port->rfc.p_mcb->peer_ready
|
||||
|| (p_port->rfc.state != RFC_STATE_OPENED)) {
|
||||
if (!p_port->rfc.p_mcb || !p_port->rfc.p_mcb->peer_ready ||
|
||||
(!ignore_rfc_state ? (p_port->rfc.state != RFC_STATE_OPENED) : false)) {
|
||||
return (PORT_LINE_ERR);
|
||||
}
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ void port_start_close (tPORT *p_port)
|
||||
if ((p_mcb == NULL) || (p_port->rfc.state == RFC_STATE_CLOSED)) {
|
||||
/* Call management callback function before calling port_release_port() to clear tPort */
|
||||
if (p_port->p_mgmt_callback) {
|
||||
p_port->p_mgmt_callback (PORT_CLOSED, p_port->inx);
|
||||
p_port->p_mgmt_callback (PORT_CLOSED, p_port->inx, NULL);
|
||||
}
|
||||
|
||||
port_release_port (p_port);
|
||||
@@ -230,7 +230,7 @@ void PORT_StartCnf (tRFC_MCB *p_mcb, UINT16 result)
|
||||
}
|
||||
|
||||
if (p_port->p_mgmt_callback) {
|
||||
p_port->p_mgmt_callback (PORT_START_FAILED, p_port->inx);
|
||||
p_port->p_mgmt_callback (PORT_START_FAILED, p_port->inx, NULL);
|
||||
}
|
||||
|
||||
port_release_port (p_port);
|
||||
@@ -427,6 +427,10 @@ void PORT_ParNegCnf (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT8 cl, UINT8 k)
|
||||
void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
|
||||
{
|
||||
tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
|
||||
tPORT_MGMT_SR_CALLBACK_ARG mgmt_cb_arg = {
|
||||
.accept = TRUE,
|
||||
.ignore_rfc_state = FALSE,
|
||||
};
|
||||
|
||||
RFCOMM_TRACE_DEBUG ("PORT_DlcEstablishInd p_mcb:%p, dlci:%d mtu:%di, p_port:%p", p_mcb, dlci, mtu, p_port);
|
||||
RFCOMM_TRACE_DEBUG ("PORT_DlcEstablishInd p_mcb addr:%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
@@ -451,7 +455,7 @@ void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
|
||||
/* If there was an inactivity timer running for MCB stop it */
|
||||
rfc_timer_stop (p_mcb);
|
||||
|
||||
RFCOMM_DlcEstablishRsp (p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS);
|
||||
// RFCOMM_DlcEstablishRsp (p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS);
|
||||
|
||||
/* This is the server side. If application wants to know when connection */
|
||||
/* is established, thats the place */
|
||||
@@ -460,10 +464,22 @@ void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
|
||||
}
|
||||
|
||||
if (p_port->p_mgmt_callback) {
|
||||
p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx);
|
||||
/**
|
||||
* @note
|
||||
* 1. The manage callback function may change the value of accept in mgmt_cb_arg.
|
||||
* 2. Use mgmt_cb_arg.ignore_rfc_state to work around the issue caused by sending
|
||||
* RFCOMM establish response after the manage callback function.
|
||||
*/
|
||||
mgmt_cb_arg.ignore_rfc_state = TRUE;
|
||||
p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx, &mgmt_cb_arg);
|
||||
}
|
||||
|
||||
p_port->state = PORT_STATE_OPENED;
|
||||
if (mgmt_cb_arg.accept) {
|
||||
RFCOMM_DlcEstablishRsp(p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS);
|
||||
p_port->state = PORT_STATE_OPENED;
|
||||
} else {
|
||||
RFCOMM_DlcEstablishRsp(p_mcb, dlci, 0, RFCOMM_LOW_RESOURCES);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -506,7 +522,7 @@ void PORT_DlcEstablishCnf (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 resul
|
||||
}
|
||||
|
||||
if (p_port->p_mgmt_callback) {
|
||||
p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx);
|
||||
p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx, NULL);
|
||||
}
|
||||
|
||||
p_port->state = PORT_STATE_OPENED;
|
||||
@@ -1063,14 +1079,15 @@ void port_rfc_closed (tPORT *p_port, UINT8 res)
|
||||
p_port->p_callback (events, p_port->inx);
|
||||
}
|
||||
|
||||
if (p_port->p_mgmt_callback) {
|
||||
p_port->p_mgmt_callback (res, p_port->inx);
|
||||
if (p_port->p_mgmt_callback && !(p_port->state == PORT_STATE_CLOSED && p_port->is_server)) {
|
||||
p_port->p_mgmt_callback(res, p_port->inx, NULL);
|
||||
}
|
||||
|
||||
p_port->rfc.state = RFC_STATE_CLOSED;
|
||||
|
||||
RFCOMM_TRACE_WARNING ("%s RFCOMM connection in state %d closed: %s (res: %d)",
|
||||
__func__, p_port->state, PORT_GetResultString(res), res);
|
||||
RFCOMM_TRACE_WARNING("%s RFCOMM connection in server:%d state %d closed: %s (res: %d)",
|
||||
__func__, p_port->is_server, p_port->state, PORT_GetResultString(res),
|
||||
res);
|
||||
|
||||
port_release_port (p_port);
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ static void rfc_mx_conf_cnf (tRFC_MCB *p_mcb, tL2CAP_CFG_INFO *p_cfg);
|
||||
*******************************************************************************/
|
||||
void rfc_mx_sm_execute (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
|
||||
{
|
||||
RFCOMM_TRACE_DEBUG("%s st:%d, evt:%d\n", __func__, p_mcb->state, event);
|
||||
|
||||
switch (p_mcb->state) {
|
||||
case RFC_MX_STATE_IDLE:
|
||||
rfc_mx_sm_state_idle (p_mcb, event, p_data);
|
||||
|
||||
@@ -62,6 +62,8 @@ static void rfc_set_port_state(tPORT_STATE *port_pars, MX_FRAME *p_frame);
|
||||
*******************************************************************************/
|
||||
void rfc_port_sm_execute (tPORT *p_port, UINT16 event, void *p_data)
|
||||
{
|
||||
RFCOMM_TRACE_DEBUG("%s st:%d, evt:%d\n", __func__, p_port->rfc.state, event);
|
||||
|
||||
if (!p_port) {
|
||||
RFCOMM_TRACE_WARNING ("NULL port event %d", event);
|
||||
return;
|
||||
@@ -296,6 +298,11 @@ void rfc_port_sm_term_wait_sec_check (tPORT *p_port, UINT16 event, void *p_data)
|
||||
if (*((UINT8 *)p_data) != RFCOMM_SUCCESS) {
|
||||
if (p_port->rfc.p_mcb) {
|
||||
rfc_send_dm (p_port->rfc.p_mcb, p_port->dlci, TRUE);
|
||||
if (*((UINT8 *)p_data) == RFCOMM_LOW_RESOURCES) {
|
||||
port_rfc_closed(p_port, PORT_NO_RESOURCES);
|
||||
} else {
|
||||
port_rfc_closed(p_port, PORT_UNKNOWN_ERROR);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rfc_send_ua (p_port->rfc.p_mcb, p_port->dlci);
|
||||
|
||||
@@ -201,7 +201,6 @@ void osi_free_fun(void *p){
|
||||
*******************************************************************************/
|
||||
void rfc_release_multiplexer_channel (tRFC_MCB *p_mcb)
|
||||
{
|
||||
|
||||
rfc_timer_free (p_mcb);
|
||||
|
||||
fixed_queue_free(p_mcb->cmd_q, osi_free_fun);
|
||||
|
||||
@@ -1539,13 +1539,12 @@ void smp_idle_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
|
||||
*******************************************************************************/
|
||||
void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
|
||||
{
|
||||
#if (BT_MULTI_CONNECTION_ENBALE == FALSE)
|
||||
if(p_cb->role == BTM_ROLE_MASTER) {
|
||||
#if (BT_MULTI_CONNECTION_ENBALE == FALSE)
|
||||
L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#if (SMP_SLAVE_CON_PARAMS_UPD_ENABLE == TRUE)
|
||||
else {
|
||||
tBTM_SEC_DEV_REC *p_rec = btm_find_dev (p_cb->pairing_bda);
|
||||
if(p_rec && p_rec->ble.skip_update_conn_param) {
|
||||
//do nothing
|
||||
@@ -1558,8 +1557,8 @@ void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
|
||||
#if (BT_MULTI_CONNECTION_ENBALE == FALSE)
|
||||
L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Submodule components/bt/host/nimble/nimble updated: a4f3ace1e7...1dc1ec6e76
@@ -26,7 +26,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP_BT_CTRL_CONFIG_MAGIC_VAL 0x5A5AA5A5
|
||||
#define ESP_BT_CTRL_CONFIG_VERSION 0x02104270
|
||||
#define ESP_BT_CTRL_CONFIG_VERSION 0x02112280
|
||||
|
||||
#define ESP_BT_HCI_TL_MAGIC_VALUE 0xfadebead
|
||||
#define ESP_BT_HCI_TL_VERSION 0x00010000
|
||||
@@ -179,6 +179,7 @@ enum {
|
||||
.hw_target_code = BLE_HW_TARGET_CODE_ESP32C3_CHIP_ECO0, \
|
||||
.slave_ce_len_min = SLAVE_CE_LEN_MIN_DEFAULT, \
|
||||
.hw_recorrect_en = AGC_RECORRECT_EN, \
|
||||
.cca_thresh = CONFIG_BT_CTRL_HW_CCA_VAL, \
|
||||
};
|
||||
|
||||
#else
|
||||
@@ -245,6 +246,7 @@ typedef struct {
|
||||
uint32_t hw_target_code; /*!< hardware target */
|
||||
uint8_t slave_ce_len_min;
|
||||
uint8_t hw_recorrect_en;
|
||||
uint8_t cca_thresh; /*!< cca threshold*/
|
||||
} esp_bt_controller_config_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,37 +1,6 @@
|
||||
# sdkconfig replacement configurations for deprecated options formatted as
|
||||
# CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION
|
||||
|
||||
CONFIG_BTDM_CONTROLLER_MODE CONFIG_BTDM_CTRL_MODE
|
||||
CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY CONFIG_BTDM_CTRL_MODE_BLE_ONLY
|
||||
CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY
|
||||
CONFIG_BTDM_CONTROLLER_MODE_BTDM CONFIG_BTDM_CTRL_MODE_BTDM
|
||||
CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN CONFIG_BTDM_CTRL_BLE_MAX_CONN
|
||||
CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN
|
||||
CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN
|
||||
CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF
|
||||
CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF
|
||||
CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF
|
||||
CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_CHOICE CONFIG_BTDM_CTRL_PINNED_TO_CORE_CHOICE
|
||||
CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE CONFIG_BTDM_CTRL_PINNED_TO_CORE
|
||||
CONFIG_BTDM_CONTROLLER_HCI_MODE_CHOICE CONFIG_BTDM_CTRL_HCI_MODE_CHOICE
|
||||
CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI CONFIG_BTDM_CTRL_HCI_MODE_VHCI
|
||||
CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4 CONFIG_BTDM_CTRL_HCI_MODE_UART_H4
|
||||
|
||||
CONFIG_BTDM_CONTROLLER_MODEM_SLEEP CONFIG_BTDM_CTRL_MODEM_SLEEP
|
||||
|
||||
CONFIG_BLE_SCAN_DUPLICATE CONFIG_BTDM_BLE_SCAN_DUPL
|
||||
CONFIG_SCAN_DUPLICATE_TYPE CONFIG_BTDM_SCAN_DUPL_TYPE
|
||||
CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE
|
||||
CONFIG_SCAN_DUPLICATE_BY_ADV_DATA CONFIG_BTDM_SCAN_DUPL_TYPE_DATA
|
||||
CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE
|
||||
CONFIG_DUPLICATE_SCAN_CACHE_SIZE CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE
|
||||
CONFIG_BLE_MESH_SCAN_DUPLICATE_EN CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN
|
||||
CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE CONFIG_BTDM_MESH_DUPL_SCAN_CACHE_SIZE
|
||||
CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED
|
||||
CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP
|
||||
CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM
|
||||
CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD
|
||||
|
||||
CONFIG_BLUEDROID_ENABLED CONFIG_BT_BLUEDROID_ENABLED
|
||||
CONFIG_BLUEDROID_PINNED_TO_CORE_CHOICE CONFIG_BT_BLUEDROID_PINNED_TO_CORE_CHOICE
|
||||
CONFIG_BLUEDROID_PINNED_TO_CORE CONFIG_BT_BLUEDROID_PINNED_TO_CORE
|
||||
|
||||
@@ -114,6 +114,21 @@ typedef struct {
|
||||
{ \
|
||||
}
|
||||
|
||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||
/**
|
||||
* @brief Parameters for console device: USB-SERIAL-JTAG
|
||||
*
|
||||
* @note It's an empty structure for now, reserved for future
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
} esp_console_dev_usb_serial_jtag_config_t;
|
||||
|
||||
#define ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT() {}
|
||||
|
||||
#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||
|
||||
/**
|
||||
* @brief initialize console module
|
||||
* @param config console configuration
|
||||
@@ -339,6 +354,29 @@ esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_con
|
||||
*/
|
||||
esp_err_t esp_console_new_repl_usb_cdc(const esp_console_dev_usb_cdc_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl);
|
||||
|
||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||
/**
|
||||
* @brief Establish a console REPL (Read-eval-print loop) environment over USB-SERIAL-JTAG
|
||||
*
|
||||
* @param[in] dev_config USB-SERIAL-JTAG configuration
|
||||
* @param[in] repl_config REPL configuration
|
||||
* @param[out] ret_repl return REPL handle after initialization succeed, return NULL otherwise
|
||||
*
|
||||
* @note This is a all-in-one function to establish the environment needed for REPL, includes:
|
||||
* - Initializes linenoise
|
||||
* - Spawn new thread to run REPL in the background
|
||||
*
|
||||
* @attention This function is meant to be used in the examples to make the code more compact.
|
||||
* Applications which use console functionality should be based on
|
||||
* the underlying linenoise and esp_console functions.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_FAIL Parameter error
|
||||
*/
|
||||
esp_err_t esp_console_new_repl_usb_serial_jtag(const esp_console_dev_usb_serial_jtag_config_t *dev_config, const esp_console_repl_config_t *repl_config, esp_console_repl_t **ret_repl);
|
||||
#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||
|
||||
/**
|
||||
* @brief Start REPL environment
|
||||
* @param[in] repl REPL handle returned from esp_console_new_repl_xxx
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user