forked from espressif/esp-idf
Compare commits
416 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
405b1986c2 | ||
|
|
7c42b55e45 | ||
|
|
f4022111c8 | ||
|
|
53dcd1202d | ||
|
|
ef2c0e8b3e | ||
|
|
7515dc97b6 | ||
|
|
a9c1820385 | ||
|
|
8fdf200932 | ||
|
|
4cde212817 | ||
|
|
6751373411 | ||
|
|
27fd353752 | ||
|
|
97603b1d59 | ||
|
|
32fd3a3215 | ||
|
|
d1c6eb9574 | ||
|
|
5ee2d3b90d | ||
|
|
8618b452f7 | ||
|
|
39fb5d7150 | ||
|
|
5dafcf9363 | ||
|
|
3f72a12d97 | ||
|
|
af4f2ace84 | ||
|
|
e8ad0415cc | ||
|
|
ac253274a0 | ||
|
|
972107fbc9 | ||
|
|
5e9267f846 | ||
|
|
cfed7c84ce | ||
|
|
3870836a90 | ||
|
|
19f319a55d | ||
|
|
0806617971 | ||
|
|
4f346169ff | ||
|
|
00b895680e | ||
|
|
997d291d85 | ||
|
|
5f2660e1f5 | ||
|
|
451e4cf3b0 | ||
|
|
132b439359 | ||
|
|
04ce9050b6 | ||
|
|
27f8ee6b97 | ||
|
|
1c001ecd7a | ||
|
|
a961984f73 | ||
|
|
2d53799372 | ||
|
|
7275490322 | ||
|
|
f6a7cda7b6 | ||
|
|
d88b74064d | ||
|
|
b9f6b579f1 | ||
|
|
72ad5a142b | ||
|
|
d07f9dfbb2 | ||
|
|
33250ea678 | ||
|
|
300657162b | ||
|
|
7fcc76fa06 | ||
|
|
85fbaaf37a | ||
|
|
da97846483 | ||
|
|
7aa29a0dbb | ||
|
|
516d9f0eae | ||
|
|
bb5789b6ee | ||
|
|
f206bc51ff | ||
|
|
ecc82a3c27 | ||
|
|
6746be5a09 | ||
|
|
007d884a85 | ||
|
|
998416c54b | ||
|
|
873c515ee3 | ||
|
|
ee295c175b | ||
|
|
25ed0aa9bb | ||
|
|
4b4614ffb1 | ||
|
|
21adda8777 | ||
|
|
8ff0f4a616 | ||
|
|
08946da2db | ||
|
|
90b8a42349 | ||
|
|
3c92cd607b | ||
|
|
4f3008bfd8 | ||
|
|
dd1fa7c502 | ||
|
|
50556b8acb | ||
|
|
9da0541020 | ||
|
|
ab74be7abe | ||
|
|
b5c45a4d46 | ||
|
|
225e98dcee | ||
|
|
d66b227e07 | ||
|
|
ce67428c56 | ||
|
|
054e82b4b3 | ||
|
|
7d4a9db191 | ||
|
|
39f97bb4e8 | ||
|
|
8f81157432 | ||
|
|
5141570f24 | ||
|
|
f86d512672 | ||
|
|
ab341359f5 | ||
|
|
f98da26b38 | ||
|
|
d0cd624d2b | ||
|
|
c8c4bd099e | ||
|
|
36c14cf214 | ||
|
|
a7c9cf3a6b | ||
|
|
9aee394dc6 | ||
|
|
05eb9d155f | ||
|
|
0669fe8f02 | ||
|
|
cabb97f9a9 | ||
|
|
41b1db4dc6 | ||
|
|
8bc76b3684 | ||
|
|
245b753904 | ||
|
|
86a6c21e79 | ||
|
|
8cc0379da1 | ||
|
|
e56bfadc58 | ||
|
|
583e80708b | ||
|
|
5cf4d8a1ec | ||
|
|
ef3c6ac276 | ||
|
|
4129436f7e | ||
|
|
0808a04ee8 | ||
|
|
c99977b67c | ||
|
|
8d3d3fdd4a | ||
|
|
c4973908e4 | ||
|
|
3bb43d5f03 | ||
|
|
209d454b5f | ||
|
|
b385fe0586 | ||
|
|
487c4b6725 | ||
|
|
667846cba1 | ||
|
|
ccbb261c35 | ||
|
|
f35fd2a6b0 | ||
|
|
5682a5ef36 | ||
|
|
b66af09b75 | ||
|
|
9b5841f17c | ||
|
|
103de7acdc | ||
|
|
c2b39f4a5f | ||
|
|
2bd198d180 | ||
|
|
5b2fee13cd | ||
|
|
6ceedabb27 | ||
|
|
dac71d688a | ||
|
|
dc304fb3af | ||
|
|
6ae56b61cf | ||
|
|
6698be57c8 | ||
|
|
ef9dbff112 | ||
|
|
561f8ff513 | ||
|
|
945d2e697c | ||
|
|
94c4f32df0 | ||
|
|
ab62202eb9 | ||
|
|
063c23deff | ||
|
|
3868307efd | ||
|
|
e0c834285f | ||
|
|
e99b4e85b9 | ||
|
|
20ab122f80 | ||
|
|
98dd235819 | ||
|
|
94ec3c8e53 | ||
|
|
7535dbc454 | ||
|
|
aeb4d8e3c2 | ||
|
|
ba13d282dd | ||
|
|
806d23b17b | ||
|
|
e410f4268e | ||
|
|
8de29499ce | ||
|
|
ffab6084f0 | ||
|
|
f58c664e2b | ||
|
|
b42ba1b0a5 | ||
|
|
67ba85650d | ||
|
|
0a97cb62ef | ||
|
|
594e1b5e44 | ||
|
|
10a5cfc900 | ||
|
|
e4a840d8cf | ||
|
|
7a32ae363e | ||
|
|
fddc905fa3 | ||
|
|
574dd08085 | ||
|
|
7705126287 | ||
|
|
bf4184a049 | ||
|
|
212222a9e0 | ||
|
|
6d3f81aa77 | ||
|
|
489e98cfb7 | ||
|
|
8d0d7972f3 | ||
|
|
e6acfedd3c | ||
|
|
0f5cae0218 | ||
|
|
712bd1d773 | ||
|
|
4e36ede3bf | ||
|
|
2f2aa41ea7 | ||
|
|
089438139d | ||
|
|
e468a105d8 | ||
|
|
894ddea353 | ||
|
|
fed3c3ebf0 | ||
|
|
f8515688cb | ||
|
|
b9dab23437 | ||
|
|
5632385d5f | ||
|
|
cfcb22fe16 | ||
|
|
d6e3943233 | ||
|
|
b563219f93 | ||
|
|
d881fcd380 | ||
|
|
058a38a141 | ||
|
|
ffe6af44c1 | ||
|
|
1fca253a65 | ||
|
|
486ff50eac | ||
|
|
cf69dfa458 | ||
|
|
501640514a | ||
|
|
a80e687f8c | ||
|
|
bc90b89e2b | ||
|
|
a1cc202b70 | ||
|
|
062ba57d0f | ||
|
|
14baac302f | ||
|
|
af211fcf0c | ||
|
|
5ee7233b5b | ||
|
|
48c7afde27 | ||
|
|
d3bab0d7f0 | ||
|
|
c9ed467e26 | ||
|
|
f0eb023f17 | ||
|
|
8944b90a06 | ||
|
|
9e4ec90a1e | ||
|
|
e4357d9cf3 | ||
|
|
db17ffef00 | ||
|
|
7f2a9f0359 | ||
|
|
ecdeea9a85 | ||
|
|
cfce9e1c72 | ||
|
|
dfce994b54 | ||
|
|
1b78dc2deb | ||
|
|
37a4b0e933 | ||
|
|
8fab9ffb95 | ||
|
|
354137a313 | ||
|
|
0399c8ecaf | ||
|
|
a12e7fa638 | ||
|
|
3278f755d2 | ||
|
|
30281166b1 | ||
|
|
9bd227f8c5 | ||
|
|
80423d638d | ||
|
|
998e18ed69 | ||
|
|
d0e553358a | ||
|
|
0cdb8b4888 | ||
|
|
c1e4ebf2bc | ||
|
|
71ca4c50b0 | ||
|
|
56d82dd5ce | ||
|
|
c4a6eef841 | ||
|
|
05b5671fc4 | ||
|
|
d3646ca59f | ||
|
|
0cb7b27f8b | ||
|
|
2319e8a0eb | ||
|
|
bc12970dde | ||
|
|
7a863cca7c | ||
|
|
9c42b6194e | ||
|
|
3511109b6e | ||
|
|
acff7e58d2 | ||
|
|
0f45323879 | ||
|
|
48ea4bc7f4 | ||
|
|
69686ae8a9 | ||
|
|
28cb5624ef | ||
|
|
c82adcae1b | ||
|
|
c574ad90df | ||
|
|
1d03398a64 | ||
|
|
daf1d05576 | ||
|
|
816a98c3ad | ||
|
|
ebfc47c34b | ||
|
|
681805b6c7 | ||
|
|
392b0b89e3 | ||
|
|
229be8c025 | ||
|
|
e4fb19000a | ||
|
|
0e640c61bd | ||
|
|
ce64bcb81f | ||
|
|
5e48c2bfef | ||
|
|
55c179a599 | ||
|
|
1181b65f7d | ||
|
|
3b116ae0cb | ||
|
|
54b595ed51 | ||
|
|
cf2600adef | ||
|
|
f7eecfcc67 | ||
|
|
eac9eb36d1 | ||
|
|
ec05f3af8f | ||
|
|
9bfb2f0cab | ||
|
|
963fa0fd3a | ||
|
|
8856cc055a | ||
|
|
fab14106c8 | ||
|
|
154294e79f | ||
|
|
e1d965e4b9 | ||
|
|
673d4679ce | ||
|
|
95f6f88aa7 | ||
|
|
621794abb5 | ||
|
|
f918cb185d | ||
|
|
ab22836859 | ||
|
|
9539d44158 | ||
|
|
b6b8af498c | ||
|
|
194b1324d2 | ||
|
|
7a030ff8d6 | ||
|
|
d9a0f9d443 | ||
|
|
3a6be05945 | ||
|
|
d1c536258c | ||
|
|
5a1247246c | ||
|
|
45758b6be0 | ||
|
|
6183de959a | ||
|
|
e9a4eb57b9 | ||
|
|
5894e15f6b | ||
|
|
891c1f4a2b | ||
|
|
f5c962d8b2 | ||
|
|
6aff7125cb | ||
|
|
c68fd9d545 | ||
|
|
d6c06ed0b5 | ||
|
|
8baa6b9d8b | ||
|
|
3923a2be85 | ||
|
|
e7dc749e2f | ||
|
|
df93f672e3 | ||
|
|
4a55009f3e | ||
|
|
dfcff0a5bf | ||
|
|
ff3566e40b | ||
|
|
63eb620d99 | ||
|
|
93c18bb2b4 | ||
|
|
3c6bce1d81 | ||
|
|
90b9c42dc0 | ||
|
|
c5f63bf701 | ||
|
|
ced95c7fb0 | ||
|
|
309fb23ffc | ||
|
|
e9a230c20c | ||
|
|
b0c7f28aed | ||
|
|
7bc1e7608c | ||
|
|
449ce1bad9 | ||
|
|
424a5e2705 | ||
|
|
d8f311c980 | ||
|
|
9b0c252e67 | ||
|
|
2a55629556 | ||
|
|
b523660199 | ||
|
|
150be549eb | ||
|
|
10898a33ed | ||
|
|
dddfc61411 | ||
|
|
404a6b3782 | ||
|
|
29f999361e | ||
|
|
32eeac0b12 | ||
|
|
7d3e8998d8 | ||
|
|
e276b98fe4 | ||
|
|
de7381b77e | ||
|
|
645d9b9590 | ||
|
|
2ad618e068 | ||
|
|
eb408e50c4 | ||
|
|
60da98ee0b | ||
|
|
314f6f371c | ||
|
|
6c69d5e6fd | ||
|
|
90ea0bb7e8 | ||
|
|
6ba817038c | ||
|
|
e54f8a96a0 | ||
|
|
2f9edfebac | ||
|
|
27c28eb1e6 | ||
|
|
6f339ff7a5 | ||
|
|
2cc07d0c4c | ||
|
|
da81b97e17 | ||
|
|
15e65aad1b | ||
|
|
281874d380 | ||
|
|
3f3d8746fc | ||
|
|
b278deabdb | ||
|
|
9065498a5a | ||
|
|
012f5c608d | ||
|
|
c695a4e468 | ||
|
|
755b163d4e | ||
|
|
b19b8702fd | ||
|
|
bd2ff0613d | ||
|
|
b6ebbb5662 | ||
|
|
38d58f1c2e | ||
|
|
ecc6080117 | ||
|
|
e589cad07e | ||
|
|
44764222a5 | ||
|
|
b6ee7f699c | ||
|
|
9b57d4aa0d | ||
|
|
60a642b31c | ||
|
|
48fda0f27b | ||
|
|
33ca8874d4 | ||
|
|
c884931b0b | ||
|
|
41baf59287 | ||
|
|
87f7d1875d | ||
|
|
545c7e5cdd | ||
|
|
ef6fe211b8 | ||
|
|
50637f638f | ||
|
|
c4b861ad65 | ||
|
|
492b926d50 | ||
|
|
b5f8cf0f03 | ||
|
|
c4bb528c61 | ||
|
|
a0bdee0c9c | ||
|
|
c015dd6c41 | ||
|
|
5afafb0050 | ||
|
|
ff008d2be3 | ||
|
|
84bfc96f08 | ||
|
|
0448ee9685 | ||
|
|
42e411dafc | ||
|
|
fbff8eb95b | ||
|
|
c778951547 | ||
|
|
a0776b2f21 | ||
|
|
ae30d1bc7b | ||
|
|
28e4162dd2 | ||
|
|
242f8ea743 | ||
|
|
5c1506f796 | ||
|
|
103559153f | ||
|
|
d340088993 | ||
|
|
e8fbd6e288 | ||
|
|
50b710d267 | ||
|
|
f4554c81fc | ||
|
|
96be8f2efa | ||
|
|
033124be14 | ||
|
|
b4c1bdb11b | ||
|
|
acc9b871d1 | ||
|
|
cb9be8c0c4 | ||
|
|
8388e1be54 | ||
|
|
5960e7419d | ||
|
|
21912b95f4 | ||
|
|
3085eb7ec6 | ||
|
|
8ed44ace4b | ||
|
|
58accf05cf | ||
|
|
6f90393f22 | ||
|
|
66fe94f816 | ||
|
|
df6adbd5bf | ||
|
|
ce3ccc18fa | ||
|
|
36d6e4e2c7 | ||
|
|
a4d45a0a4d | ||
|
|
38170d465c | ||
|
|
ccea4a0f8f | ||
|
|
954c0981d8 | ||
|
|
de79de1c26 | ||
|
|
194e1835c2 | ||
|
|
17ac80867b | ||
|
|
05605920ae | ||
|
|
121e5a7847 | ||
|
|
031ab556a9 | ||
|
|
4837f93968 | ||
|
|
717b1697df | ||
|
|
b5942dc400 | ||
|
|
72d4de442a | ||
|
|
485e254719 | ||
|
|
0ebae99ab0 | ||
|
|
7e488b0c6b | ||
|
|
3a4cf72f30 | ||
|
|
6e0f905761 | ||
|
|
489f5efbd1 | ||
|
|
3a70e61477 | ||
|
|
043ef32651 | ||
|
|
eae3b45170 | ||
|
|
a1c79bbc7b | ||
|
|
cc46b5054a |
@@ -32,8 +32,3 @@ insert_final_newline = false
|
||||
|
||||
[*.py]
|
||||
max_line_length = 119
|
||||
|
||||
[{*.cmake,CMakeLists.txt}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
max_line_length = 120
|
||||
|
||||
36
.gitignore
vendored
36
.gitignore
vendored
@@ -18,23 +18,18 @@ GPATH
|
||||
# eclipse setting
|
||||
.settings
|
||||
|
||||
# MacOS directory files
|
||||
.DS_Store
|
||||
|
||||
# Example project files
|
||||
examples/**/sdkconfig
|
||||
examples/**/sdkconfig.old
|
||||
examples/**/build
|
||||
|
||||
# Doc build artifacts
|
||||
docs/*/_build/
|
||||
docs/*/doxygen-warning-log.txt
|
||||
docs/*/sphinx-warning-log.txt
|
||||
docs/*/sphinx-warning-log-sanitized.txt
|
||||
docs/*/xml/
|
||||
docs/*/xml_in/
|
||||
docs/*/man/
|
||||
docs/doxygen_sqlite3.db
|
||||
#Doc build artifacts
|
||||
docs/_build/
|
||||
docs/doxygen-warning-log.txt
|
||||
docs/sphinx-warning-log.txt
|
||||
docs/sphinx-warning-log-sanitized.txt
|
||||
docs/xml/
|
||||
docs/man/
|
||||
|
||||
# Unit test app files
|
||||
tools/unit-test-app/sdkconfig
|
||||
@@ -43,11 +38,6 @@ tools/unit-test-app/build
|
||||
tools/unit-test-app/builds
|
||||
tools/unit-test-app/output
|
||||
|
||||
# IDF monitor test
|
||||
tools/test_idf_monitor/outputs
|
||||
|
||||
TEST_LOGS
|
||||
|
||||
# AWS IoT Examples require device-specific certs/keys
|
||||
examples/protocols/aws_iot/*/main/certs/*.pem.*
|
||||
|
||||
@@ -56,15 +46,3 @@ examples/protocols/aws_iot/*/main/certs/*.pem.*
|
||||
*.gcno
|
||||
coverage.info
|
||||
coverage_report/
|
||||
|
||||
# Windows tools installer build
|
||||
tools/windows/tool_setup/.*
|
||||
tools/windows/tool_setup/input
|
||||
tools/windows/tool_setup/dl
|
||||
tools/windows/tool_setup/keys
|
||||
tools/windows/tool_setup/Output
|
||||
|
||||
test_multi_heap_host
|
||||
|
||||
# VS Code Settings
|
||||
.vscode/
|
||||
|
||||
1562
.gitlab-ci.yml
1562
.gitlab-ci.yml
File diff suppressed because it is too large
Load Diff
24
.gitmodules
vendored
24
.gitmodules
vendored
@@ -37,27 +37,3 @@
|
||||
[submodule "components/json/cJSON"]
|
||||
path = components/json/cJSON
|
||||
url = https://github.com/DaveGamble/cJSON.git
|
||||
|
||||
[submodule "components/mbedtls/mbedtls"]
|
||||
path = components/mbedtls/mbedtls
|
||||
url = https://github.com/espressif/mbedtls.git
|
||||
|
||||
[submodule "components/asio/asio"]
|
||||
path = components/asio/asio
|
||||
url = https://github.com/espressif/asio.git
|
||||
|
||||
[submodule "components/expat/expat"]
|
||||
path = components/expat/expat
|
||||
url = https://github.com/libexpat/libexpat.git
|
||||
|
||||
[submodule "components/lwip/lwip"]
|
||||
path = components/lwip/lwip
|
||||
url = https://github.com/espressif/esp-lwip.git
|
||||
|
||||
[submodule "components/mqtt/esp-mqtt"]
|
||||
path = components/mqtt/esp-mqtt
|
||||
url = https://github.com/espressif/esp-mqtt.git
|
||||
|
||||
[submodule "components/protobuf-c/protobuf-c"]
|
||||
path = components/protobuf-c/protobuf-c
|
||||
url = https://github.com/protobuf-c/protobuf-c
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# .readthedocs.yml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Optionally build your docs in additional formats such as PDF and ePub
|
||||
formats:
|
||||
- htmlzip
|
||||
- pdf
|
||||
|
||||
# Optionally set the version of Python and requirements required to build your docs
|
||||
python:
|
||||
version: 2.7
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
@@ -25,8 +25,6 @@ Before sending us a Pull Request, please consider this list of points:
|
||||
|
||||
* Are comments and documentation written in clear English, with no spelling or grammar errors?
|
||||
|
||||
* Example contributions are also welcome. Please check the :doc:`creating-examples` guide for these.
|
||||
|
||||
* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" `squashed into previous commits <http://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/>`_?
|
||||
|
||||
* If you're unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback.
|
||||
@@ -53,6 +51,5 @@ Related Documents
|
||||
|
||||
style-guide
|
||||
documenting-code
|
||||
creating-examples
|
||||
../api-reference/template
|
||||
contributor-agreement
|
||||
contributor-agreement
|
||||
49
Kconfig
49
Kconfig
@@ -4,9 +4,6 @@
|
||||
#
|
||||
mainmenu "Espressif IoT Development Framework Configuration"
|
||||
|
||||
config IDF_CMAKE
|
||||
bool
|
||||
option env="IDF_CMAKE"
|
||||
|
||||
menu "SDK tool configuration"
|
||||
config TOOLPREFIX
|
||||
@@ -18,15 +15,11 @@ config TOOLPREFIX
|
||||
|
||||
config PYTHON
|
||||
string "Python 2 interpreter"
|
||||
depends on !IDF_CMAKE
|
||||
default "python"
|
||||
help
|
||||
The executable name/path that is used to run python. On some systems Python 2.x
|
||||
may need to be invoked as python2.
|
||||
|
||||
(Note: This option is used with the GNU Make build system only, not idf.py
|
||||
or CMake-based builds.)
|
||||
|
||||
config MAKE_WARN_UNDEFINED_VARIABLES
|
||||
bool "'make' warns on undefined variables"
|
||||
default "y"
|
||||
@@ -71,7 +64,6 @@ choice OPTIMIZATION_ASSERTION_LEVEL
|
||||
default OPTIMIZATION_ASSERTIONS_ENABLED
|
||||
help
|
||||
Assertions can be:
|
||||
|
||||
- Enabled. Failure will print verbose assertion details. This is the default.
|
||||
|
||||
- Set to "silent" to save code size (failed assertions will abort() but user
|
||||
@@ -129,21 +121,15 @@ choice STACK_CHECK_MODE
|
||||
smashing attacks. This is done by adding a guard variable to functions with vulnerable objects.
|
||||
The guards are initialized when a function is entered and then checked when the function exits.
|
||||
If a guard check fails, program is halted. Protection has the following modes:
|
||||
|
||||
- In NORMAL mode (GCC flag: -fstack-protector) only functions that call alloca,
|
||||
and functions with buffers larger than 8 bytes are protected.
|
||||
|
||||
- STRONG mode (GCC flag: -fstack-protector-strong) is like NORMAL, but includes
|
||||
additional functions to be protected -- those that have local array definitions,
|
||||
or have references to local frame addresses.
|
||||
|
||||
- In OVERALL mode (GCC flag: -fstack-protector-all) all functions are protected.
|
||||
- In NORMAL mode (GCC flag: -fstack-protector) only functions that call alloca, and functions with buffers larger than
|
||||
8 bytes are protected.
|
||||
- STRONG mode (GCC flag: -fstack-protector-strong) is like NORMAL, but includes additional functions to be protected -- those that
|
||||
have local array definitions, or have references to local frame addresses.
|
||||
- In OVERALL mode (GCC flag: -fstack-protector-all) all functions are protected.
|
||||
|
||||
Modes have the following impact on code performance and coverage:
|
||||
|
||||
- performance: NORMAL > STRONG > OVERALL
|
||||
|
||||
- coverage: NORMAL < STRONG < OVERALL
|
||||
- performance: NORMAL > STRONG > OVERALL
|
||||
- coverage: NORMAL < STRONG < OVERALL
|
||||
|
||||
|
||||
config STACK_CHECK_NONE
|
||||
@@ -162,27 +148,6 @@ config STACK_CHECK
|
||||
help
|
||||
Stack smashing protection.
|
||||
|
||||
config WARN_WRITE_STRINGS
|
||||
bool "Enable -Wwrite-strings warning flag"
|
||||
default "n"
|
||||
help
|
||||
Adds -Wwrite-strings flag for the C/C++ compilers.
|
||||
|
||||
For C, this gives string constants the type ``const char[]`` so that
|
||||
copying the address of one into a non-const ``char *`` pointer
|
||||
produces a warning. This warning helps to find at compile time code
|
||||
that tries to write into a string constant.
|
||||
|
||||
For C++, this warns about the deprecated conversion from string
|
||||
literals to ``char *``.
|
||||
|
||||
config DISABLE_GCC8_WARNINGS
|
||||
bool "Disable new warnings introduced in GCC 6 - 8"
|
||||
default "n"
|
||||
help
|
||||
Enable this option if using GCC 6 or newer, and wanting to disable warnings which don't appear with GCC 5.
|
||||
|
||||
|
||||
endmenu # Compiler Options
|
||||
|
||||
menu "Component config"
|
||||
|
||||
13
README.md
13
README.md
@@ -1,6 +1,6 @@
|
||||
# Espressif IoT Development Framework
|
||||
|
||||
[](https://docs.espressif.com/projects/esp-idf/en/latest/?badge=latest)
|
||||
[](https://esp-idf.readthedocs.io/en/latest/?badge=latest)
|
||||
|
||||
ESP-IDF is the official development framework for the [ESP32](https://espressif.com/en/products/hardware/esp32/overview) chip.
|
||||
|
||||
@@ -49,7 +49,7 @@ NOTE: The `-j4` option causes `make` to run 4 parallel jobs. This is much faster
|
||||
|
||||
## Flashing the Project
|
||||
|
||||
When the build finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this automatically by running:
|
||||
When `make all` finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this from make by running:
|
||||
|
||||
`make -j4 flash`
|
||||
|
||||
@@ -59,7 +59,7 @@ You don't need to run `make all` before running `make flash`, `make flash` will
|
||||
|
||||
## Viewing Serial Output
|
||||
|
||||
The `make monitor` target uses the [idf_monitor tool](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html) to display serial output from the ESP32. idf_monitor also has a range of features to decode crash output and interact with the device. [Check the documentation page for details](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html).
|
||||
The `make monitor` target uses the [idf_monitor tool](https://esp-idf.readthedocs.io/en/latest/get-started/idf-monitor.html) to display serial output from the ESP32. idf_monitor also has a range of features to decode crash output and interact with the device. [Check the documentation page for details](https://esp-idf.readthedocs.io/en/latest/get-started/idf-monitor.html).
|
||||
|
||||
Exit the monitor by typing Ctrl-].
|
||||
|
||||
@@ -88,7 +88,6 @@ Multiple make functions can be combined into one. For example: to build the app
|
||||
make -j5 flash monitor
|
||||
```
|
||||
|
||||
|
||||
## The Partition Table
|
||||
|
||||
Once you've compiled your project, the "build" directory will contain a binary file with a name like "my_app.bin". This is an ESP32 image binary that can be loaded by the bootloader.
|
||||
@@ -104,7 +103,7 @@ The simplest way to use the partition table is to `make menuconfig` and choose o
|
||||
|
||||
In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table.
|
||||
|
||||
For more details about partition tables and how to create custom variations, view the [`docs/en/api-guides/partition-tables.rst`](docs/en/api-guides/partition-tables.rst) file.
|
||||
For more details about partition tables and how to create custom variations, view the [`docs/api-guides/partition-tables.rst`](docs/api-guides/partition-tables.rst) file.
|
||||
|
||||
## Erasing Flash
|
||||
|
||||
@@ -114,12 +113,12 @@ This can be combined with other targets, ie `make erase_flash flash` will erase
|
||||
|
||||
# Resources
|
||||
|
||||
* Documentation for the latest version: https://docs.espressif.com/projects/esp-idf/. This documentation is built from the [docs directory](docs) of this repository.
|
||||
* Documentation for the latest version: https://esp-idf.readthedocs.io/. This documentation is built from the [docs directory](docs) of this repository.
|
||||
|
||||
* The [esp32.com forum](https://esp32.com/) is a place to ask questions and find community resources.
|
||||
|
||||
* [Check the Issues section on github](https://github.com/espressif/esp-idf/issues) if you find a bug or have a feature request. Please check existing Issues before opening a new one.
|
||||
|
||||
* If you're interested in contributing to ESP-IDF, please check the [Contributions Guide](https://docs.espressif.com/projects/esp-idf/en/latest/contribute/index.html).
|
||||
* If you're interested in contributing to ESP-IDF, please check the [Contributions Guide](https://esp-idf.readthedocs.io/en/latest/contribute/index.html).
|
||||
|
||||
|
||||
|
||||
@@ -9,11 +9,8 @@
|
||||
if [ -z ${IDF_PATH} ]; then
|
||||
echo "IDF_PATH must be set before including this script."
|
||||
else
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/components/esptool_py/esptool"
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/components/espcoredump"
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/components/partition_table/"
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/tools/"
|
||||
export PATH="${IDF_ADD_PATHS_EXTRAS}:${PATH}"
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_PATH}/components/esptool_py/esptool:${IDF_PATH}/components/espcoredump:${IDF_PATH}/components/partition_table/"
|
||||
export PATH="${PATH}:${IDF_ADD_PATHS_EXTRAS}"
|
||||
echo "Added to PATH: ${IDF_ADD_PATHS_EXTRAS}"
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
set(COMPONENT_SRCS "app_trace.c"
|
||||
"app_trace_util.c"
|
||||
"host_file_io.c"
|
||||
"gcov/gcov_rtio.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||
|
||||
if(CONFIG_SYSVIEW_ENABLE)
|
||||
list(APPEND COMPONENT_ADD_INCLUDEDIRS
|
||||
sys_view/Config
|
||||
sys_view/SEGGER
|
||||
sys_view/Sample/OS)
|
||||
|
||||
list(APPEND COMPONENT_SRCS "sys_view/SEGGER/SEGGER_SYSVIEW.c"
|
||||
"sys_view/Sample/Config/SEGGER_SYSVIEW_Config_FreeRTOS.c"
|
||||
"sys_view/Sample/OS/SEGGER_SYSVIEW_FreeRTOS.c"
|
||||
"sys_view/esp32/SEGGER_RTT_esp32.c")
|
||||
endif()
|
||||
|
||||
set(COMPONENT_REQUIRES)
|
||||
set(COMPONENT_PRIV_REQUIRES xtensa-debug-module)
|
||||
|
||||
register_component()
|
||||
|
||||
# disable --coverage for this component, as it is used as transport
|
||||
# for gcov
|
||||
component_compile_options("-fno-profile-arcs" "-fno-test-coverage")
|
||||
|
||||
target_link_libraries(app_trace gcov)
|
||||
@@ -56,7 +56,6 @@ config ESP32_APPTRACE_PENDING_DATA_SIZE_MAX
|
||||
events will be discarded when main HW buffer is full.
|
||||
|
||||
menu "FreeRTOS SystemView Tracing"
|
||||
depends on ESP32_APPTRACE_ENABLE
|
||||
config SYSVIEW_ENABLE
|
||||
bool "SystemView Tracing Enable"
|
||||
depends on ESP32_APPTRACE_ENABLE
|
||||
@@ -191,12 +190,4 @@ config SYSVIEW_EVT_TIMER_EXIT_ENABLE
|
||||
Enables "Timer Exit" event.
|
||||
|
||||
endmenu
|
||||
|
||||
config ESP32_GCOV_ENABLE
|
||||
bool "GCOV to Host Enable"
|
||||
depends on ESP32_DEBUG_STUBS_ENABLE && ESP32_APPTRACE_ENABLE && !SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables support for GCOV data transfer to host.
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -156,7 +156,6 @@
|
||||
// ALSO SEE example usage of application tracing module in 'components/app_trace/README.rst'
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "eri.h"
|
||||
@@ -336,8 +335,6 @@ typedef struct {
|
||||
uint8_t *(*get_down_buffer)(uint32_t *, esp_apptrace_tmo_t *);
|
||||
esp_err_t (*put_down_buffer)(uint8_t *, esp_apptrace_tmo_t *);
|
||||
bool (*host_is_connected)(void);
|
||||
esp_err_t (*status_reg_set)(uint32_t val);
|
||||
esp_err_t (*status_reg_get)(uint32_t *val);
|
||||
} esp_apptrace_hw_t;
|
||||
|
||||
static uint32_t esp_apptrace_trax_down_buffer_write_nolock(uint8_t *data, uint32_t size);
|
||||
@@ -347,8 +344,6 @@ static esp_err_t esp_apptrace_trax_put_buffer(uint8_t *ptr, esp_apptrace_tmo_t *
|
||||
static bool esp_apptrace_trax_host_is_connected(void);
|
||||
static uint8_t *esp_apptrace_trax_down_buffer_get(uint32_t *size, esp_apptrace_tmo_t *tmo);
|
||||
static esp_err_t esp_apptrace_trax_down_buffer_put(uint8_t *ptr, esp_apptrace_tmo_t *tmo);
|
||||
static esp_err_t esp_apptrace_trax_status_reg_set(uint32_t val);
|
||||
static esp_err_t esp_apptrace_trax_status_reg_get(uint32_t *val);
|
||||
|
||||
static esp_apptrace_hw_t s_trace_hw[ESP_APPTRACE_HW_MAX] = {
|
||||
{
|
||||
@@ -357,9 +352,7 @@ static esp_apptrace_hw_t s_trace_hw[ESP_APPTRACE_HW_MAX] = {
|
||||
.flush_up_buffer = esp_apptrace_trax_flush,
|
||||
.get_down_buffer = esp_apptrace_trax_down_buffer_get,
|
||||
.put_down_buffer = esp_apptrace_trax_down_buffer_put,
|
||||
.host_is_connected = esp_apptrace_trax_host_is_connected,
|
||||
.status_reg_set = esp_apptrace_trax_status_reg_set,
|
||||
.status_reg_get = esp_apptrace_trax_status_reg_get
|
||||
.host_is_connected = esp_apptrace_trax_host_is_connected
|
||||
}
|
||||
};
|
||||
|
||||
@@ -422,8 +415,6 @@ static void esp_apptrace_trax_init()
|
||||
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(ESP_APPTRACE_TRAX_INBLOCK_START));
|
||||
// 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", xPortGetCoreID());
|
||||
@@ -592,11 +583,11 @@ static uint8_t *esp_apptrace_trax_down_buffer_get(uint32_t *size, esp_apptrace_t
|
||||
while (1) {
|
||||
uint32_t sz = esp_apptrace_rb_read_size_get(&s_trace_buf.rb_down);
|
||||
if (sz != 0) {
|
||||
*size = MIN(*size, sz);
|
||||
ptr = esp_apptrace_rb_consume(&s_trace_buf.rb_down, *size);
|
||||
ptr = esp_apptrace_rb_consume(&s_trace_buf.rb_down, sz > *size ? *size : sz);
|
||||
if (!ptr) {
|
||||
assert(false && "Failed to consume bytes from down buffer!");
|
||||
}
|
||||
*size = sz;
|
||||
break;
|
||||
}
|
||||
// may need to flush
|
||||
@@ -836,18 +827,6 @@ static bool esp_apptrace_trax_host_is_connected(void)
|
||||
return eri_read(ESP_APPTRACE_TRAX_CTRL_REG) & ESP_APPTRACE_TRAX_HOST_CONNECT ? true : false;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_status_reg_set(uint32_t val)
|
||||
{
|
||||
eri_write(ESP_APPTRACE_TRAX_STAT_REG, val);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_status_reg_get(uint32_t *val)
|
||||
{
|
||||
*val = eri_read(ESP_APPTRACE_TRAX_STAT_REG);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_apptrace_trax_dest_init()
|
||||
{
|
||||
for (int i = 0; i < ESP_APPTRACE_TRAX_BLOCKS_NUM; i++) {
|
||||
@@ -1184,49 +1163,13 @@ bool esp_apptrace_host_is_connected(esp_apptrace_dest_t dest)
|
||||
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
|
||||
#else
|
||||
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
|
||||
return false;
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
} else {
|
||||
ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!");
|
||||
return false;
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
return hw->host_is_connected();
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_status_reg_set(esp_apptrace_dest_t dest, uint32_t val)
|
||||
{
|
||||
esp_apptrace_hw_t *hw = NULL;
|
||||
|
||||
if (dest == ESP_APPTRACE_DEST_TRAX) {
|
||||
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
|
||||
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
|
||||
#else
|
||||
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
} else {
|
||||
ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
return hw->status_reg_set(val);
|
||||
}
|
||||
|
||||
esp_err_t esp_apptrace_status_reg_get(esp_apptrace_dest_t dest, uint32_t *val)
|
||||
{
|
||||
esp_apptrace_hw_t *hw = NULL;
|
||||
|
||||
if (dest == ESP_APPTRACE_DEST_TRAX) {
|
||||
#if CONFIG_ESP32_APPTRACE_DEST_TRAX
|
||||
hw = ESP_APPTRACE_HW(ESP_APPTRACE_HW_TRAX);
|
||||
#else
|
||||
ESP_APPTRACE_LOGE("Application tracing via TRAX is disabled in menuconfig!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
} else {
|
||||
ESP_APPTRACE_LOGE("Trace destinations other then TRAX are not supported yet!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
return hw->status_reg_get(val);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,108 +21,22 @@
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_dbg_stubs.h"
|
||||
|
||||
#if CONFIG_ESP32_GCOV_ENABLE
|
||||
|
||||
#define ESP_GCOV_DOWN_BUF_SIZE 4200
|
||||
#if CONFIG_ESP32_APPTRACE_ENABLE
|
||||
|
||||
#define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "esp_gcov_rtio";
|
||||
|
||||
#if GCC_NOT_5_2_0
|
||||
void __gcov_dump(void);
|
||||
void __gcov_reset(void);
|
||||
#else
|
||||
/* The next code for old GCC */
|
||||
|
||||
static void (*s_gcov_exit)(void);
|
||||
/* Root of a program/shared-object state */
|
||||
struct gcov_root
|
||||
{
|
||||
void *list;
|
||||
unsigned dumped : 1; /* counts have been dumped. */
|
||||
unsigned run_counted : 1; /* run has been accounted for. */
|
||||
struct gcov_root *next;
|
||||
struct gcov_root *prev;
|
||||
};
|
||||
|
||||
/* Per-dynamic-object gcov state. */
|
||||
extern struct gcov_root __gcov_root;
|
||||
|
||||
static void esp_gcov_reset_status(void)
|
||||
{
|
||||
__gcov_root.dumped = 0;
|
||||
__gcov_root.run_counted = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int esp_dbg_stub_gcov_dump_do(void)
|
||||
{
|
||||
int ret = ESP_OK;
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "Alloc apptrace down buf %d bytes", ESP_GCOV_DOWN_BUF_SIZE);
|
||||
void *down_buf = malloc(ESP_GCOV_DOWN_BUF_SIZE);
|
||||
if (down_buf == NULL) {
|
||||
ESP_EARLY_LOGE(TAG, "Could not allocate memory for the buffer");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "Config apptrace down buf");
|
||||
esp_apptrace_down_buffer_config(down_buf, ESP_GCOV_DOWN_BUF_SIZE);
|
||||
ESP_EARLY_LOGV(TAG, "Dump data...");
|
||||
#if GCC_NOT_5_2_0
|
||||
__gcov_dump();
|
||||
// reset dump status to allow incremental data accumulation
|
||||
__gcov_reset();
|
||||
#else
|
||||
ESP_EARLY_LOGV(TAG, "Check for dump handler %p", s_gcov_exit);
|
||||
if (s_gcov_exit) {
|
||||
s_gcov_exit();
|
||||
// reset dump status to allow incremental data accumulation
|
||||
esp_gcov_reset_status();
|
||||
}
|
||||
#endif
|
||||
ESP_EARLY_LOGV(TAG, "Free apptrace down buf");
|
||||
free(down_buf);
|
||||
ESP_EARLY_LOGV(TAG, "Finish file transfer session");
|
||||
ret = esp_apptrace_fstop(ESP_APPTRACE_DEST_TRAX);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Triggers gcov info dump.
|
||||
* This function is to be called by OpenOCD, not by normal user code.
|
||||
* TODO: what about interrupted flash access (when cache disabled)???
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
static int esp_dbg_stub_gcov_entry(void)
|
||||
{
|
||||
#if GCC_NOT_5_2_0
|
||||
return esp_dbg_stub_gcov_dump_do();
|
||||
#else
|
||||
int ret = ESP_OK;
|
||||
// disable IRQs on this CPU, other CPU is halted by OpenOCD
|
||||
unsigned irq_state = portENTER_CRITICAL_NESTED();
|
||||
ret = esp_dbg_stub_gcov_dump_do();
|
||||
portEXIT_CRITICAL_NESTED(irq_state);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
static uint8_t s_gcov_down_buf[256];
|
||||
|
||||
void esp_gcov_dump()
|
||||
{
|
||||
// disable IRQs on this CPU, other CPU is halted by OpenOCD
|
||||
unsigned irq_state = portENTER_CRITICAL_NESTED();
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
int other_core = xPortGetCoreID() ? 0 : 1;
|
||||
esp_cpu_stall(other_core);
|
||||
#if CONFIG_FREERTOS_UNICORE == 0
|
||||
esp_cpu_stall(!xPortGetCoreID());
|
||||
#endif
|
||||
|
||||
while (!esp_apptrace_host_is_connected(ESP_APPTRACE_DEST_TRAX)) {
|
||||
// to avoid complains that task watchdog got triggered for other tasks
|
||||
TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
|
||||
@@ -134,62 +48,46 @@ void esp_gcov_dump()
|
||||
TIMERG1.wdt_wprotect=0;
|
||||
}
|
||||
|
||||
esp_dbg_stub_gcov_dump_do();
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
esp_cpu_unstall(other_core);
|
||||
#endif
|
||||
portEXIT_CRITICAL_NESTED(irq_state);
|
||||
if (s_gcov_exit) {
|
||||
esp_apptrace_down_buffer_config(s_gcov_down_buf, sizeof(s_gcov_down_buf));
|
||||
s_gcov_exit();
|
||||
}
|
||||
|
||||
int ret = esp_apptrace_fstop(ESP_APPTRACE_DEST_TRAX);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
int gcov_rtio_atexit(void (*function)(void) __attribute__ ((unused)))
|
||||
int gcov_rtio_atexit(void (*function)(void))
|
||||
{
|
||||
#if GCC_NOT_5_2_0
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
#else
|
||||
ESP_EARLY_LOGV(TAG, "%s %p", __FUNCTION__, function);
|
||||
s_gcov_exit = function;
|
||||
#endif
|
||||
esp_dbg_stub_entry_set(ESP_DBG_STUB_ENTRY_GCOV, (uint32_t)&esp_dbg_stub_gcov_entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *gcov_rtio_fopen(const char *path, const char *mode)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s '%s' '%s'", __FUNCTION__, path, mode);
|
||||
return esp_apptrace_fopen(ESP_APPTRACE_DEST_TRAX, path, mode);
|
||||
}
|
||||
|
||||
int gcov_rtio_fclose(void *stream)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
return esp_apptrace_fclose(ESP_APPTRACE_DEST_TRAX, stream);
|
||||
}
|
||||
|
||||
size_t gcov_rtio_fread(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s read %u", __FUNCTION__, size*nmemb);
|
||||
size_t sz = esp_apptrace_fread(ESP_APPTRACE_DEST_TRAX, ptr, size, nmemb, stream);
|
||||
ESP_EARLY_LOGV(TAG, "%s actually read %u", __FUNCTION__, sz);
|
||||
return sz;
|
||||
}
|
||||
|
||||
size_t gcov_rtio_fwrite(const void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __FUNCTION__);
|
||||
return esp_apptrace_fwrite(ESP_APPTRACE_DEST_TRAX, ptr, size, nmemb, stream);
|
||||
}
|
||||
|
||||
int gcov_rtio_fseek(void *stream, long offset, int whence)
|
||||
{
|
||||
int ret = esp_apptrace_fseek(ESP_APPTRACE_DEST_TRAX, stream, offset, whence);
|
||||
ESP_EARLY_LOGV(TAG, "%s(%p %ld %d) = %d", __FUNCTION__, stream, offset, whence, ret);
|
||||
return ret;
|
||||
return esp_apptrace_fseek(ESP_APPTRACE_DEST_TRAX, stream, offset, whence);
|
||||
}
|
||||
|
||||
long gcov_rtio_ftell(void *stream)
|
||||
{
|
||||
long ret = esp_apptrace_ftell(ESP_APPTRACE_DEST_TRAX, stream);
|
||||
ESP_EARLY_LOGV(TAG, "%s(%p) = %ld", __FUNCTION__, stream, ret);
|
||||
return ret;
|
||||
return esp_apptrace_ftell(ESP_APPTRACE_DEST_TRAX, stream);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -87,7 +87,6 @@ static esp_err_t esp_apptrace_file_cmd_send(esp_apptrace_dest_t dest, uint8_t cm
|
||||
esp_err_t ret;
|
||||
esp_apptrace_fcmd_hdr_t *hdr;
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "%s %d", __func__, cmd);
|
||||
uint8_t *ptr = esp_apptrace_buffer_get(dest, sizeof(*hdr) + args_len, ESP_APPTRACE_TMO_INFINITE); //TODO: finite tmo
|
||||
if (ptr == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
@@ -102,13 +101,13 @@ static esp_err_t esp_apptrace_file_cmd_send(esp_apptrace_dest_t dest, uint8_t cm
|
||||
// now indicate that this buffer is ready to be sent off to host
|
||||
ret = esp_apptrace_buffer_put(dest, ptr, ESP_APPTRACE_TMO_INFINITE);//TODO: finite tmo
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to put apptrace buffer (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to put apptrace buffer (%d)!", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = esp_apptrace_flush(dest, ESP_APPTRACE_TMO_INFINITE);//TODO: finite tmo
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to flush apptrace buffer (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to flush apptrace buffer (%d)!", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -120,12 +119,11 @@ static esp_err_t esp_apptrace_file_rsp_recv(esp_apptrace_dest_t dest, uint8_t *b
|
||||
uint32_t tot_rd = 0;
|
||||
while (tot_rd < buf_len) {
|
||||
uint32_t rd_size = buf_len - tot_rd;
|
||||
esp_err_t ret = esp_apptrace_read(dest, buf + tot_rd, &rd_size, ESP_APPTRACE_TMO_INFINITE); //TODO: finite tmo
|
||||
esp_err_t ret = esp_apptrace_read(dest, buf, &rd_size, ESP_APPTRACE_TMO_INFINITE); //TODO: finite tmo
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return ret;
|
||||
}
|
||||
ESP_EARLY_LOGV(TAG, "%s read %d bytes", __FUNCTION__, rd_size);
|
||||
tot_rd += rd_size;
|
||||
}
|
||||
|
||||
@@ -144,8 +142,6 @@ void *esp_apptrace_fopen(esp_apptrace_dest_t dest, const char *path, const char
|
||||
{
|
||||
esp_apptrace_fopen_args_t cmd_args;
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "esp_apptrace_fopen '%s' '%s'", path, mode);
|
||||
|
||||
cmd_args.path = path;
|
||||
cmd_args.path_len = strlen(path) + 1;
|
||||
cmd_args.mode = mode;
|
||||
@@ -154,7 +150,7 @@ void *esp_apptrace_fopen(esp_apptrace_dest_t dest, const char *path, const char
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FOPEN, esp_apptrace_fopen_args_prepare,
|
||||
&cmd_args, cmd_args.path_len+cmd_args.mode_len);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -162,7 +158,7 @@ void *esp_apptrace_fopen(esp_apptrace_dest_t dest, const char *path, const char
|
||||
void *resp;
|
||||
ret = esp_apptrace_file_rsp_recv(dest, (uint8_t *)&resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -184,7 +180,7 @@ int esp_apptrace_fclose(esp_apptrace_dest_t dest, void *stream)
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FCLOSE, esp_apptrace_fclose_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
@@ -192,7 +188,7 @@ int esp_apptrace_fclose(esp_apptrace_dest_t dest, void *stream)
|
||||
int resp;
|
||||
ret = esp_apptrace_file_rsp_recv(dest, (uint8_t *)&resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
@@ -211,15 +207,13 @@ size_t esp_apptrace_fwrite(esp_apptrace_dest_t dest, const void *ptr, size_t siz
|
||||
{
|
||||
esp_apptrace_fwrite_args_t cmd_args;
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "esp_apptrace_fwrite f %p l %d", stream, size*nmemb);
|
||||
|
||||
cmd_args.buf = (void *)ptr;
|
||||
cmd_args.size = size * nmemb;
|
||||
cmd_args.file = stream;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FWRITE, esp_apptrace_fwrite_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args.file)+cmd_args.size);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -227,7 +221,7 @@ size_t esp_apptrace_fwrite(esp_apptrace_dest_t dest, const void *ptr, size_t siz
|
||||
size_t resp;
|
||||
ret = esp_apptrace_file_rsp_recv(dest, (uint8_t *)&resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -246,14 +240,12 @@ size_t esp_apptrace_fread(esp_apptrace_dest_t dest, void *ptr, size_t size, size
|
||||
{
|
||||
esp_apptrace_fread_args_t cmd_args;
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "esp_apptrace_fread f %p l %d", stream, size*nmemb);
|
||||
|
||||
cmd_args.size = size * nmemb;
|
||||
cmd_args.file = stream;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FREAD, esp_apptrace_fread_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -261,13 +253,13 @@ size_t esp_apptrace_fread(esp_apptrace_dest_t dest, void *ptr, size_t size, size
|
||||
size_t resp;
|
||||
ret = esp_apptrace_file_rsp_recv(dest, (uint8_t *)&resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return 0;
|
||||
}
|
||||
if (resp > 0) {
|
||||
ret = esp_apptrace_file_rsp_recv(dest, ptr, resp);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read file data (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to read file data (%d)!", ret);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -279,23 +271,19 @@ static void esp_apptrace_fseek_args_prepare(uint8_t *buf, void *priv)
|
||||
esp_apptrace_fseek_args_t *args = priv;
|
||||
|
||||
memcpy(buf, &args->file, sizeof(args->file));
|
||||
memcpy(buf + sizeof(args->file), &args->offset, sizeof(args->offset));
|
||||
memcpy(buf + sizeof(args->file) + sizeof(args->offset), &args->whence, sizeof(args->whence));
|
||||
}
|
||||
|
||||
int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int whence)
|
||||
{
|
||||
esp_apptrace_fseek_args_t cmd_args;
|
||||
|
||||
ESP_EARLY_LOGV(TAG, "esp_apptrace_fseek f %p o 0x%lx w %d", stream, offset, whence);
|
||||
|
||||
cmd_args.file = stream;
|
||||
cmd_args.offset = offset;
|
||||
cmd_args.whence = whence;
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FSEEK, esp_apptrace_fseek_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -303,7 +291,7 @@ int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int
|
||||
int resp;
|
||||
ret = esp_apptrace_file_rsp_recv(dest, (uint8_t *)&resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -325,7 +313,7 @@ int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream)
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_FTELL, esp_apptrace_ftell_args_prepare,
|
||||
&cmd_args, sizeof(cmd_args));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to send file cmd (%d)!", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -333,7 +321,7 @@ int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream)
|
||||
int resp;
|
||||
ret = esp_apptrace_file_rsp_recv(dest, (uint8_t *)&resp, sizeof(resp));
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to read response (%d)!", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -342,10 +330,9 @@ int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream)
|
||||
|
||||
int esp_apptrace_fstop(esp_apptrace_dest_t dest)
|
||||
{
|
||||
ESP_EARLY_LOGV(TAG, "%s", __func__);
|
||||
esp_err_t ret = esp_apptrace_file_cmd_send(dest, ESP_APPTRACE_FILE_CMD_STOP, NULL, NULL, 0);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_EARLY_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", ret);
|
||||
ESP_LOGE(TAG, "Failed to send files transfer stop cmd (%d)!", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ static inline void esp_apptrace_tmo_init(esp_apptrace_tmo_t *tmo, uint32_t user_
|
||||
{
|
||||
tmo->start = portGET_RUN_TIME_COUNTER_VALUE();
|
||||
tmo->tmo = user_tmo;
|
||||
tmo->elapsed = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,102 +1,102 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
----------------------------------------------------------------------
|
||||
File : Global.h
|
||||
Purpose : Global types
|
||||
In case your application already has a Global.h, you should
|
||||
merge the files. In order to use Segger code, the types
|
||||
U8, U16, U32, I8, I16, I32 need to be defined in Global.h;
|
||||
additional definitions do not hurt.
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GLOBAL_H // Guard against multiple inclusion
|
||||
#define GLOBAL_H
|
||||
|
||||
#define U8 unsigned char
|
||||
#define U16 unsigned short
|
||||
#define U32 unsigned long
|
||||
#define I8 signed char
|
||||
#define I16 signed short
|
||||
#define I32 signed long
|
||||
|
||||
#ifdef _WIN32
|
||||
//
|
||||
// Microsoft VC6 compiler related
|
||||
//
|
||||
#define U64 unsigned __int64
|
||||
#define U128 unsigned __int128
|
||||
#define I64 __int64
|
||||
#define I128 __int128
|
||||
#if _MSC_VER <= 1200
|
||||
#define U64_C(x) x##UI64
|
||||
#else
|
||||
#define U64_C(x) x##ULL
|
||||
#endif
|
||||
#else
|
||||
//
|
||||
// C99 compliant compiler
|
||||
//
|
||||
#define U64 unsigned long long
|
||||
#define I64 signed long long
|
||||
#define U64_C(x) x##ULL
|
||||
#endif
|
||||
|
||||
#endif // Avoid multiple inclusion
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
----------------------------------------------------------------------
|
||||
File : Global.h
|
||||
Purpose : Global types
|
||||
In case your application already has a Global.h, you should
|
||||
merge the files. In order to use Segger code, the types
|
||||
U8, U16, U32, I8, I16, I32 need to be defined in Global.h;
|
||||
additional definitions do not hurt.
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GLOBAL_H // Guard against multiple inclusion
|
||||
#define GLOBAL_H
|
||||
|
||||
#define U8 unsigned char
|
||||
#define U16 unsigned short
|
||||
#define U32 unsigned long
|
||||
#define I8 signed char
|
||||
#define I16 signed short
|
||||
#define I32 signed long
|
||||
|
||||
#ifdef _WIN32
|
||||
//
|
||||
// Microsoft VC6 compiler related
|
||||
//
|
||||
#define U64 unsigned __int64
|
||||
#define U128 unsigned __int128
|
||||
#define I64 __int64
|
||||
#define I128 __int128
|
||||
#if _MSC_VER <= 1200
|
||||
#define U64_C(x) x##UI64
|
||||
#else
|
||||
#define U64_C(x) x##ULL
|
||||
#endif
|
||||
#else
|
||||
//
|
||||
// C99 compliant compiler
|
||||
//
|
||||
#define U64 unsigned long long
|
||||
#define I64 signed long long
|
||||
#define U64_C(x) x##ULL
|
||||
#endif
|
||||
|
||||
#endif // Avoid multiple inclusion
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -1,298 +1,298 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
File : SEGGER_RTT_Conf.h
|
||||
Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
allows real-time communication on targets which support
|
||||
debugger memory accesses while the CPU is running.
|
||||
Revision: $Rev: 5626 $
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_RTT_CONF_H
|
||||
#define SEGGER_RTT_CONF_H
|
||||
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
#include <intrinsics.h>
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, configurable
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3)
|
||||
#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3)
|
||||
|
||||
#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k)
|
||||
#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
|
||||
|
||||
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64)
|
||||
|
||||
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
|
||||
|
||||
//
|
||||
// Target is not allowed to perform other RTT operations while string still has not been stored completely.
|
||||
// Otherwise we would probably end up with a mixed string in the buffer.
|
||||
// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
|
||||
//
|
||||
// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
|
||||
// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
|
||||
// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
|
||||
// (Higher priority = lower priority number)
|
||||
// Default value for embOS: 128u
|
||||
// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
|
||||
// or define SEGGER_RTT_LOCK() to completely disable interrupts.
|
||||
//
|
||||
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for SEGGER Embedded Studio,
|
||||
* Rowley CrossStudio and GCC
|
||||
*/
|
||||
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
|
||||
#ifdef __ARM_ARCH_6M__
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs %0, primask \n\t" \
|
||||
"mov r1, $1 \n\t" \
|
||||
"msr primask, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: \
|
||||
); \
|
||||
}
|
||||
|
||||
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs %0, basepri \n\t" \
|
||||
"mov r1, %1 \n\t" \
|
||||
"msr basepri, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: \
|
||||
); \
|
||||
}
|
||||
|
||||
#elif defined(__ARM_ARCH_7A__)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs r1, CPSR \n\t" \
|
||||
"mov %0, r1 \n\t" \
|
||||
"orr r1, r1, #0xC0 \n\t" \
|
||||
"msr CPSR_c, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
|
||||
"mrs r1, CPSR \n\t" \
|
||||
"bic r1, r1, #0xC0 \n\t" \
|
||||
"and r0, r0, #0xC0 \n\t" \
|
||||
"orr r1, r1, r0 \n\t" \
|
||||
"msr CPSR_c, r1 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: "r0", "r1" \
|
||||
); \
|
||||
}
|
||||
#else
|
||||
#define SEGGER_RTT_LOCK()
|
||||
#define SEGGER_RTT_UNLOCK()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for IAR EWARM
|
||||
*/
|
||||
#ifdef __ICCARM__
|
||||
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_PRIMASK(); \
|
||||
__set_PRIMASK(1);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
|
||||
}
|
||||
#elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__)))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_BASEPRI(); \
|
||||
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for IAR RX
|
||||
*/
|
||||
#ifdef __ICCRX__
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned long LockState; \
|
||||
LockState = __get_interrupt_state(); \
|
||||
__disable_interrupt();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for KEIL ARM
|
||||
*/
|
||||
#ifdef __CC_ARM
|
||||
#if (defined __TARGET_ARCH_6S_M)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
register unsigned char PRIMASK __asm( "primask"); \
|
||||
LockState = PRIMASK; \
|
||||
PRIMASK = 1u; \
|
||||
__schedule_barrier();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \
|
||||
__schedule_barrier(); \
|
||||
}
|
||||
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
register unsigned char BASEPRI __asm( "basepri"); \
|
||||
LockState = BASEPRI; \
|
||||
BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \
|
||||
__schedule_barrier();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \
|
||||
__schedule_barrier(); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for TI ARM
|
||||
*/
|
||||
#ifdef __TI_ARM__
|
||||
#if defined (__TI_ARM_V6M0__)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_PRIMASK(); \
|
||||
__set_PRIMASK(1);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
|
||||
}
|
||||
#elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = OS_GetBASEPRI(); \
|
||||
OS_SetBASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() OS_SetBASEPRI(LockState); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration fallback
|
||||
*/
|
||||
#ifndef SEGGER_RTT_LOCK
|
||||
void SEGGER_SYSVIEW_X_RTT_Lock();
|
||||
#define SEGGER_RTT_LOCK() SEGGER_SYSVIEW_X_RTT_Lock() // Lock RTT (nestable) (i.e. disable interrupts)
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_UNLOCK
|
||||
void SEGGER_SYSVIEW_X_RTT_Unlock();
|
||||
#define SEGGER_RTT_UNLOCK() SEGGER_SYSVIEW_X_RTT_Unlock() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
File : SEGGER_RTT_Conf.h
|
||||
Purpose : Implementation of SEGGER real-time transfer (RTT) which
|
||||
allows real-time communication on targets which support
|
||||
debugger memory accesses while the CPU is running.
|
||||
Revision: $Rev: 5626 $
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_RTT_CONF_H
|
||||
#define SEGGER_RTT_CONF_H
|
||||
|
||||
#ifdef __IAR_SYSTEMS_ICC__
|
||||
#include <intrinsics.h>
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, configurable
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 3)
|
||||
#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 3)
|
||||
|
||||
#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k)
|
||||
#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16)
|
||||
|
||||
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64)
|
||||
|
||||
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0)
|
||||
|
||||
//
|
||||
// Target is not allowed to perform other RTT operations while string still has not been stored completely.
|
||||
// Otherwise we would probably end up with a mixed string in the buffer.
|
||||
// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here.
|
||||
//
|
||||
// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4.
|
||||
// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches.
|
||||
// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly.
|
||||
// (Higher priority = lower priority number)
|
||||
// Default value for embOS: 128u
|
||||
// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC
|
||||
// or define SEGGER_RTT_LOCK() to completely disable interrupts.
|
||||
//
|
||||
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for SEGGER Embedded Studio,
|
||||
* Rowley CrossStudio and GCC
|
||||
*/
|
||||
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
|
||||
#ifdef __ARM_ARCH_6M__
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs %0, primask \n\t" \
|
||||
"mov r1, $1 \n\t" \
|
||||
"msr primask, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: \
|
||||
); \
|
||||
}
|
||||
|
||||
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs %0, basepri \n\t" \
|
||||
"mov r1, %1 \n\t" \
|
||||
"msr basepri, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: "i"(SEGGER_RTT_MAX_INTERRUPT_PRIORITY) \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: \
|
||||
); \
|
||||
}
|
||||
|
||||
#elif defined(__ARM_ARCH_7A__)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
__asm volatile ("mrs r1, CPSR \n\t" \
|
||||
"mov %0, r1 \n\t" \
|
||||
"orr r1, r1, #0xC0 \n\t" \
|
||||
"msr CPSR_c, r1 \n\t" \
|
||||
: "=r" (LockState) \
|
||||
: \
|
||||
: "r1" \
|
||||
);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \
|
||||
"mrs r1, CPSR \n\t" \
|
||||
"bic r1, r1, #0xC0 \n\t" \
|
||||
"and r0, r0, #0xC0 \n\t" \
|
||||
"orr r1, r1, r0 \n\t" \
|
||||
"msr CPSR_c, r1 \n\t" \
|
||||
: \
|
||||
: "r" (LockState) \
|
||||
: "r0", "r1" \
|
||||
); \
|
||||
}
|
||||
#else
|
||||
#define SEGGER_RTT_LOCK()
|
||||
#define SEGGER_RTT_UNLOCK()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for IAR EWARM
|
||||
*/
|
||||
#ifdef __ICCARM__
|
||||
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_PRIMASK(); \
|
||||
__set_PRIMASK(1);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
|
||||
}
|
||||
#elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__)))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_BASEPRI(); \
|
||||
__set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for IAR RX
|
||||
*/
|
||||
#ifdef __ICCRX__
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned long LockState; \
|
||||
LockState = __get_interrupt_state(); \
|
||||
__disable_interrupt();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for KEIL ARM
|
||||
*/
|
||||
#ifdef __CC_ARM
|
||||
#if (defined __TARGET_ARCH_6S_M)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
register unsigned char PRIMASK __asm( "primask"); \
|
||||
LockState = PRIMASK; \
|
||||
PRIMASK = 1u; \
|
||||
__schedule_barrier();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \
|
||||
__schedule_barrier(); \
|
||||
}
|
||||
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
register unsigned char BASEPRI __asm( "basepri"); \
|
||||
LockState = BASEPRI; \
|
||||
BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \
|
||||
__schedule_barrier();
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \
|
||||
__schedule_barrier(); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration for TI ARM
|
||||
*/
|
||||
#ifdef __TI_ARM__
|
||||
#if defined (__TI_ARM_V6M0__)
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = __get_PRIMASK(); \
|
||||
__set_PRIMASK(1);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \
|
||||
}
|
||||
#elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__))
|
||||
#ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY
|
||||
#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20)
|
||||
#endif
|
||||
#define SEGGER_RTT_LOCK() { \
|
||||
unsigned int LockState; \
|
||||
LockState = OS_GetBASEPRI(); \
|
||||
OS_SetBASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY);
|
||||
|
||||
#define SEGGER_RTT_UNLOCK() OS_SetBASEPRI(LockState); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* RTT lock configuration fallback
|
||||
*/
|
||||
#ifndef SEGGER_RTT_LOCK
|
||||
void SEGGER_SYSVIEW_X_RTT_Lock();
|
||||
#define SEGGER_RTT_LOCK() SEGGER_SYSVIEW_X_RTT_Lock() // Lock RTT (nestable) (i.e. disable interrupts)
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_RTT_UNLOCK
|
||||
void SEGGER_SYSVIEW_X_RTT_Unlock();
|
||||
#define SEGGER_RTT_UNLOCK() SEGGER_SYSVIEW_X_RTT_Unlock() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -1,176 +1,176 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
|
||||
File : SEGGER_SYSVIEW_Conf.h
|
||||
Purpose : SEGGER SystemView configuration.
|
||||
Revision: $Rev: 5927 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_CONF_H
|
||||
#define SEGGER_SYSVIEW_CONF_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, fixed
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
//
|
||||
// Constants for known core configuration
|
||||
//
|
||||
#define SEGGER_SYSVIEW_CORE_OTHER 0
|
||||
#define SEGGER_SYSVIEW_CORE_CM0 1 // Cortex-M0/M0+/M1
|
||||
#define SEGGER_SYSVIEW_CORE_CM3 2 // Cortex-M3/M4/M7
|
||||
#define SEGGER_SYSVIEW_CORE_RX 3 // Renesas RX
|
||||
|
||||
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
|
||||
#ifdef __ARM_ARCH_6M__
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__ICCARM__)
|
||||
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif ((defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__CC_ARM)
|
||||
#if (defined(__TARGET_ARCH_6S_M))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__TI_ARM__)
|
||||
#ifdef __TI_ARM_V6M0__
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif (defined(__TI_ARM_V7M3__) || defined(__TI_ARM_V7M4__))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__ICCRX__)
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
|
||||
#elif defined(__RX)
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_CORE
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_OTHER
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, configurable
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView buffer configuration
|
||||
*/
|
||||
#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024 // Number of bytes that SystemView uses for the buffer.
|
||||
#define SEGGER_SYSVIEW_RTT_CHANNEL 1 // The RTT channel that SystemView will use. 0: Auto selection
|
||||
|
||||
#define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1 // Use a static buffer to generate events instead of a buffer on the stack
|
||||
|
||||
#define SEGGER_SYSVIEW_POST_MORTEM_MODE 0 // 1: Enable post mortem analysis mode
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView timestamp configuration
|
||||
*/
|
||||
#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
|
||||
#define SEGGER_SYSVIEW_GET_TIMESTAMP() (*(U32 *)(0xE0001004)) // Retrieve a system timestamp. Cortex-M cycle counter.
|
||||
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by clock source
|
||||
#else
|
||||
#define SEGGER_SYSVIEW_GET_TIMESTAMP() SEGGER_SYSVIEW_X_GetTimestamp() // Retrieve a system timestamp via user-defined function
|
||||
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by SEGGER_SYSVIEW_X_GetTimestamp()
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView Id configuration
|
||||
*/
|
||||
//TODO: optimise it
|
||||
#define SEGGER_SYSVIEW_ID_BASE 0x3F400000 // Default value for the lowest Id reported by the application. Can be overridden by the application via SEGGER_SYSVIEW_SetRAMBase(). (i.e. 0x20000000 when all Ids are an address in this RAM)
|
||||
#define SEGGER_SYSVIEW_ID_SHIFT 0 // Number of bits to shift the Id to save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView interrupt configuration
|
||||
*/
|
||||
#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x1FF) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[8:0] = active vector)
|
||||
#elif SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM0
|
||||
#if defined(__ICCARM__)
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() (__get_IPSR()) // Workaround for IAR, which might do a byte-access to 0xE000ED04. Read IPSR instead.
|
||||
#else
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x3F) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[5:0] = active vector)
|
||||
#endif
|
||||
#else
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() SEGGER_SYSVIEW_X_GetInterruptId() // Get the currently active interrupt Id from the user-provided function.
|
||||
#endif
|
||||
|
||||
void SEGGER_SYSVIEW_X_SysView_Lock();
|
||||
void SEGGER_SYSVIEW_X_SysView_Unlock();
|
||||
#define SEGGER_SYSVIEW_LOCK() SEGGER_SYSVIEW_X_SysView_Lock()
|
||||
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_SYSVIEW_X_SysView_Unlock()
|
||||
|
||||
#endif // SEGGER_SYSVIEW_CONF_H
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
|
||||
File : SEGGER_SYSVIEW_Conf.h
|
||||
Purpose : SEGGER SystemView configuration.
|
||||
Revision: $Rev: 5927 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_CONF_H
|
||||
#define SEGGER_SYSVIEW_CONF_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, fixed
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
//
|
||||
// Constants for known core configuration
|
||||
//
|
||||
#define SEGGER_SYSVIEW_CORE_OTHER 0
|
||||
#define SEGGER_SYSVIEW_CORE_CM0 1 // Cortex-M0/M0+/M1
|
||||
#define SEGGER_SYSVIEW_CORE_CM3 2 // Cortex-M3/M4/M7
|
||||
#define SEGGER_SYSVIEW_CORE_RX 3 // Renesas RX
|
||||
|
||||
#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)
|
||||
#ifdef __ARM_ARCH_6M__
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__ICCARM__)
|
||||
#if (defined (__ARM6M__) && (__CORE__ == __ARM6M__))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif ((defined (__ARM7M__) && (__CORE__ == __ARM7M__)) || (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__CC_ARM)
|
||||
#if (defined(__TARGET_ARCH_6S_M))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__TI_ARM__)
|
||||
#ifdef __TI_ARM_V6M0__
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM0
|
||||
#elif (defined(__TI_ARM_V7M3__) || defined(__TI_ARM_V7M4__))
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_CM3
|
||||
#endif
|
||||
#elif defined(__ICCRX__)
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
|
||||
#elif defined(__RX)
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_RX
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_CORE
|
||||
#define SEGGER_SYSVIEW_CORE SEGGER_SYSVIEW_CORE_OTHER
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, configurable
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView buffer configuration
|
||||
*/
|
||||
#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024 // Number of bytes that SystemView uses for the buffer.
|
||||
#define SEGGER_SYSVIEW_RTT_CHANNEL 1 // The RTT channel that SystemView will use. 0: Auto selection
|
||||
|
||||
#define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1 // Use a static buffer to generate events instead of a buffer on the stack
|
||||
|
||||
#define SEGGER_SYSVIEW_POST_MORTEM_MODE 0 // 1: Enable post mortem analysis mode
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView timestamp configuration
|
||||
*/
|
||||
#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
|
||||
#define SEGGER_SYSVIEW_GET_TIMESTAMP() (*(U32 *)(0xE0001004)) // Retrieve a system timestamp. Cortex-M cycle counter.
|
||||
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by clock source
|
||||
#else
|
||||
#define SEGGER_SYSVIEW_GET_TIMESTAMP() SEGGER_SYSVIEW_X_GetTimestamp() // Retrieve a system timestamp via user-defined function
|
||||
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32 // Define number of valid bits low-order delivered by SEGGER_SYSVIEW_X_GetTimestamp()
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView Id configuration
|
||||
*/
|
||||
//TODO: optimise it
|
||||
#define SEGGER_SYSVIEW_ID_BASE 0x3F400000 // Default value for the lowest Id reported by the application. Can be overridden by the application via SEGGER_SYSVIEW_SetRAMBase(). (i.e. 0x20000000 when all Ids are an address in this RAM)
|
||||
#define SEGGER_SYSVIEW_ID_SHIFT 0 // Number of bits to shift the Id to save bandwidth. (i.e. 2 when Ids are 4 byte aligned)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SystemView interrupt configuration
|
||||
*/
|
||||
#if SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM3
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x1FF) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[8:0] = active vector)
|
||||
#elif SEGGER_SYSVIEW_CORE == SEGGER_SYSVIEW_CORE_CM0
|
||||
#if defined(__ICCARM__)
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() (__get_IPSR()) // Workaround for IAR, which might do a byte-access to 0xE000ED04. Read IPSR instead.
|
||||
#else
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() ((*(U32 *)(0xE000ED04)) & 0x3F) // Get the currently active interrupt Id. (i.e. read Cortex-M ICSR[5:0] = active vector)
|
||||
#endif
|
||||
#else
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() SEGGER_SYSVIEW_X_GetInterruptId() // Get the currently active interrupt Id from the user-provided function.
|
||||
#endif
|
||||
|
||||
void SEGGER_SYSVIEW_X_SysView_Lock();
|
||||
void SEGGER_SYSVIEW_X_SysView_Unlock();
|
||||
#define SEGGER_SYSVIEW_LOCK() SEGGER_SYSVIEW_X_SysView_Lock()
|
||||
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_SYSVIEW_X_SysView_Unlock()
|
||||
|
||||
#endif // SEGGER_SYSVIEW_CONF_H
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -1,155 +1,155 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
----------------------------------------------------------------------
|
||||
File : SEGGER.h
|
||||
Purpose : Global types etc & general purpose utility functions
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_H // Guard against multiple inclusion
|
||||
#define SEGGER_H
|
||||
|
||||
#include "Global.h" // Type definitions: U8, U16, U32, I8, I16, I32
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" { /* Make sure we have C-declarations in C++ programs */
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Keywords/specifiers
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef INLINE
|
||||
#ifdef _WIN32
|
||||
//
|
||||
// Microsoft VC6 and newer.
|
||||
// Force inlining without cost checking.
|
||||
//
|
||||
#define INLINE __forceinline
|
||||
#else
|
||||
#if (defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) || defined(__RX) || defined(__ICCRX__))
|
||||
//
|
||||
// Other known compilers.
|
||||
//
|
||||
#define INLINE inline
|
||||
#else
|
||||
//
|
||||
// Unknown compilers.
|
||||
//
|
||||
#define INLINE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Function-like macros
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#define SEGGER_COUNTOF(a) (sizeof((a))/sizeof((a)[0]))
|
||||
#define SEGGER_MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#define SEGGER_MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Types
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char *pBuffer;
|
||||
int BufferSize;
|
||||
int Cnt;
|
||||
} SEGGER_BUFFER_DESC;
|
||||
|
||||
typedef struct {
|
||||
int CacheLineSize; // 0: No Cache. Most Systems such as ARM9 use a 32 bytes cache line size.
|
||||
void (*pfDMB) (void); // Optional DMB function for Data Memory Barrier to make sure all memory operations are completed.
|
||||
void (*pfClean) (void *p, unsigned NumBytes); // Optional clean function for cached memory.
|
||||
void (*pfInvalidate)(void *p, unsigned NumBytes); // Optional invalidate function for cached memory.
|
||||
} SEGGER_CACHE_CONFIG;
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Utility functions
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
void SEGGER_ARM_memcpy (void *pDest, const void *pSrc, int NumBytes);
|
||||
void SEGGER_memcpy (void *pDest, const void *pSrc, int NumBytes);
|
||||
void SEGGER_memxor (void *pDest, const void *pSrc, unsigned NumBytes);
|
||||
void SEGGER_StoreChar (SEGGER_BUFFER_DESC *p, char c);
|
||||
void SEGGER_PrintUnsigned(SEGGER_BUFFER_DESC *pBufferDesc, U32 v, unsigned Base, int NumDigits);
|
||||
void SEGGER_PrintInt (SEGGER_BUFFER_DESC *pBufferDesc, I32 v, unsigned Base, unsigned NumDigits);
|
||||
int SEGGER_snprintf (char *pBuffer, int BufferSize, const char *sFormat, ...);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* Make sure we have C-declarations in C++ programs */
|
||||
#endif
|
||||
|
||||
#endif // Avoid multiple inclusion
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
----------------------------------------------------------------------
|
||||
File : SEGGER.h
|
||||
Purpose : Global types etc & general purpose utility functions
|
||||
---------------------------END-OF-HEADER------------------------------
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_H // Guard against multiple inclusion
|
||||
#define SEGGER_H
|
||||
|
||||
#include "Global.h" // Type definitions: U8, U16, U32, I8, I16, I32
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" { /* Make sure we have C-declarations in C++ programs */
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Keywords/specifiers
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef INLINE
|
||||
#ifdef _WIN32
|
||||
//
|
||||
// Microsoft VC6 and newer.
|
||||
// Force inlining without cost checking.
|
||||
//
|
||||
#define INLINE __forceinline
|
||||
#else
|
||||
#if (defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) || defined(__RX) || defined(__ICCRX__))
|
||||
//
|
||||
// Other known compilers.
|
||||
//
|
||||
#define INLINE inline
|
||||
#else
|
||||
//
|
||||
// Unknown compilers.
|
||||
//
|
||||
#define INLINE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Function-like macros
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#define SEGGER_COUNTOF(a) (sizeof((a))/sizeof((a)[0]))
|
||||
#define SEGGER_MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#define SEGGER_MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Types
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char *pBuffer;
|
||||
int BufferSize;
|
||||
int Cnt;
|
||||
} SEGGER_BUFFER_DESC;
|
||||
|
||||
typedef struct {
|
||||
int CacheLineSize; // 0: No Cache. Most Systems such as ARM9 use a 32 bytes cache line size.
|
||||
void (*pfDMB) (void); // Optional DMB function for Data Memory Barrier to make sure all memory operations are completed.
|
||||
void (*pfClean) (void *p, unsigned NumBytes); // Optional clean function for cached memory.
|
||||
void (*pfInvalidate)(void *p, unsigned NumBytes); // Optional invalidate function for cached memory.
|
||||
} SEGGER_CACHE_CONFIG;
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Utility functions
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
void SEGGER_ARM_memcpy (void *pDest, const void *pSrc, int NumBytes);
|
||||
void SEGGER_memcpy (void *pDest, const void *pSrc, int NumBytes);
|
||||
void SEGGER_memxor (void *pDest, const void *pSrc, unsigned NumBytes);
|
||||
void SEGGER_StoreChar (SEGGER_BUFFER_DESC *p, char c);
|
||||
void SEGGER_PrintUnsigned(SEGGER_BUFFER_DESC *pBufferDesc, U32 v, unsigned Base, int NumDigits);
|
||||
void SEGGER_PrintInt (SEGGER_BUFFER_DESC *pBufferDesc, I32 v, unsigned Base, unsigned NumDigits);
|
||||
int SEGGER_snprintf (char *pBuffer, int BufferSize, const char *sFormat, ...);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* Make sure we have C-declarations in C++ programs */
|
||||
#endif
|
||||
|
||||
#endif // Avoid multiple inclusion
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,334 +1,334 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
File : SEGGER_SYSVIEW.h
|
||||
Purpose : System visualization API.
|
||||
Revision: $Rev: 5626 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_H
|
||||
#define SEGGER_SYSVIEW_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* #include Section
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "SEGGER.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, fixed
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#define SEGGER_SYSVIEW_VERSION 21000
|
||||
|
||||
#define SEGGER_SYSVIEW_INFO_SIZE 9 // Minimum size, which has to be reserved for a packet. 1-2 byte of message type, 0-2 byte of payload length, 1-5 bytes of timestamp.
|
||||
#define SEGGER_SYSVIEW_QUANTA_U32 5 // Maximum number of bytes to encode a U32, should be reserved for each 32-bit value in a packet.
|
||||
|
||||
#define SEGGER_SYSVIEW_LOG (0u)
|
||||
#define SEGGER_SYSVIEW_WARNING (1u)
|
||||
#define SEGGER_SYSVIEW_ERROR (2u)
|
||||
#define SEGGER_SYSVIEW_FLAG_APPEND (1u << 6)
|
||||
|
||||
#define SEGGER_SYSVIEW_PREPARE_PACKET(p) (p) + 4
|
||||
//
|
||||
// SystemView events. First 32 IDs from 0 .. 31 are reserved for these
|
||||
//
|
||||
#define SYSVIEW_EVTID_NOP 0 // Dummy packet.
|
||||
#define SYSVIEW_EVTID_OVERFLOW 1
|
||||
#define SYSVIEW_EVTID_ISR_ENTER 2
|
||||
#define SYSVIEW_EVTID_ISR_EXIT 3
|
||||
#define SYSVIEW_EVTID_TASK_START_EXEC 4
|
||||
#define SYSVIEW_EVTID_TASK_STOP_EXEC 5
|
||||
#define SYSVIEW_EVTID_TASK_START_READY 6
|
||||
#define SYSVIEW_EVTID_TASK_STOP_READY 7
|
||||
#define SYSVIEW_EVTID_TASK_CREATE 8
|
||||
#define SYSVIEW_EVTID_TASK_INFO 9
|
||||
#define SYSVIEW_EVTID_TRACE_START 10
|
||||
#define SYSVIEW_EVTID_TRACE_STOP 11
|
||||
#define SYSVIEW_EVTID_SYSTIME_CYCLES 12
|
||||
#define SYSVIEW_EVTID_SYSTIME_US 13
|
||||
#define SYSVIEW_EVTID_SYSDESC 14
|
||||
#define SYSVIEW_EVTID_USER_START 15
|
||||
#define SYSVIEW_EVTID_USER_STOP 16
|
||||
#define SYSVIEW_EVTID_IDLE 17
|
||||
#define SYSVIEW_EVTID_ISR_TO_SCHEDULER 18
|
||||
#define SYSVIEW_EVTID_TIMER_ENTER 19
|
||||
#define SYSVIEW_EVTID_TIMER_EXIT 20
|
||||
#define SYSVIEW_EVTID_STACK_INFO 21
|
||||
#define SYSVIEW_EVTID_MODULEDESC 22
|
||||
|
||||
#define SYSVIEW_EVTID_INIT 24
|
||||
#define SYSVIEW_EVTID_NAME_RESOURCE 25
|
||||
#define SYSVIEW_EVTID_PRINT_FORMATTED 26
|
||||
#define SYSVIEW_EVTID_NUMMODULES 27
|
||||
#define SYSVIEW_EVTID_END_CALL 28
|
||||
#define SYSVIEW_EVTID_TASK_TERMINATE 29
|
||||
|
||||
#define SYSVIEW_EVTID_EX 31
|
||||
//
|
||||
// Event masks to disable/enable events
|
||||
//
|
||||
#define SYSVIEW_EVTMASK_NOP (1 << SYSVIEW_EVTID_NOP)
|
||||
#define SYSVIEW_EVTMASK_OVERFLOW (1 << SYSVIEW_EVTID_OVERFLOW)
|
||||
#define SYSVIEW_EVTMASK_ISR_ENTER (1 << SYSVIEW_EVTID_ISR_ENTER)
|
||||
#define SYSVIEW_EVTMASK_ISR_EXIT (1 << SYSVIEW_EVTID_ISR_EXIT)
|
||||
#define SYSVIEW_EVTMASK_TASK_START_EXEC (1 << SYSVIEW_EVTID_TASK_START_EXEC)
|
||||
#define SYSVIEW_EVTMASK_TASK_STOP_EXEC (1 << SYSVIEW_EVTID_TASK_STOP_EXEC)
|
||||
#define SYSVIEW_EVTMASK_TASK_START_READY (1 << SYSVIEW_EVTID_TASK_START_READY)
|
||||
#define SYSVIEW_EVTMASK_TASK_STOP_READY (1 << SYSVIEW_EVTID_TASK_STOP_READY)
|
||||
#define SYSVIEW_EVTMASK_TASK_CREATE (1 << SYSVIEW_EVTID_TASK_CREATE)
|
||||
#define SYSVIEW_EVTMASK_TASK_INFO (1 << SYSVIEW_EVTID_TASK_INFO)
|
||||
#define SYSVIEW_EVTMASK_TRACE_START (1 << SYSVIEW_EVTID_TRACE_START)
|
||||
#define SYSVIEW_EVTMASK_TRACE_STOP (1 << SYSVIEW_EVTID_TRACE_STOP)
|
||||
#define SYSVIEW_EVTMASK_SYSTIME_CYCLES (1 << SYSVIEW_EVTID_SYSTIME_CYCLES)
|
||||
#define SYSVIEW_EVTMASK_SYSTIME_US (1 << SYSVIEW_EVTID_SYSTIME_US)
|
||||
#define SYSVIEW_EVTMASK_SYSDESC (1 << SYSVIEW_EVTID_SYSDESC)
|
||||
#define SYSVIEW_EVTMASK_USER_START (1 << SYSVIEW_EVTID_USER_START)
|
||||
#define SYSVIEW_EVTMASK_USER_STOP (1 << SYSVIEW_EVTID_USER_STOP)
|
||||
#define SYSVIEW_EVTMASK_IDLE (1 << SYSVIEW_EVTID_IDLE)
|
||||
#define SYSVIEW_EVTMASK_ISR_TO_SCHEDULER (1 << SYSVIEW_EVTID_ISR_TO_SCHEDULER)
|
||||
#define SYSVIEW_EVTMASK_TIMER_ENTER (1 << SYSVIEW_EVTID_TIMER_ENTER)
|
||||
#define SYSVIEW_EVTMASK_TIMER_EXIT (1 << SYSVIEW_EVTID_TIMER_EXIT)
|
||||
#define SYSVIEW_EVTMASK_STACK_INFO (1 << SYSVIEW_EVTID_STACK_INFO)
|
||||
#define SYSVIEW_EVTMASK_MODULEDESC (1 << SYSVIEW_EVTID_MODULEDESC)
|
||||
|
||||
#define SYSVIEW_EVTMASK_INIT (1 << SYSVIEW_EVTID_INIT)
|
||||
#define SYSVIEW_EVTMASK_NAME_RESOURCE (1 << SYSVIEW_EVTID_NAME_RESOURCE)
|
||||
#define SYSVIEW_EVTMASK_PRINT_FORMATTED (1 << SYSVIEW_EVTID_PRINT_FORMATTED)
|
||||
#define SYSVIEW_EVTMASK_NUMMODULES (1 << SYSVIEW_EVTID_NUMMODULES)
|
||||
#define SYSVIEW_EVTMASK_END_CALL (1 << SYSVIEW_EVTID_END_CALL)
|
||||
#define SYSVIEW_EVTMASK_TASK_TERMINATE (1 << SYSVIEW_EVTID_TASK_TERMINATE)
|
||||
|
||||
#define SYSVIEW_EVTMASK_EX (1 << SYSVIEW_EVTID_EX)
|
||||
|
||||
#define SYSVIEW_EVTMASK_ALL_INTERRUPTS ( SYSVIEW_EVTMASK_ISR_ENTER \
|
||||
| SYSVIEW_EVTMASK_ISR_EXIT \
|
||||
| SYSVIEW_EVTMASK_ISR_TO_SCHEDULER)
|
||||
#define SYSVIEW_EVTMASK_ALL_TASKS ( SYSVIEW_EVTMASK_TASK_START_EXEC \
|
||||
| SYSVIEW_EVTMASK_TASK_STOP_EXEC \
|
||||
| SYSVIEW_EVTMASK_TASK_START_READY \
|
||||
| SYSVIEW_EVTMASK_TASK_STOP_READY \
|
||||
| SYSVIEW_EVTMASK_TASK_CREATE \
|
||||
| SYSVIEW_EVTMASK_TASK_INFO \
|
||||
| SYSVIEW_EVTMASK_STACK_INFO \
|
||||
| SYSVIEW_EVTMASK_TASK_TERMINATE)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Structures
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
U32 TaskID;
|
||||
const char* sName;
|
||||
U32 Prio;
|
||||
U32 StackBase;
|
||||
U32 StackSize;
|
||||
} SEGGER_SYSVIEW_TASKINFO;
|
||||
|
||||
typedef struct SEGGER_SYSVIEW_MODULE_STRUCT SEGGER_SYSVIEW_MODULE;
|
||||
|
||||
struct SEGGER_SYSVIEW_MODULE_STRUCT {
|
||||
const char* sModule;
|
||||
U32 NumEvents;
|
||||
U32 EventOffset;
|
||||
void (*pfSendModuleDesc)(void);
|
||||
SEGGER_SYSVIEW_MODULE* pNext;
|
||||
};
|
||||
|
||||
typedef void (SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC)(void);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* API functions
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
U64 (*pfGetTime) (void);
|
||||
void (*pfSendTaskList) (void);
|
||||
} SEGGER_SYSVIEW_OS_API;
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Control and initialization functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_Init (U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API *pOSAPI, SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc);
|
||||
void SEGGER_SYSVIEW_SetRAMBase (U32 RAMBaseAddress);
|
||||
void SEGGER_SYSVIEW_Start (void);
|
||||
void SEGGER_SYSVIEW_Stop (void);
|
||||
void SEGGER_SYSVIEW_GetSysDesc (void);
|
||||
void SEGGER_SYSVIEW_SendTaskList (void);
|
||||
void SEGGER_SYSVIEW_SendTaskInfo (const SEGGER_SYSVIEW_TASKINFO* pInfo);
|
||||
void SEGGER_SYSVIEW_SendSysDesc (const char* sSysDesc);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Event recording functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_RecordVoid (unsigned int EventId);
|
||||
void SEGGER_SYSVIEW_RecordU32 (unsigned int EventId, U32 Para0);
|
||||
void SEGGER_SYSVIEW_RecordU32x2 (unsigned int EventId, U32 Para0, U32 Para1);
|
||||
void SEGGER_SYSVIEW_RecordU32x3 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2);
|
||||
void SEGGER_SYSVIEW_RecordU32x4 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3);
|
||||
void SEGGER_SYSVIEW_RecordU32x5 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4);
|
||||
void SEGGER_SYSVIEW_RecordU32x6 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5);
|
||||
void SEGGER_SYSVIEW_RecordU32x7 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6);
|
||||
void SEGGER_SYSVIEW_RecordU32x8 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7);
|
||||
void SEGGER_SYSVIEW_RecordU32x9 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8);
|
||||
void SEGGER_SYSVIEW_RecordU32x10 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8, U32 Para9);
|
||||
void SEGGER_SYSVIEW_RecordString (unsigned int EventId, const char* pString);
|
||||
void SEGGER_SYSVIEW_RecordSystime (void);
|
||||
void SEGGER_SYSVIEW_RecordEnterISR (U32 IrqId);
|
||||
void SEGGER_SYSVIEW_RecordExitISR (void);
|
||||
void SEGGER_SYSVIEW_RecordExitISRToScheduler (void);
|
||||
void SEGGER_SYSVIEW_RecordEnterTimer (U32 TimerId);
|
||||
void SEGGER_SYSVIEW_RecordExitTimer (void);
|
||||
void SEGGER_SYSVIEW_RecordEndCall (unsigned int EventID);
|
||||
void SEGGER_SYSVIEW_RecordEndCallU32 (unsigned int EventID, U32 Para0);
|
||||
|
||||
void SEGGER_SYSVIEW_OnIdle (void);
|
||||
void SEGGER_SYSVIEW_OnTaskCreate (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskTerminate (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskStartExec (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskStopExec (void);
|
||||
void SEGGER_SYSVIEW_OnTaskStartReady (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskStopReady (U32 TaskId, unsigned int Cause);
|
||||
void SEGGER_SYSVIEW_OnUserStart (unsigned int UserId); // Start of user defined event (such as a subroutine to profile)
|
||||
void SEGGER_SYSVIEW_OnUserStop (unsigned int UserId); // Start of user defined event
|
||||
|
||||
void SEGGER_SYSVIEW_NameResource (U32 ResourceId, const char* sName);
|
||||
|
||||
int SEGGER_SYSVIEW_SendPacket (U8* pPacket, U8* pPayloadEnd, unsigned int EventId);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Event parameter encoding functions
|
||||
*/
|
||||
U8* SEGGER_SYSVIEW_EncodeU32 (U8* pPayload, U32 Value);
|
||||
U8* SEGGER_SYSVIEW_EncodeData (U8* pPayload, const char* pSrc, unsigned int Len);
|
||||
U8* SEGGER_SYSVIEW_EncodeString (U8* pPayload, const char* s, unsigned int MaxLen);
|
||||
U8* SEGGER_SYSVIEW_EncodeId (U8* pPayload, U32 Id);
|
||||
U32 SEGGER_SYSVIEW_ShrinkId (U32 Id);
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Middleware module registration
|
||||
*/
|
||||
void SEGGER_SYSVIEW_RegisterModule (SEGGER_SYSVIEW_MODULE* pModule);
|
||||
void SEGGER_SYSVIEW_RecordModuleDescription (const SEGGER_SYSVIEW_MODULE* pModule, const char* sDescription);
|
||||
void SEGGER_SYSVIEW_SendModule (U8 ModuleId);
|
||||
void SEGGER_SYSVIEW_SendModuleDescription (void);
|
||||
void SEGGER_SYSVIEW_SendNumModules (void);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* printf-Style functions
|
||||
*/
|
||||
#ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
|
||||
void SEGGER_SYSVIEW_PrintfHostEx (const char* s, U32 Options, ...);
|
||||
void SEGGER_SYSVIEW_PrintfTargetEx (const char* s, U32 Options, ...);
|
||||
void SEGGER_SYSVIEW_PrintfHost (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_PrintfTarget (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_WarnfHost (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_WarnfTarget (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_ErrorfHost (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_ErrorfTarget (const char* s, ...);
|
||||
#endif
|
||||
|
||||
void SEGGER_SYSVIEW_Print (const char* s);
|
||||
void SEGGER_SYSVIEW_Warn (const char* s);
|
||||
void SEGGER_SYSVIEW_Error (const char* s);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Run-time configuration functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_EnableEvents (U32 EnableMask);
|
||||
void SEGGER_SYSVIEW_DisableEvents (U32 DisableMask);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Application-provided functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_Conf (void);
|
||||
U32 SEGGER_SYSVIEW_X_GetTimestamp (void);
|
||||
U32 SEGGER_SYSVIEW_X_GetInterruptId (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
File : SEGGER_SYSVIEW.h
|
||||
Purpose : System visualization API.
|
||||
Revision: $Rev: 5626 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_H
|
||||
#define SEGGER_SYSVIEW_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* #include Section
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "SEGGER.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Defines, fixed
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#define SEGGER_SYSVIEW_VERSION 21000
|
||||
|
||||
#define SEGGER_SYSVIEW_INFO_SIZE 9 // Minimum size, which has to be reserved for a packet. 1-2 byte of message type, 0-2 byte of payload length, 1-5 bytes of timestamp.
|
||||
#define SEGGER_SYSVIEW_QUANTA_U32 5 // Maximum number of bytes to encode a U32, should be reserved for each 32-bit value in a packet.
|
||||
|
||||
#define SEGGER_SYSVIEW_LOG (0u)
|
||||
#define SEGGER_SYSVIEW_WARNING (1u)
|
||||
#define SEGGER_SYSVIEW_ERROR (2u)
|
||||
#define SEGGER_SYSVIEW_FLAG_APPEND (1u << 6)
|
||||
|
||||
#define SEGGER_SYSVIEW_PREPARE_PACKET(p) (p) + 4
|
||||
//
|
||||
// SystemView events. First 32 IDs from 0 .. 31 are reserved for these
|
||||
//
|
||||
#define SYSVIEW_EVTID_NOP 0 // Dummy packet.
|
||||
#define SYSVIEW_EVTID_OVERFLOW 1
|
||||
#define SYSVIEW_EVTID_ISR_ENTER 2
|
||||
#define SYSVIEW_EVTID_ISR_EXIT 3
|
||||
#define SYSVIEW_EVTID_TASK_START_EXEC 4
|
||||
#define SYSVIEW_EVTID_TASK_STOP_EXEC 5
|
||||
#define SYSVIEW_EVTID_TASK_START_READY 6
|
||||
#define SYSVIEW_EVTID_TASK_STOP_READY 7
|
||||
#define SYSVIEW_EVTID_TASK_CREATE 8
|
||||
#define SYSVIEW_EVTID_TASK_INFO 9
|
||||
#define SYSVIEW_EVTID_TRACE_START 10
|
||||
#define SYSVIEW_EVTID_TRACE_STOP 11
|
||||
#define SYSVIEW_EVTID_SYSTIME_CYCLES 12
|
||||
#define SYSVIEW_EVTID_SYSTIME_US 13
|
||||
#define SYSVIEW_EVTID_SYSDESC 14
|
||||
#define SYSVIEW_EVTID_USER_START 15
|
||||
#define SYSVIEW_EVTID_USER_STOP 16
|
||||
#define SYSVIEW_EVTID_IDLE 17
|
||||
#define SYSVIEW_EVTID_ISR_TO_SCHEDULER 18
|
||||
#define SYSVIEW_EVTID_TIMER_ENTER 19
|
||||
#define SYSVIEW_EVTID_TIMER_EXIT 20
|
||||
#define SYSVIEW_EVTID_STACK_INFO 21
|
||||
#define SYSVIEW_EVTID_MODULEDESC 22
|
||||
|
||||
#define SYSVIEW_EVTID_INIT 24
|
||||
#define SYSVIEW_EVTID_NAME_RESOURCE 25
|
||||
#define SYSVIEW_EVTID_PRINT_FORMATTED 26
|
||||
#define SYSVIEW_EVTID_NUMMODULES 27
|
||||
#define SYSVIEW_EVTID_END_CALL 28
|
||||
#define SYSVIEW_EVTID_TASK_TERMINATE 29
|
||||
|
||||
#define SYSVIEW_EVTID_EX 31
|
||||
//
|
||||
// Event masks to disable/enable events
|
||||
//
|
||||
#define SYSVIEW_EVTMASK_NOP (1 << SYSVIEW_EVTID_NOP)
|
||||
#define SYSVIEW_EVTMASK_OVERFLOW (1 << SYSVIEW_EVTID_OVERFLOW)
|
||||
#define SYSVIEW_EVTMASK_ISR_ENTER (1 << SYSVIEW_EVTID_ISR_ENTER)
|
||||
#define SYSVIEW_EVTMASK_ISR_EXIT (1 << SYSVIEW_EVTID_ISR_EXIT)
|
||||
#define SYSVIEW_EVTMASK_TASK_START_EXEC (1 << SYSVIEW_EVTID_TASK_START_EXEC)
|
||||
#define SYSVIEW_EVTMASK_TASK_STOP_EXEC (1 << SYSVIEW_EVTID_TASK_STOP_EXEC)
|
||||
#define SYSVIEW_EVTMASK_TASK_START_READY (1 << SYSVIEW_EVTID_TASK_START_READY)
|
||||
#define SYSVIEW_EVTMASK_TASK_STOP_READY (1 << SYSVIEW_EVTID_TASK_STOP_READY)
|
||||
#define SYSVIEW_EVTMASK_TASK_CREATE (1 << SYSVIEW_EVTID_TASK_CREATE)
|
||||
#define SYSVIEW_EVTMASK_TASK_INFO (1 << SYSVIEW_EVTID_TASK_INFO)
|
||||
#define SYSVIEW_EVTMASK_TRACE_START (1 << SYSVIEW_EVTID_TRACE_START)
|
||||
#define SYSVIEW_EVTMASK_TRACE_STOP (1 << SYSVIEW_EVTID_TRACE_STOP)
|
||||
#define SYSVIEW_EVTMASK_SYSTIME_CYCLES (1 << SYSVIEW_EVTID_SYSTIME_CYCLES)
|
||||
#define SYSVIEW_EVTMASK_SYSTIME_US (1 << SYSVIEW_EVTID_SYSTIME_US)
|
||||
#define SYSVIEW_EVTMASK_SYSDESC (1 << SYSVIEW_EVTID_SYSDESC)
|
||||
#define SYSVIEW_EVTMASK_USER_START (1 << SYSVIEW_EVTID_USER_START)
|
||||
#define SYSVIEW_EVTMASK_USER_STOP (1 << SYSVIEW_EVTID_USER_STOP)
|
||||
#define SYSVIEW_EVTMASK_IDLE (1 << SYSVIEW_EVTID_IDLE)
|
||||
#define SYSVIEW_EVTMASK_ISR_TO_SCHEDULER (1 << SYSVIEW_EVTID_ISR_TO_SCHEDULER)
|
||||
#define SYSVIEW_EVTMASK_TIMER_ENTER (1 << SYSVIEW_EVTID_TIMER_ENTER)
|
||||
#define SYSVIEW_EVTMASK_TIMER_EXIT (1 << SYSVIEW_EVTID_TIMER_EXIT)
|
||||
#define SYSVIEW_EVTMASK_STACK_INFO (1 << SYSVIEW_EVTID_STACK_INFO)
|
||||
#define SYSVIEW_EVTMASK_MODULEDESC (1 << SYSVIEW_EVTID_MODULEDESC)
|
||||
|
||||
#define SYSVIEW_EVTMASK_INIT (1 << SYSVIEW_EVTID_INIT)
|
||||
#define SYSVIEW_EVTMASK_NAME_RESOURCE (1 << SYSVIEW_EVTID_NAME_RESOURCE)
|
||||
#define SYSVIEW_EVTMASK_PRINT_FORMATTED (1 << SYSVIEW_EVTID_PRINT_FORMATTED)
|
||||
#define SYSVIEW_EVTMASK_NUMMODULES (1 << SYSVIEW_EVTID_NUMMODULES)
|
||||
#define SYSVIEW_EVTMASK_END_CALL (1 << SYSVIEW_EVTID_END_CALL)
|
||||
#define SYSVIEW_EVTMASK_TASK_TERMINATE (1 << SYSVIEW_EVTID_TASK_TERMINATE)
|
||||
|
||||
#define SYSVIEW_EVTMASK_EX (1 << SYSVIEW_EVTID_EX)
|
||||
|
||||
#define SYSVIEW_EVTMASK_ALL_INTERRUPTS ( SYSVIEW_EVTMASK_ISR_ENTER \
|
||||
| SYSVIEW_EVTMASK_ISR_EXIT \
|
||||
| SYSVIEW_EVTMASK_ISR_TO_SCHEDULER)
|
||||
#define SYSVIEW_EVTMASK_ALL_TASKS ( SYSVIEW_EVTMASK_TASK_START_EXEC \
|
||||
| SYSVIEW_EVTMASK_TASK_STOP_EXEC \
|
||||
| SYSVIEW_EVTMASK_TASK_START_READY \
|
||||
| SYSVIEW_EVTMASK_TASK_STOP_READY \
|
||||
| SYSVIEW_EVTMASK_TASK_CREATE \
|
||||
| SYSVIEW_EVTMASK_TASK_INFO \
|
||||
| SYSVIEW_EVTMASK_STACK_INFO \
|
||||
| SYSVIEW_EVTMASK_TASK_TERMINATE)
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Structures
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
U32 TaskID;
|
||||
const char* sName;
|
||||
U32 Prio;
|
||||
U32 StackBase;
|
||||
U32 StackSize;
|
||||
} SEGGER_SYSVIEW_TASKINFO;
|
||||
|
||||
typedef struct SEGGER_SYSVIEW_MODULE_STRUCT SEGGER_SYSVIEW_MODULE;
|
||||
|
||||
struct SEGGER_SYSVIEW_MODULE_STRUCT {
|
||||
const char* sModule;
|
||||
U32 NumEvents;
|
||||
U32 EventOffset;
|
||||
void (*pfSendModuleDesc)(void);
|
||||
SEGGER_SYSVIEW_MODULE* pNext;
|
||||
};
|
||||
|
||||
typedef void (SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC)(void);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* API functions
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
U64 (*pfGetTime) (void);
|
||||
void (*pfSendTaskList) (void);
|
||||
} SEGGER_SYSVIEW_OS_API;
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Control and initialization functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_Init (U32 SysFreq, U32 CPUFreq, const SEGGER_SYSVIEW_OS_API *pOSAPI, SEGGER_SYSVIEW_SEND_SYS_DESC_FUNC pfSendSysDesc);
|
||||
void SEGGER_SYSVIEW_SetRAMBase (U32 RAMBaseAddress);
|
||||
void SEGGER_SYSVIEW_Start (void);
|
||||
void SEGGER_SYSVIEW_Stop (void);
|
||||
void SEGGER_SYSVIEW_GetSysDesc (void);
|
||||
void SEGGER_SYSVIEW_SendTaskList (void);
|
||||
void SEGGER_SYSVIEW_SendTaskInfo (const SEGGER_SYSVIEW_TASKINFO* pInfo);
|
||||
void SEGGER_SYSVIEW_SendSysDesc (const char* sSysDesc);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Event recording functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_RecordVoid (unsigned int EventId);
|
||||
void SEGGER_SYSVIEW_RecordU32 (unsigned int EventId, U32 Para0);
|
||||
void SEGGER_SYSVIEW_RecordU32x2 (unsigned int EventId, U32 Para0, U32 Para1);
|
||||
void SEGGER_SYSVIEW_RecordU32x3 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2);
|
||||
void SEGGER_SYSVIEW_RecordU32x4 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3);
|
||||
void SEGGER_SYSVIEW_RecordU32x5 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4);
|
||||
void SEGGER_SYSVIEW_RecordU32x6 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5);
|
||||
void SEGGER_SYSVIEW_RecordU32x7 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6);
|
||||
void SEGGER_SYSVIEW_RecordU32x8 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7);
|
||||
void SEGGER_SYSVIEW_RecordU32x9 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8);
|
||||
void SEGGER_SYSVIEW_RecordU32x10 (unsigned int EventId, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4, U32 Para5, U32 Para6, U32 Para7, U32 Para8, U32 Para9);
|
||||
void SEGGER_SYSVIEW_RecordString (unsigned int EventId, const char* pString);
|
||||
void SEGGER_SYSVIEW_RecordSystime (void);
|
||||
void SEGGER_SYSVIEW_RecordEnterISR (U32 IrqId);
|
||||
void SEGGER_SYSVIEW_RecordExitISR (void);
|
||||
void SEGGER_SYSVIEW_RecordExitISRToScheduler (void);
|
||||
void SEGGER_SYSVIEW_RecordEnterTimer (U32 TimerId);
|
||||
void SEGGER_SYSVIEW_RecordExitTimer (void);
|
||||
void SEGGER_SYSVIEW_RecordEndCall (unsigned int EventID);
|
||||
void SEGGER_SYSVIEW_RecordEndCallU32 (unsigned int EventID, U32 Para0);
|
||||
|
||||
void SEGGER_SYSVIEW_OnIdle (void);
|
||||
void SEGGER_SYSVIEW_OnTaskCreate (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskTerminate (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskStartExec (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskStopExec (void);
|
||||
void SEGGER_SYSVIEW_OnTaskStartReady (U32 TaskId);
|
||||
void SEGGER_SYSVIEW_OnTaskStopReady (U32 TaskId, unsigned int Cause);
|
||||
void SEGGER_SYSVIEW_OnUserStart (unsigned int UserId); // Start of user defined event (such as a subroutine to profile)
|
||||
void SEGGER_SYSVIEW_OnUserStop (unsigned int UserId); // Start of user defined event
|
||||
|
||||
void SEGGER_SYSVIEW_NameResource (U32 ResourceId, const char* sName);
|
||||
|
||||
int SEGGER_SYSVIEW_SendPacket (U8* pPacket, U8* pPayloadEnd, unsigned int EventId);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Event parameter encoding functions
|
||||
*/
|
||||
U8* SEGGER_SYSVIEW_EncodeU32 (U8* pPayload, U32 Value);
|
||||
U8* SEGGER_SYSVIEW_EncodeData (U8* pPayload, const char* pSrc, unsigned int Len);
|
||||
U8* SEGGER_SYSVIEW_EncodeString (U8* pPayload, const char* s, unsigned int MaxLen);
|
||||
U8* SEGGER_SYSVIEW_EncodeId (U8* pPayload, U32 Id);
|
||||
U32 SEGGER_SYSVIEW_ShrinkId (U32 Id);
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Middleware module registration
|
||||
*/
|
||||
void SEGGER_SYSVIEW_RegisterModule (SEGGER_SYSVIEW_MODULE* pModule);
|
||||
void SEGGER_SYSVIEW_RecordModuleDescription (const SEGGER_SYSVIEW_MODULE* pModule, const char* sDescription);
|
||||
void SEGGER_SYSVIEW_SendModule (U8 ModuleId);
|
||||
void SEGGER_SYSVIEW_SendModuleDescription (void);
|
||||
void SEGGER_SYSVIEW_SendNumModules (void);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* printf-Style functions
|
||||
*/
|
||||
#ifndef SEGGER_SYSVIEW_EXCLUDE_PRINTF // Define in project to avoid warnings about variable parameter list
|
||||
void SEGGER_SYSVIEW_PrintfHostEx (const char* s, U32 Options, ...);
|
||||
void SEGGER_SYSVIEW_PrintfTargetEx (const char* s, U32 Options, ...);
|
||||
void SEGGER_SYSVIEW_PrintfHost (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_PrintfTarget (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_WarnfHost (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_WarnfTarget (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_ErrorfHost (const char* s, ...);
|
||||
void SEGGER_SYSVIEW_ErrorfTarget (const char* s, ...);
|
||||
#endif
|
||||
|
||||
void SEGGER_SYSVIEW_Print (const char* s);
|
||||
void SEGGER_SYSVIEW_Warn (const char* s);
|
||||
void SEGGER_SYSVIEW_Error (const char* s);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Run-time configuration functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_EnableEvents (U32 EnableMask);
|
||||
void SEGGER_SYSVIEW_DisableEvents (U32 DisableMask);
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Application-provided functions
|
||||
*/
|
||||
void SEGGER_SYSVIEW_Conf (void);
|
||||
U32 SEGGER_SYSVIEW_X_GetTimestamp (void);
|
||||
U32 SEGGER_SYSVIEW_X_GetInterruptId (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -1,178 +1,178 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
File : SEGGER_SYSVIEW_ConfDefaults.h
|
||||
Purpose : Defines defaults for configurable defines used in
|
||||
SEGGER SystemView.
|
||||
Revision: $Rev: 3734 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_CONFDEFAULTS_H
|
||||
#define SEGGER_SYSVIEW_CONFDEFAULTS_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* #include Section
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "SEGGER_SYSVIEW_Conf.h"
|
||||
#include "SEGGER_RTT_Conf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Configuration defaults
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
// Number of bytes that SystemView uses for a buffer.
|
||||
#ifndef SEGGER_SYSVIEW_RTT_BUFFER_SIZE
|
||||
#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024
|
||||
#endif
|
||||
|
||||
// The RTT channel that SystemView will use.
|
||||
#ifndef SEGGER_SYSVIEW_RTT_CHANNEL
|
||||
#define SEGGER_SYSVIEW_RTT_CHANNEL 0
|
||||
#endif
|
||||
// Sanity check of RTT channel
|
||||
#if (SEGGER_SYSVIEW_RTT_CHANNEL == 0) && (SEGGER_RTT_MAX_NUM_UP_BUFFERS < 2)
|
||||
#error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > 1!"
|
||||
#elif (SEGGER_SYSVIEW_RTT_CHANNEL >= SEGGER_RTT_MAX_NUM_UP_BUFFERS)
|
||||
#error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > SEGGER_SYSVIEW_RTT_CHANNEL!"
|
||||
#endif
|
||||
|
||||
// Place the SystemView buffer into its own/the RTT section
|
||||
#if !(defined SEGGER_SYSVIEW_BUFFER_SECTION) && (defined SEGGER_RTT_SECTION)
|
||||
#define SEGGER_SYSVIEW_BUFFER_SECTION SEGGER_RTT_SECTION
|
||||
#endif
|
||||
|
||||
// Retrieve a system timestamp. This gets the Cortex-M cycle counter.
|
||||
#ifndef SEGGER_SYSVIEW_GET_TIMESTAMP
|
||||
#error "SEGGER_SYSVIEW_GET_TIMESTAMP has to be defined in SEGGER_SYSVIEW_Conf.h!"
|
||||
#endif
|
||||
|
||||
// Define number of valid bits low-order delivered by clock source.
|
||||
#ifndef SEGGER_SYSVIEW_TIMESTAMP_BITS
|
||||
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32
|
||||
#endif
|
||||
|
||||
// Lowest Id reported by the Application.
|
||||
#ifndef SEGGER_SYSVIEW_ID_BASE
|
||||
#define SEGGER_SYSVIEW_ID_BASE 0
|
||||
#endif
|
||||
|
||||
// Number of bits to shift Ids to save bandwidth
|
||||
#ifndef SEGGER_SYSVIEW_ID_SHIFT
|
||||
#define SEGGER_SYSVIEW_ID_SHIFT 0
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_GET_INTERRUPT_ID
|
||||
#error "SEGGER_SYSVIEW_GET_INTERRUPT_ID has to be defined in SEGGER_SYSVIEW_Conf.h!"
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_MAX_ARGUMENTS
|
||||
#define SEGGER_SYSVIEW_MAX_ARGUMENTS 16
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_MAX_STRING_LEN
|
||||
#define SEGGER_SYSVIEW_MAX_STRING_LEN 128
|
||||
#endif
|
||||
|
||||
// Use a static buffer instead of a buffer on the stack for packets
|
||||
#ifndef SEGGER_SYSVIEW_USE_STATIC_BUFFER
|
||||
#define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1
|
||||
#endif
|
||||
|
||||
// Maximum packet size used by SystemView for the static buffer
|
||||
#ifndef SEGGER_SYSVIEW_MAX_PACKET_SIZE
|
||||
#define SEGGER_SYSVIEW_MAX_PACKET_SIZE SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_ARGUMENTS * SEGGER_SYSVIEW_QUANTA_U32
|
||||
#endif
|
||||
|
||||
// Use post-mortem analysis instead of real-time analysis
|
||||
#ifndef SEGGER_SYSVIEW_POST_MORTEM_MODE
|
||||
#define SEGGER_SYSVIEW_POST_MORTEM_MODE 0
|
||||
#endif
|
||||
|
||||
// Configure how frequently syncronization is sent
|
||||
#ifndef SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT
|
||||
#define SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT 8
|
||||
#endif
|
||||
|
||||
// Lock SystemView (nestable)
|
||||
#ifndef SEGGER_SYSVIEW_LOCK
|
||||
#define SEGGER_SYSVIEW_LOCK() SEGGER_RTT_LOCK()
|
||||
#endif
|
||||
|
||||
// Unlock SystemView (nestable)
|
||||
#ifndef SEGGER_SYSVIEW_UNLOCK
|
||||
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_RTT_UNLOCK()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
File : SEGGER_SYSVIEW_ConfDefaults.h
|
||||
Purpose : Defines defaults for configurable defines used in
|
||||
SEGGER SystemView.
|
||||
Revision: $Rev: 3734 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_CONFDEFAULTS_H
|
||||
#define SEGGER_SYSVIEW_CONFDEFAULTS_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* #include Section
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "SEGGER_SYSVIEW_Conf.h"
|
||||
#include "SEGGER_RTT_Conf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Configuration defaults
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
// Number of bytes that SystemView uses for a buffer.
|
||||
#ifndef SEGGER_SYSVIEW_RTT_BUFFER_SIZE
|
||||
#define SEGGER_SYSVIEW_RTT_BUFFER_SIZE 1024
|
||||
#endif
|
||||
|
||||
// The RTT channel that SystemView will use.
|
||||
#ifndef SEGGER_SYSVIEW_RTT_CHANNEL
|
||||
#define SEGGER_SYSVIEW_RTT_CHANNEL 0
|
||||
#endif
|
||||
// Sanity check of RTT channel
|
||||
#if (SEGGER_SYSVIEW_RTT_CHANNEL == 0) && (SEGGER_RTT_MAX_NUM_UP_BUFFERS < 2)
|
||||
#error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > 1!"
|
||||
#elif (SEGGER_SYSVIEW_RTT_CHANNEL >= SEGGER_RTT_MAX_NUM_UP_BUFFERS)
|
||||
#error "SEGGER_RTT_MAX_NUM_UP_BUFFERS in SEGGER_RTT_Conf.h has to be > SEGGER_SYSVIEW_RTT_CHANNEL!"
|
||||
#endif
|
||||
|
||||
// Place the SystemView buffer into its own/the RTT section
|
||||
#if !(defined SEGGER_SYSVIEW_BUFFER_SECTION) && (defined SEGGER_RTT_SECTION)
|
||||
#define SEGGER_SYSVIEW_BUFFER_SECTION SEGGER_RTT_SECTION
|
||||
#endif
|
||||
|
||||
// Retrieve a system timestamp. This gets the Cortex-M cycle counter.
|
||||
#ifndef SEGGER_SYSVIEW_GET_TIMESTAMP
|
||||
#error "SEGGER_SYSVIEW_GET_TIMESTAMP has to be defined in SEGGER_SYSVIEW_Conf.h!"
|
||||
#endif
|
||||
|
||||
// Define number of valid bits low-order delivered by clock source.
|
||||
#ifndef SEGGER_SYSVIEW_TIMESTAMP_BITS
|
||||
#define SEGGER_SYSVIEW_TIMESTAMP_BITS 32
|
||||
#endif
|
||||
|
||||
// Lowest Id reported by the Application.
|
||||
#ifndef SEGGER_SYSVIEW_ID_BASE
|
||||
#define SEGGER_SYSVIEW_ID_BASE 0
|
||||
#endif
|
||||
|
||||
// Number of bits to shift Ids to save bandwidth
|
||||
#ifndef SEGGER_SYSVIEW_ID_SHIFT
|
||||
#define SEGGER_SYSVIEW_ID_SHIFT 0
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_GET_INTERRUPT_ID
|
||||
#error "SEGGER_SYSVIEW_GET_INTERRUPT_ID has to be defined in SEGGER_SYSVIEW_Conf.h!"
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_MAX_ARGUMENTS
|
||||
#define SEGGER_SYSVIEW_MAX_ARGUMENTS 16
|
||||
#endif
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_MAX_STRING_LEN
|
||||
#define SEGGER_SYSVIEW_MAX_STRING_LEN 128
|
||||
#endif
|
||||
|
||||
// Use a static buffer instead of a buffer on the stack for packets
|
||||
#ifndef SEGGER_SYSVIEW_USE_STATIC_BUFFER
|
||||
#define SEGGER_SYSVIEW_USE_STATIC_BUFFER 1
|
||||
#endif
|
||||
|
||||
// Maximum packet size used by SystemView for the static buffer
|
||||
#ifndef SEGGER_SYSVIEW_MAX_PACKET_SIZE
|
||||
#define SEGGER_SYSVIEW_MAX_PACKET_SIZE SEGGER_SYSVIEW_INFO_SIZE + SEGGER_SYSVIEW_MAX_STRING_LEN + 2 * SEGGER_SYSVIEW_QUANTA_U32 + SEGGER_SYSVIEW_MAX_ARGUMENTS * SEGGER_SYSVIEW_QUANTA_U32
|
||||
#endif
|
||||
|
||||
// Use post-mortem analysis instead of real-time analysis
|
||||
#ifndef SEGGER_SYSVIEW_POST_MORTEM_MODE
|
||||
#define SEGGER_SYSVIEW_POST_MORTEM_MODE 0
|
||||
#endif
|
||||
|
||||
// Configure how frequently syncronization is sent
|
||||
#ifndef SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT
|
||||
#define SEGGER_SYSVIEW_SYNC_PERIOD_SHIFT 8
|
||||
#endif
|
||||
|
||||
// Lock SystemView (nestable)
|
||||
#ifndef SEGGER_SYSVIEW_LOCK
|
||||
#define SEGGER_SYSVIEW_LOCK() SEGGER_RTT_LOCK()
|
||||
#endif
|
||||
|
||||
// Unlock SystemView (nestable)
|
||||
#ifndef SEGGER_SYSVIEW_UNLOCK
|
||||
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_RTT_UNLOCK()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -1,110 +1,110 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
File : SEGGER_SYSVIEW_Int.h
|
||||
Purpose : SEGGER SystemView internal header.
|
||||
Revision: $Rev: 5626 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_INT_H
|
||||
#define SEGGER_SYSVIEW_INT_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* #include Section
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "SEGGER_SYSVIEW.h"
|
||||
#include "SEGGER_SYSVIEW_Conf.h"
|
||||
#include "SEGGER_SYSVIEW_ConfDefaults.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Private data types
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
//
|
||||
// Commands that Host can send to target
|
||||
//
|
||||
typedef enum {
|
||||
SEGGER_SYSVIEW_COMMAND_ID_START = 1,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_STOP,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_SYSTIME,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_TASKLIST,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_SYSDESC,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_NUMMODULES,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_MODULEDESC,
|
||||
// Extended commands: Commands >= 128 have a second parameter
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_MODULE = 128
|
||||
} SEGGER_SYSVIEW_COMMAND_ID;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
File : SEGGER_SYSVIEW_Int.h
|
||||
Purpose : SEGGER SystemView internal header.
|
||||
Revision: $Rev: 5626 $
|
||||
*/
|
||||
|
||||
#ifndef SEGGER_SYSVIEW_INT_H
|
||||
#define SEGGER_SYSVIEW_INT_H
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* #include Section
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "SEGGER_SYSVIEW.h"
|
||||
#include "SEGGER_SYSVIEW_Conf.h"
|
||||
#include "SEGGER_SYSVIEW_ConfDefaults.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Private data types
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
//
|
||||
// Commands that Host can send to target
|
||||
//
|
||||
typedef enum {
|
||||
SEGGER_SYSVIEW_COMMAND_ID_START = 1,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_STOP,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_SYSTIME,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_TASKLIST,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_SYSDESC,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_NUMMODULES,
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_MODULEDESC,
|
||||
// Extended commands: Commands >= 128 have a second parameter
|
||||
SEGGER_SYSVIEW_COMMAND_ID_GET_MODULE = 128
|
||||
} SEGGER_SYSVIEW_COMMAND_ID;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -1,290 +1,290 @@
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
|
||||
File : SEGGER_SYSVIEW_FreeRTOS.c
|
||||
Purpose : Interface between FreeRTOS and SystemView.
|
||||
Revision: $Rev: 3734 $
|
||||
*/
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "SEGGER_SYSVIEW.h"
|
||||
#include "SEGGER_SYSVIEW_FreeRTOS.h"
|
||||
#include "string.h" // Required for memset
|
||||
|
||||
|
||||
|
||||
typedef struct SYSVIEW_FREERTOS_TASK_STATUS SYSVIEW_FREERTOS_TASK_STATUS;
|
||||
|
||||
struct SYSVIEW_FREERTOS_TASK_STATUS {
|
||||
U32 xHandle;
|
||||
const char* pcTaskName;
|
||||
unsigned uxCurrentPriority;
|
||||
U32 pxStack;
|
||||
unsigned uStackHighWaterMark;
|
||||
};
|
||||
|
||||
static SYSVIEW_FREERTOS_TASK_STATUS _aTasks[SYSVIEW_FREERTOS_MAX_NOF_TASKS];
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* _cbSendTaskList()
|
||||
*
|
||||
* Function description
|
||||
* This function is part of the link between FreeRTOS and SYSVIEW.
|
||||
* Called from SystemView when asked by the host, it uses SYSVIEW
|
||||
* functions to send the entire task list to the host.
|
||||
*/
|
||||
static void _cbSendTaskList(void) {
|
||||
unsigned n;
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle) {
|
||||
#if INCLUDE_uxTaskGetStackHighWaterMark // Report Task Stack High Watermark
|
||||
_aTasks[n].uStackHighWaterMark = uxTaskGetStackHighWaterMark((TaskHandle_t)_aTasks[n].xHandle);
|
||||
#endif
|
||||
SYSVIEW_SendTaskInfo((U32)_aTasks[n].xHandle, _aTasks[n].pcTaskName, (unsigned)_aTasks[n].uxCurrentPriority, (U32)_aTasks[n].pxStack, (unsigned)_aTasks[n].uStackHighWaterMark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* _cbGetTime()
|
||||
*
|
||||
* Function description
|
||||
* This function is part of the link between FreeRTOS and SYSVIEW.
|
||||
* Called from SystemView when asked by the host, returns the
|
||||
* current system time in micro seconds.
|
||||
*/
|
||||
static U64 _cbGetTime(void) {
|
||||
U64 Time;
|
||||
|
||||
Time = xTaskGetTickCountFromISR();
|
||||
Time *= portTICK_PERIOD_MS;
|
||||
Time *= 1000;
|
||||
return Time;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Global functions
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_AddTask()
|
||||
*
|
||||
* Function description
|
||||
* Add a task to the internal list and record its information.
|
||||
*/
|
||||
void SYSVIEW_AddTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
|
||||
unsigned n;
|
||||
|
||||
if (memcmp(pcTaskName, "IDLE", 5) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
|
||||
SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not record task information. Maximum number of tasks reached.");
|
||||
return;
|
||||
}
|
||||
|
||||
_aTasks[n].xHandle = xHandle;
|
||||
_aTasks[n].pcTaskName = pcTaskName;
|
||||
_aTasks[n].uxCurrentPriority = uxCurrentPriority;
|
||||
_aTasks[n].pxStack = pxStack;
|
||||
_aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
|
||||
|
||||
SYSVIEW_SendTaskInfo(xHandle, pcTaskName,uxCurrentPriority, pxStack, uStackHighWaterMark);
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_UpdateTask()
|
||||
*
|
||||
* Function description
|
||||
* Update a task in the internal list and record its information.
|
||||
*/
|
||||
void SYSVIEW_UpdateTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
|
||||
unsigned n;
|
||||
|
||||
if (memcmp(pcTaskName, "IDLE", 5) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle == xHandle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n < SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
|
||||
_aTasks[n].pcTaskName = pcTaskName;
|
||||
_aTasks[n].uxCurrentPriority = uxCurrentPriority;
|
||||
_aTasks[n].pxStack = pxStack;
|
||||
_aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
|
||||
|
||||
SYSVIEW_SendTaskInfo(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
|
||||
} else {
|
||||
SYSVIEW_AddTask(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_DeleteTask()
|
||||
*
|
||||
* Function description
|
||||
* Delete a task from the internal list.
|
||||
*/
|
||||
void SYSVIEW_DeleteTask(U32 xHandle) {
|
||||
unsigned n;
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle == xHandle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
|
||||
SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not find task information. Cannot delete task.");
|
||||
return;
|
||||
}
|
||||
|
||||
_aTasks[n].xHandle = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_SendTaskInfo()
|
||||
*
|
||||
* Function description
|
||||
* Record task information.
|
||||
*/
|
||||
void SYSVIEW_SendTaskInfo(U32 TaskID, const char* sName, unsigned Prio, U32 StackBase, unsigned StackSize) {
|
||||
SEGGER_SYSVIEW_TASKINFO TaskInfo;
|
||||
|
||||
memset(&TaskInfo, 0, sizeof(TaskInfo)); // Fill all elements with 0 to allow extending the structure in future version without breaking the code
|
||||
TaskInfo.TaskID = TaskID;
|
||||
TaskInfo.sName = sName;
|
||||
TaskInfo.Prio = Prio;
|
||||
TaskInfo.StackBase = StackBase;
|
||||
TaskInfo.StackSize = StackSize;
|
||||
SEGGER_SYSVIEW_SendTaskInfo(&TaskInfo);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_RecordU32x4()
|
||||
*
|
||||
* Function description
|
||||
* Record an event with 4 parameters
|
||||
*/
|
||||
void SYSVIEW_RecordU32x4(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3) {
|
||||
U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32];
|
||||
U8* pPayload;
|
||||
//
|
||||
pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
|
||||
//
|
||||
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_RecordU32x5()
|
||||
*
|
||||
* Function description
|
||||
* Record an event with 5 parameters
|
||||
*/
|
||||
void SYSVIEW_RecordU32x5(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4) {
|
||||
U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32];
|
||||
U8* pPayload;
|
||||
//
|
||||
pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para4); // Add the fifth parameter to the packet
|
||||
//
|
||||
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Public API structures
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
// Callbacks provided to SYSTEMVIEW by FreeRTOS
|
||||
const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = {
|
||||
_cbGetTime,
|
||||
_cbSendTaskList,
|
||||
};
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
/*********************************************************************
|
||||
* SEGGER Microcontroller GmbH & Co. KG *
|
||||
* The Embedded Experts *
|
||||
**********************************************************************
|
||||
* *
|
||||
* (c) 2015 - 2017 SEGGER Microcontroller GmbH & Co. KG *
|
||||
* *
|
||||
* www.segger.com Support: support@segger.com *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SEGGER SystemView * Real-time application analysis *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* SEGGER strongly recommends to not make any changes *
|
||||
* to or modify the source code of this software in order to stay *
|
||||
* compatible with the RTT protocol and J-Link. *
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or *
|
||||
* without modification, are permitted provided that the following *
|
||||
* conditions are met: *
|
||||
* *
|
||||
* o Redistributions of source code must retain the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* o Redistributions in binary form must reproduce the above *
|
||||
* copyright notice, this list of conditions and the following *
|
||||
* disclaimer in the documentation and/or other materials provided *
|
||||
* with the distribution. *
|
||||
* *
|
||||
* o Neither the name of SEGGER Microcontroller GmbH & Co. KG *
|
||||
* nor the names of its contributors may be used to endorse or *
|
||||
* promote products derived from this software without specific *
|
||||
* prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
|
||||
* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR *
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT *
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; *
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
|
||||
* DAMAGE. *
|
||||
* *
|
||||
**********************************************************************
|
||||
* *
|
||||
* SystemView version: V2.42 *
|
||||
* *
|
||||
**********************************************************************
|
||||
-------------------------- END-OF-HEADER -----------------------------
|
||||
|
||||
File : SEGGER_SYSVIEW_FreeRTOS.c
|
||||
Purpose : Interface between FreeRTOS and SystemView.
|
||||
Revision: $Rev: 3734 $
|
||||
*/
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "SEGGER_SYSVIEW.h"
|
||||
#include "SEGGER_SYSVIEW_FreeRTOS.h"
|
||||
#include "string.h" // Required for memset
|
||||
|
||||
|
||||
|
||||
typedef struct SYSVIEW_FREERTOS_TASK_STATUS SYSVIEW_FREERTOS_TASK_STATUS;
|
||||
|
||||
struct SYSVIEW_FREERTOS_TASK_STATUS {
|
||||
U32 xHandle;
|
||||
const char* pcTaskName;
|
||||
unsigned uxCurrentPriority;
|
||||
U32 pxStack;
|
||||
unsigned uStackHighWaterMark;
|
||||
};
|
||||
|
||||
static SYSVIEW_FREERTOS_TASK_STATUS _aTasks[SYSVIEW_FREERTOS_MAX_NOF_TASKS];
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* _cbSendTaskList()
|
||||
*
|
||||
* Function description
|
||||
* This function is part of the link between FreeRTOS and SYSVIEW.
|
||||
* Called from SystemView when asked by the host, it uses SYSVIEW
|
||||
* functions to send the entire task list to the host.
|
||||
*/
|
||||
static void _cbSendTaskList(void) {
|
||||
unsigned n;
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle) {
|
||||
#if INCLUDE_uxTaskGetStackHighWaterMark // Report Task Stack High Watermark
|
||||
_aTasks[n].uStackHighWaterMark = uxTaskGetStackHighWaterMark((TaskHandle_t)_aTasks[n].xHandle);
|
||||
#endif
|
||||
SYSVIEW_SendTaskInfo((U32)_aTasks[n].xHandle, _aTasks[n].pcTaskName, (unsigned)_aTasks[n].uxCurrentPriority, (U32)_aTasks[n].pxStack, (unsigned)_aTasks[n].uStackHighWaterMark);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* _cbGetTime()
|
||||
*
|
||||
* Function description
|
||||
* This function is part of the link between FreeRTOS and SYSVIEW.
|
||||
* Called from SystemView when asked by the host, returns the
|
||||
* current system time in micro seconds.
|
||||
*/
|
||||
static U64 _cbGetTime(void) {
|
||||
U64 Time;
|
||||
|
||||
Time = xTaskGetTickCountFromISR();
|
||||
Time *= portTICK_PERIOD_MS;
|
||||
Time *= 1000;
|
||||
return Time;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Global functions
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_AddTask()
|
||||
*
|
||||
* Function description
|
||||
* Add a task to the internal list and record its information.
|
||||
*/
|
||||
void SYSVIEW_AddTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
|
||||
unsigned n;
|
||||
|
||||
if (memcmp(pcTaskName, "IDLE", 5) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
|
||||
SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not record task information. Maximum number of tasks reached.");
|
||||
return;
|
||||
}
|
||||
|
||||
_aTasks[n].xHandle = xHandle;
|
||||
_aTasks[n].pcTaskName = pcTaskName;
|
||||
_aTasks[n].uxCurrentPriority = uxCurrentPriority;
|
||||
_aTasks[n].pxStack = pxStack;
|
||||
_aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
|
||||
|
||||
SYSVIEW_SendTaskInfo(xHandle, pcTaskName,uxCurrentPriority, pxStack, uStackHighWaterMark);
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_UpdateTask()
|
||||
*
|
||||
* Function description
|
||||
* Update a task in the internal list and record its information.
|
||||
*/
|
||||
void SYSVIEW_UpdateTask(U32 xHandle, const char* pcTaskName, unsigned uxCurrentPriority, U32 pxStack, unsigned uStackHighWaterMark) {
|
||||
unsigned n;
|
||||
|
||||
if (memcmp(pcTaskName, "IDLE", 5) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle == xHandle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n < SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
|
||||
_aTasks[n].pcTaskName = pcTaskName;
|
||||
_aTasks[n].uxCurrentPriority = uxCurrentPriority;
|
||||
_aTasks[n].pxStack = pxStack;
|
||||
_aTasks[n].uStackHighWaterMark = uStackHighWaterMark;
|
||||
|
||||
SYSVIEW_SendTaskInfo(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
|
||||
} else {
|
||||
SYSVIEW_AddTask(xHandle, pcTaskName, uxCurrentPriority, pxStack, uStackHighWaterMark);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_DeleteTask()
|
||||
*
|
||||
* Function description
|
||||
* Delete a task from the internal list.
|
||||
*/
|
||||
void SYSVIEW_DeleteTask(U32 xHandle) {
|
||||
unsigned n;
|
||||
|
||||
for (n = 0; n < SYSVIEW_FREERTOS_MAX_NOF_TASKS; n++) {
|
||||
if (_aTasks[n].xHandle == xHandle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n == SYSVIEW_FREERTOS_MAX_NOF_TASKS) {
|
||||
SEGGER_SYSVIEW_Warn("SYSTEMVIEW: Could not find task information. Cannot delete task.");
|
||||
return;
|
||||
}
|
||||
|
||||
_aTasks[n].xHandle = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_SendTaskInfo()
|
||||
*
|
||||
* Function description
|
||||
* Record task information.
|
||||
*/
|
||||
void SYSVIEW_SendTaskInfo(U32 TaskID, const char* sName, unsigned Prio, U32 StackBase, unsigned StackSize) {
|
||||
SEGGER_SYSVIEW_TASKINFO TaskInfo;
|
||||
|
||||
memset(&TaskInfo, 0, sizeof(TaskInfo)); // Fill all elements with 0 to allow extending the structure in future version without breaking the code
|
||||
TaskInfo.TaskID = TaskID;
|
||||
TaskInfo.sName = sName;
|
||||
TaskInfo.Prio = Prio;
|
||||
TaskInfo.StackBase = StackBase;
|
||||
TaskInfo.StackSize = StackSize;
|
||||
SEGGER_SYSVIEW_SendTaskInfo(&TaskInfo);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_RecordU32x4()
|
||||
*
|
||||
* Function description
|
||||
* Record an event with 4 parameters
|
||||
*/
|
||||
void SYSVIEW_RecordU32x4(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3) {
|
||||
U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 4 * SEGGER_SYSVIEW_QUANTA_U32];
|
||||
U8* pPayload;
|
||||
//
|
||||
pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
|
||||
//
|
||||
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* SYSVIEW_RecordU32x5()
|
||||
*
|
||||
* Function description
|
||||
* Record an event with 5 parameters
|
||||
*/
|
||||
void SYSVIEW_RecordU32x5(unsigned Id, U32 Para0, U32 Para1, U32 Para2, U32 Para3, U32 Para4) {
|
||||
U8 aPacket[SEGGER_SYSVIEW_INFO_SIZE + 5 * SEGGER_SYSVIEW_QUANTA_U32];
|
||||
U8* pPayload;
|
||||
//
|
||||
pPayload = SEGGER_SYSVIEW_PREPARE_PACKET(aPacket); // Prepare the packet for SystemView
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para0); // Add the first parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para1); // Add the second parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para2); // Add the third parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para3); // Add the fourth parameter to the packet
|
||||
pPayload = SEGGER_SYSVIEW_EncodeU32(pPayload, Para4); // Add the fifth parameter to the packet
|
||||
//
|
||||
SEGGER_SYSVIEW_SendPacket(&aPacket[0], pPayload, Id); // Send the packet
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Public API structures
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
// Callbacks provided to SYSTEMVIEW by FreeRTOS
|
||||
const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI = {
|
||||
_cbGetTime,
|
||||
_cbSendTaskList,
|
||||
};
|
||||
|
||||
/*************************** End of file ****************************/
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "rom/ets_sys.h"
|
||||
#include "esp_app_trace.h"
|
||||
|
||||
#define LOG_LOCAL_LEVEL ESP_LOG_ERROR
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "segger_rtt";
|
||||
|
||||
@@ -124,7 +125,7 @@ unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, u
|
||||
uint8_t event_id = *pbuf;
|
||||
|
||||
if (NumBytes > SYSVIEW_EVENTS_BUF_SZ) {
|
||||
ESP_LOGE(TAG, "Too large event %u bytes!", NumBytes);
|
||||
ESP_LOGE(TAG, "Too large event %d bytes!", NumBytes);
|
||||
return 0;
|
||||
}
|
||||
if (xPortGetCoreID()) { // dual core specific code
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
set(COMPONENT_SRCDIRS ".")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
|
||||
set(COMPONENT_REQUIRES unity)
|
||||
|
||||
register_component()
|
||||
@@ -1,17 +0,0 @@
|
||||
set(COMPONENT_SRCS "esp_ota_ops.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||
|
||||
set(COMPONENT_REQUIRES spi_flash partition_table)
|
||||
set(COMPONENT_PRIV_REQUIRES bootloader_support)
|
||||
|
||||
register_component()
|
||||
|
||||
# Add custom target for generating empty otadata partition for flashing
|
||||
if(${OTADATA_PARTITION_OFFSET})
|
||||
add_custom_command(OUTPUT "${PROJECT_BINARY_DIR}/${BLANK_OTADATA_FILE}"
|
||||
COMMAND ${PYTHON} ${CMAKE_CURRENT_SOURCE_DIR}/gen_empty_partition.py
|
||||
--size ${OTADATA_PARTITION_SIZE} "${PROJECT_BINARY_DIR}/${BLANK_OTADATA_FILE}")
|
||||
|
||||
add_custom_target(blank_ota_data ALL DEPENDS "${PROJECT_BINARY_DIR}/${BLANK_OTADATA_FILE}")
|
||||
add_dependencies(flash blank_ota_data)
|
||||
endif()
|
||||
@@ -1,60 +0,0 @@
|
||||
# Generate partition binary
|
||||
#
|
||||
.PHONY: dump_otadata erase_ota blank_ota_data
|
||||
|
||||
GEN_EMPTY_PART := $(PYTHON) $(COMPONENT_PATH)/gen_empty_partition.py
|
||||
BLANK_OTA_DATA_FILE = $(BUILD_DIR_BASE)/ota_data_initial.bin
|
||||
|
||||
PARTITION_TABLE_LEN := 0xC00
|
||||
OTADATA_LEN := 0x2000
|
||||
|
||||
PARTITION_TABLE_ONCHIP_BIN_PATH := $(call dequote,$(abspath $(BUILD_DIR_BASE)))
|
||||
PARTITION_TABLE_ONCHIP_BIN_NAME := "onchip_partition.bin"
|
||||
OTADATA_ONCHIP_BIN_NAME := "onchip_otadata.bin"
|
||||
|
||||
PARTITION_TABLE_ONCHIP_BIN := $(PARTITION_TABLE_ONCHIP_BIN_PATH)/$(call dequote,$(PARTITION_TABLE_ONCHIP_BIN_NAME))
|
||||
OTADATA_ONCHIP_BIN := $(PARTITION_TABLE_ONCHIP_BIN_PATH)/$(call dequote,$(OTADATA_ONCHIP_BIN_NAME))
|
||||
|
||||
PARTITION_TABLE_GET_BIN_CMD = $(ESPTOOLPY_SERIAL) read_flash $(PARTITION_TABLE_OFFSET) $(PARTITION_TABLE_LEN) $(PARTITION_TABLE_ONCHIP_BIN)
|
||||
OTADATA_GET_BIN_CMD = $(ESPTOOLPY_SERIAL) read_flash $(OTADATA_OFFSET) $(OTADATA_LEN) $(OTADATA_ONCHIP_BIN)
|
||||
|
||||
GEN_OTADATA = $(IDF_PATH)/components/app_update/dump_otadata.py
|
||||
ERASE_OTADATA_CMD = $(ESPTOOLPY_SERIAL) erase_region $(OTADATA_OFFSET) $(OTADATA_LEN)
|
||||
|
||||
# If there is no otadata partition, both OTA_DATA_OFFSET and BLANK_OTA_DATA_FILE
|
||||
# expand to empty values.
|
||||
ESPTOOL_ALL_FLASH_ARGS += $(OTA_DATA_OFFSET) $(BLANK_OTA_DATA_FILE)
|
||||
|
||||
$(PARTITION_TABLE_ONCHIP_BIN):
|
||||
$(PARTITION_TABLE_GET_BIN_CMD)
|
||||
|
||||
onchip_otadata_get_info: $(PARTITION_TABLE_ONCHIP_BIN)
|
||||
$(eval OTADATA_OFFSET:=$(shell $(GET_PART_INFO) --type data --subtype ota --offset $(PARTITION_TABLE_ONCHIP_BIN)))
|
||||
@echo $(if $(OTADATA_OFFSET), $(shell export OTADATA_OFFSET), $(shell rm -f $(PARTITION_TABLE_ONCHIP_BIN));$(error "ERROR: ESP32 does not have otadata partition."))
|
||||
|
||||
$(OTADATA_ONCHIP_BIN):
|
||||
$(OTADATA_GET_BIN_CMD)
|
||||
|
||||
dump_otadata: onchip_otadata_get_info $(OTADATA_ONCHIP_BIN) $(PARTITION_TABLE_ONCHIP_BIN)
|
||||
@echo "otadata retrieved. Contents:"
|
||||
@echo $(SEPARATOR)
|
||||
$(GEN_OTADATA) $(OTADATA_ONCHIP_BIN)
|
||||
@echo $(SEPARATOR)
|
||||
rm -f $(PARTITION_TABLE_ONCHIP_BIN)
|
||||
rm -f $(OTADATA_ONCHIP_BIN)
|
||||
|
||||
$(BLANK_OTA_DATA_FILE): partition_table_get_info
|
||||
$(GEN_EMPTY_PART) --size $(OTA_DATA_SIZE) $(BLANK_OTA_DATA_FILE)
|
||||
$(eval BLANK_OTA_DATA_FILE = $(shell if [ $(OTA_DATA_SIZE) != 0 ]; then echo $(BLANK_OTA_DATA_FILE); else echo " "; fi) )
|
||||
|
||||
blank_ota_data: $(BLANK_OTA_DATA_FILE)
|
||||
|
||||
erase_ota: partition_table_get_info | check_python_dependencies
|
||||
@echo $(if $(OTA_DATA_OFFSET), "Erase ota_data [addr=$(OTA_DATA_OFFSET) size=$(OTA_DATA_SIZE)] ...", $(error "ERROR: Partition table does not have ota_data partition."))
|
||||
$(ESPTOOLPY_SERIAL) erase_region $(OTA_DATA_OFFSET) $(OTA_DATA_SIZE)
|
||||
|
||||
all: blank_ota_data
|
||||
flash: blank_ota_data
|
||||
|
||||
clean:
|
||||
rm -f $(BLANK_OTA_DATA_FILE)
|
||||
0
components/app_update/component.mk
Normal file → Executable file
0
components/app_update/component.mk
Normal file → Executable file
@@ -1,88 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# gen_otadata prints info about the otadata partition.
|
||||
#
|
||||
# Copyright 2018 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.
|
||||
from __future__ import print_function, division
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import struct
|
||||
import sys
|
||||
import hashlib
|
||||
import binascii
|
||||
|
||||
__version__ = '1.0'
|
||||
|
||||
quiet = False
|
||||
|
||||
def status(msg):
|
||||
""" Print status message to stderr """
|
||||
if not quiet:
|
||||
critical(msg)
|
||||
|
||||
def critical(msg):
|
||||
""" Print critical message to stderr """
|
||||
if not quiet:
|
||||
sys.stderr.write(msg)
|
||||
sys.stderr.write('\n')
|
||||
|
||||
def little_endian(buff, offset):
|
||||
data = buff[offset:offset+4]
|
||||
data.reverse()
|
||||
data = ''.join(data)
|
||||
return data
|
||||
|
||||
def main():
|
||||
global quiet
|
||||
parser = argparse.ArgumentParser(description='Prints otadata partition in human readable form.')
|
||||
|
||||
parser.add_argument('--quiet', '-q', help="Don't print status messages to stderr", action='store_true')
|
||||
|
||||
search_type = parser.add_mutually_exclusive_group()
|
||||
|
||||
parser.add_argument('input', help='Path to binary file containing otadata partition to parse.',
|
||||
type=argparse.FileType('rb'))
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
quiet = args.quiet
|
||||
|
||||
input = args.input.read()
|
||||
|
||||
hex_input_0 = binascii.hexlify(input)
|
||||
hex_input_0 = map(''.join, zip(*[iter(hex_input_0)]*2))
|
||||
hex_input_1 = binascii.hexlify(input[4096:])
|
||||
hex_input_1 = map(''.join, zip(*[iter(hex_input_1)]*2))
|
||||
|
||||
print("\t%11s\t%8s |\t%8s\t%8s" %("OTA_SEQ", "CRC", "OTA_SEQ", "CRC"))
|
||||
print("Firmware: 0x%s \t 0x%s |\t0x%s \t 0x%s" % (little_endian(hex_input_0, 0), little_endian(hex_input_0, 28), \
|
||||
little_endian(hex_input_1, 0), little_endian(hex_input_1, 28)))
|
||||
class InputError(RuntimeError):
|
||||
def __init__(self, e):
|
||||
super(InputError, self).__init__(e)
|
||||
|
||||
class ValidationError(InputError):
|
||||
def __init__(self, partition, message):
|
||||
super(ValidationError, self).__init__(
|
||||
"Partition %s invalid: %s" % (partition.name, message))
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
r = main()
|
||||
sys.exit(r)
|
||||
except InputError as e:
|
||||
print(e, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "esp_ota_ops.h"
|
||||
@@ -145,7 +144,8 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
|
||||
if (it->handle == handle) {
|
||||
// must erase the partition before writing to it
|
||||
assert(it->erased_size > 0 && "must erase the partition before writing to it");
|
||||
if (it->wrote_size == 0 && it->partial_bytes == 0 && size > 0 && data_bytes[0] != ESP_IMAGE_HEADER_MAGIC) {
|
||||
|
||||
if(it->wrote_size == 0 && size > 0 && data_bytes[0] != 0xE9) {
|
||||
ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x", data_bytes[0]);
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
@@ -191,7 +191,7 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
|
||||
}
|
||||
|
||||
//if go to here ,means don't find the handle
|
||||
ESP_LOGE(TAG,"not found the handle");
|
||||
ESP_LOGE(TAG,"not found the handle")
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@@ -235,11 +235,19 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle)
|
||||
.size = it->part->size,
|
||||
};
|
||||
|
||||
if (esp_image_verify(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) {
|
||||
if (esp_image_load(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) {
|
||||
ret = ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
ret = esp_secure_boot_verify_signature(it->part->address, data.image_len);
|
||||
if (ret != ESP_OK) {
|
||||
ret = ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
LIST_REMOVE(it, entries);
|
||||
free(it);
|
||||
@@ -291,7 +299,7 @@ static esp_err_t esp_rewrite_ota_data(esp_partition_subtype_t subtype)
|
||||
uint16_t ota_app_count = 0;
|
||||
uint32_t i = 0;
|
||||
uint32_t seq;
|
||||
spi_flash_mmap_handle_t ota_data_map;
|
||||
static spi_flash_mmap_memory_t ota_data_map;
|
||||
const void *result = NULL;
|
||||
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
@@ -372,11 +380,11 @@ esp_err_t esp_ota_set_boot_partition(const esp_partition_t *partition)
|
||||
.offset = partition->address,
|
||||
.size = partition->size,
|
||||
};
|
||||
if (esp_image_verify(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) {
|
||||
if (esp_image_load(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURE_SIGNED_ON_UPDATE
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
esp_err_t ret = esp_secure_boot_verify_signature(partition->address, data.image_len);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
@@ -437,7 +445,7 @@ const esp_partition_t *esp_ota_get_boot_partition(void)
|
||||
{
|
||||
esp_err_t ret;
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
spi_flash_mmap_handle_t ota_data_map;
|
||||
static spi_flash_mmap_memory_t ota_data_map;
|
||||
const void *result = NULL;
|
||||
uint16_t ota_app_count = 0;
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
@@ -493,18 +501,9 @@ const esp_partition_t *esp_ota_get_boot_partition(void)
|
||||
|
||||
const esp_partition_t* esp_ota_get_running_partition(void)
|
||||
{
|
||||
static const esp_partition_t *curr_partition = NULL;
|
||||
|
||||
/*
|
||||
* Currently running partition is unlikely to change across reset cycle,
|
||||
* so it can be cached here, and avoid lookup on every flash write operation.
|
||||
*/
|
||||
if (curr_partition != NULL) {
|
||||
return curr_partition;
|
||||
}
|
||||
|
||||
/* Find the flash address of this exact function. By definition that is part
|
||||
of the currently running firmware. Then find the enclosing partition. */
|
||||
|
||||
size_t phys_offs = spi_flash_cache2phys(esp_ota_get_running_partition);
|
||||
|
||||
assert (phys_offs != SPI_FLASH_CACHE2PHYS_FAIL); /* indicates cache2phys lookup is buggy */
|
||||
@@ -518,7 +517,6 @@ const esp_partition_t* esp_ota_get_running_partition(void)
|
||||
const esp_partition_t *p = esp_partition_get(it);
|
||||
if (p->address <= phys_offs && p->address + p->size > phys_offs) {
|
||||
esp_partition_iterator_release(it);
|
||||
curr_partition = p;
|
||||
return p;
|
||||
}
|
||||
it = esp_partition_next(it);
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# generates an empty binary file
|
||||
#
|
||||
# This tool generates an empty binary file of the required size.
|
||||
#
|
||||
# Copyright 2018 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.
|
||||
from __future__ import print_function, division
|
||||
from __future__ import unicode_literals
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import struct
|
||||
import sys
|
||||
import hashlib
|
||||
import binascii
|
||||
|
||||
__version__ = '1.0'
|
||||
|
||||
quiet = False
|
||||
|
||||
def status(msg):
|
||||
""" Print status message to stderr """
|
||||
if not quiet:
|
||||
critical(msg)
|
||||
|
||||
def critical(msg):
|
||||
""" Print critical message to stderr """
|
||||
if not quiet:
|
||||
sys.stderr.write(msg)
|
||||
sys.stderr.write('\n')
|
||||
|
||||
def generate_blanked_file(size, output_path):
|
||||
output = b"\xFF" * size
|
||||
try:
|
||||
stdout_binary = sys.stdout.buffer # Python 3
|
||||
except AttributeError:
|
||||
stdout_binary = sys.stdout
|
||||
with stdout_binary if output_path == '-' else open(output_path, 'wb') as f:
|
||||
f.write(output)
|
||||
|
||||
def main():
|
||||
global quiet
|
||||
parser = argparse.ArgumentParser(description='Generates an empty binary file of the required size.')
|
||||
|
||||
parser.add_argument('--quiet', '-q', help="Don't print status messages to stderr", action='store_true')
|
||||
|
||||
parser.add_argument('--size', help='Size of generated the file', type=str, required=True)
|
||||
|
||||
parser.add_argument('output', help='Path for binary file.', nargs='?', default='-')
|
||||
args = parser.parse_args()
|
||||
|
||||
quiet = args.quiet
|
||||
|
||||
size = int(args.size, 0)
|
||||
if size > 0 :
|
||||
generate_blanked_file(size, args.output)
|
||||
return 0
|
||||
|
||||
class InputError(RuntimeError):
|
||||
def __init__(self, e):
|
||||
super(InputError, self).__init__(e)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
r = main()
|
||||
sys.exit(r)
|
||||
except InputError as e:
|
||||
print(e, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
3
components/app_update/include/esp_ota_ops.h
Normal file → Executable file
3
components/app_update/include/esp_ota_ops.h
Normal file → Executable file
@@ -20,6 +20,7 @@
|
||||
#include <stddef.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_spi_flash.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
@@ -132,7 +133,7 @@ esp_err_t esp_ota_set_boot_partition(const esp_partition_t* partition);
|
||||
* If the OTA data partition is not present or not valid then the result is the first app partition found in the
|
||||
* partition table. In priority order, this means: the factory app, the first OTA app slot, or the test app partition.
|
||||
*
|
||||
* Note that there is no guarantee the returned partition is a valid app. Use esp_image_verify(ESP_IMAGE_VERIFY, ...) to verify if the
|
||||
* Note that there is no guarantee the returned partition is a valid app. Use esp_image_load(ESP_IMAGE_VERIFY, ...) to verify if the
|
||||
* returned partition contains a bootable image.
|
||||
*
|
||||
* @return Pointer to info for partition structure, or NULL if partition table is invalid or a flash read operation failed. Any returned pointer is valid for the lifetime of the application.
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
# Set empty otadata partition file for flashing, if OTA data partition in
|
||||
# partition table
|
||||
# (NB: because of component dependency, we know partition_table
|
||||
# project_include.cmake has already been included.)
|
||||
if(${OTADATA_PARTITION_OFFSET})
|
||||
set(BLANK_OTADATA_FILE "ota_data_initial.bin")
|
||||
endif()
|
||||
@@ -1,6 +0,0 @@
|
||||
set(COMPONENT_SRCDIRS ".")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
|
||||
set(COMPONENT_REQUIRES unity app_update bootloader_support nvs_flash)
|
||||
|
||||
register_component()
|
||||
@@ -1,478 +0,0 @@
|
||||
/*
|
||||
* Tests for switching between partitions: factory, OTAx, test.
|
||||
*/
|
||||
|
||||
#include <esp_types.h>
|
||||
#include <stdio.h>
|
||||
#include "string.h"
|
||||
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/rtc.h"
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "unity.h"
|
||||
|
||||
#include "bootloader_common.h"
|
||||
#include "../include_bootloader/bootloader_flash.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
RTC_DATA_ATTR static int boot_count = 0;
|
||||
static const char *TAG = "ota_test";
|
||||
|
||||
/* @brief Copies a current app to next partition using handle.
|
||||
*
|
||||
* @param[in] update_handle - Handle of API ota.
|
||||
* @param[in] cur_app - Current app.
|
||||
*/
|
||||
static void copy_app_partition(esp_ota_handle_t update_handle, const esp_partition_t *curr_app)
|
||||
{
|
||||
const void *partition_bin = NULL;
|
||||
spi_flash_mmap_handle_t data_map;
|
||||
TEST_ESP_OK(esp_partition_mmap(curr_app, 0, curr_app->size, SPI_FLASH_MMAP_DATA, &partition_bin, &data_map));
|
||||
TEST_ESP_OK(esp_ota_write(update_handle, (const void *)partition_bin, curr_app->size));
|
||||
spi_flash_munmap(data_map);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BOOTLOADER_FACTORY_RESET) || defined(CONFIG_BOOTLOADER_APP_TEST)
|
||||
/* @brief Copies partition from source partition to destination partition.
|
||||
*
|
||||
* Partitions can be of any types and subtypes.
|
||||
* @param[in] dst_partition - Destination partition
|
||||
* @param[in] src_partition - Source partition
|
||||
*/
|
||||
static void copy_partition(const esp_partition_t *dst_partition, const esp_partition_t *src_partition)
|
||||
{
|
||||
const void *partition_bin = NULL;
|
||||
spi_flash_mmap_handle_t data_map;
|
||||
TEST_ESP_OK(esp_partition_mmap(src_partition, 0, src_partition->size, SPI_FLASH_MMAP_DATA, &partition_bin, &data_map));
|
||||
TEST_ESP_OK(esp_partition_erase_range(dst_partition, 0, dst_partition->size));
|
||||
TEST_ESP_OK(esp_partition_write(dst_partition, 0, (const void *)partition_bin, dst_partition->size));
|
||||
spi_flash_munmap(data_map);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* @brief Get the next partition of OTA for the update.
|
||||
*
|
||||
* @return The next partition of OTA(OTA0-15).
|
||||
*/
|
||||
static const esp_partition_t * get_next_update_partition(void)
|
||||
{
|
||||
const esp_partition_t *update_partition = esp_ota_get_next_update_partition(NULL);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, update_partition);
|
||||
ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", update_partition->subtype, update_partition->address);
|
||||
return update_partition;
|
||||
}
|
||||
|
||||
/* @brief Copies a current app to next partition (OTA0-15) and then configure OTA data for a new boot partition.
|
||||
*
|
||||
* @param[in] cur_app_partition - Current app.
|
||||
* @param[in] next_app_partition - Next app for boot.
|
||||
*/
|
||||
static void copy_current_app_to_next_part(const esp_partition_t *cur_app_partition, const esp_partition_t *next_app_partition)
|
||||
{
|
||||
esp_ota_get_next_update_partition(NULL);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, next_app_partition);
|
||||
ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", next_app_partition->subtype, next_app_partition->address);
|
||||
|
||||
esp_ota_handle_t update_handle = 0;
|
||||
TEST_ESP_OK(esp_ota_begin(next_app_partition, OTA_SIZE_UNKNOWN, &update_handle));
|
||||
|
||||
copy_app_partition(update_handle, cur_app_partition);
|
||||
|
||||
TEST_ESP_OK(esp_ota_end(update_handle));
|
||||
TEST_ESP_OK(esp_ota_set_boot_partition(next_app_partition));
|
||||
}
|
||||
|
||||
/* @brief Erase otadata partition
|
||||
*/
|
||||
static void erase_ota_data(void)
|
||||
{
|
||||
const esp_partition_t *data_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, data_partition);
|
||||
TEST_ESP_OK(esp_partition_erase_range(data_partition, 0, 2 * SPI_FLASH_SEC_SIZE));
|
||||
}
|
||||
|
||||
/* @brief Reboots ESP using mode deep sleep. This mode guaranty that RTC_DATA_ATTR variables is not reset.
|
||||
*/
|
||||
static void reboot_as_deep_sleep(void)
|
||||
{
|
||||
esp_sleep_enable_timer_wakeup(2000);
|
||||
esp_deep_sleep_start();
|
||||
}
|
||||
|
||||
/* @brief Copies a current app to next partition (OTA0-15), after that ESP is rebooting and run this (the next) OTAx.
|
||||
*/
|
||||
static void copy_current_app_to_next_part_and_reboot()
|
||||
{
|
||||
const esp_partition_t *cur_app = esp_ota_get_running_partition();
|
||||
copy_current_app_to_next_part(cur_app, get_next_update_partition());
|
||||
reboot_as_deep_sleep();
|
||||
}
|
||||
|
||||
/* @brief Get running app.
|
||||
*
|
||||
* @return The next partition of OTA(OTA0-15).
|
||||
*/
|
||||
static const esp_partition_t* get_running_firmware(void)
|
||||
{
|
||||
const esp_partition_t *configured = esp_ota_get_boot_partition();
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)",
|
||||
running->type, running->subtype, running->address);
|
||||
ESP_LOGI(TAG, "Configured partition type %d subtype %d (offset 0x%08x)",
|
||||
configured->type, configured->subtype, configured->address);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, configured);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, running);
|
||||
if (running->subtype != ESP_PARTITION_SUBTYPE_APP_TEST) {
|
||||
TEST_ASSERT_EQUAL_PTR(running, configured);
|
||||
}
|
||||
return running;
|
||||
}
|
||||
|
||||
// type of a corrupt ota_data
|
||||
typedef enum {
|
||||
CORR_CRC_1_SECTOR_OTA_DATA = (1 << 0), /*!< Corrupt CRC only 1 sector of ota_data */
|
||||
CORR_CRC_2_SECTOR_OTA_DATA = (1 << 1), /*!< Corrupt CRC only 2 sector of ota_data */
|
||||
} corrupt_ota_data_t;
|
||||
|
||||
/* @brief Get two copies ota_data from otadata partition.
|
||||
*
|
||||
* @param[in] otadata_partition - otadata partition.
|
||||
* @param[out] ota_data_0 - First copy from otadata_partition.
|
||||
* @param[out] ota_data_1 - Second copy from otadata_partition.
|
||||
*/
|
||||
static void get_ota_data(const esp_partition_t *otadata_partition, esp_ota_select_entry_t *ota_data_0, esp_ota_select_entry_t *ota_data_1)
|
||||
{
|
||||
uint32_t offset = otadata_partition->address;
|
||||
uint32_t size = otadata_partition->size;
|
||||
if (offset != 0) {
|
||||
const esp_ota_select_entry_t *ota_select_map;
|
||||
ota_select_map = bootloader_mmap(offset, size);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, ota_select_map);
|
||||
|
||||
memcpy(ota_data_0, ota_select_map, sizeof(esp_ota_select_entry_t));
|
||||
memcpy(ota_data_1, (uint8_t *)ota_select_map + SPI_FLASH_SEC_SIZE, sizeof(esp_ota_select_entry_t));
|
||||
bootloader_munmap(ota_select_map);
|
||||
}
|
||||
}
|
||||
|
||||
/* @brief Writes a ota_data into required sector of otadata_partition.
|
||||
*
|
||||
* @param[in] otadata_partition - Partition information otadata.
|
||||
* @param[in] ota_data - otadata structure.
|
||||
* @param[in] sec_id - Sector number 0 or 1.
|
||||
*/
|
||||
static void write_ota_data(const esp_partition_t *otadata_partition, esp_ota_select_entry_t *ota_data, int sec_id)
|
||||
{
|
||||
esp_partition_write(otadata_partition, SPI_FLASH_SEC_SIZE * sec_id, &ota_data[sec_id], sizeof(esp_ota_select_entry_t));
|
||||
}
|
||||
|
||||
/* @brief Makes a corrupt of ota_data.
|
||||
* @param[in] err - type error
|
||||
*/
|
||||
static void corrupt_ota_data(corrupt_ota_data_t err)
|
||||
{
|
||||
esp_ota_select_entry_t ota_data[2];
|
||||
|
||||
const esp_partition_t *otadata_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, otadata_partition);
|
||||
get_ota_data(otadata_partition, &ota_data[0], &ota_data[1]);
|
||||
|
||||
if (err & CORR_CRC_1_SECTOR_OTA_DATA) {
|
||||
ota_data[0].crc = 0;
|
||||
}
|
||||
if (err & CORR_CRC_2_SECTOR_OTA_DATA) {
|
||||
ota_data[1].crc = 0;
|
||||
}
|
||||
TEST_ESP_OK(esp_partition_erase_range(otadata_partition, 0, otadata_partition->size));
|
||||
write_ota_data(otadata_partition, &ota_data[0], 0);
|
||||
write_ota_data(otadata_partition, &ota_data[1], 1);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BOOTLOADER_FACTORY_RESET) || defined(CONFIG_BOOTLOADER_APP_TEST)
|
||||
/* @brief Sets the pin number to output and sets output level as low. After reboot (deep sleep) this pin keep the same level.
|
||||
*
|
||||
* The output level of the pad will be force locked and can not be changed.
|
||||
* Power down or call gpio_hold_dis will disable this function.
|
||||
*
|
||||
* @param[in] num_pin - Pin number
|
||||
*/
|
||||
static void set_output_pin(uint32_t num_pin)
|
||||
{
|
||||
TEST_ESP_OK(gpio_hold_dis(num_pin));
|
||||
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
|
||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||
io_conf.pin_bit_mask = (1ULL << num_pin);
|
||||
io_conf.pull_down_en = 0;
|
||||
io_conf.pull_up_en = 0;
|
||||
TEST_ESP_OK(gpio_config(&io_conf));
|
||||
|
||||
TEST_ESP_OK(gpio_set_level(num_pin, 0));
|
||||
TEST_ESP_OK(gpio_hold_en(num_pin));
|
||||
}
|
||||
|
||||
/* @brief Unset the pin number hold function.
|
||||
*/
|
||||
static void reset_output_pin(uint32_t num_pin)
|
||||
{
|
||||
TEST_ESP_OK(gpio_hold_dis(num_pin));
|
||||
TEST_ESP_OK(gpio_reset_pin(num_pin));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* @brief Checks and prepares the partition so that the factory app is launched after that.
|
||||
*/
|
||||
static void start_test(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "boot count 1 - reset");
|
||||
boot_count = 1;
|
||||
erase_ota_data();
|
||||
reboot_as_deep_sleep();
|
||||
}
|
||||
|
||||
static void test_flow1(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
copy_current_app_to_next_part_and_reboot(cur_app);
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
copy_current_app_to_next_part_and_reboot(cur_app);
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "OTA1");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
|
||||
copy_current_app_to_next_part_and_reboot(cur_app);
|
||||
break;
|
||||
case 5:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
erase_ota_data();
|
||||
break;
|
||||
default:
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> copy OTA0 to OTA1 -> reboot --//--
|
||||
// 4 Stage: run OTA1 -> check it -> copy OTA1 to OTA0 -> reboot --//--
|
||||
// 5 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, OTA0", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow1, test_flow1, test_flow1, test_flow1);
|
||||
|
||||
static void test_flow2(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
copy_current_app_to_next_part_and_reboot(cur_app);
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
copy_current_app_to_next_part(cur_app, get_next_update_partition());
|
||||
corrupt_ota_data(CORR_CRC_1_SECTOR_OTA_DATA);
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
erase_ota_data();
|
||||
break;
|
||||
default:
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> corrupt ota data -> reboot --//--
|
||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, corrupt ota_sec1, factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow2, test_flow2, test_flow2);
|
||||
|
||||
static void test_flow3(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
copy_current_app_to_next_part_and_reboot(cur_app);
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
copy_current_app_to_next_part_and_reboot(cur_app);
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "OTA1");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
|
||||
copy_current_app_to_next_part(cur_app, get_next_update_partition());
|
||||
corrupt_ota_data(CORR_CRC_2_SECTOR_OTA_DATA);
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 5:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
erase_ota_data();
|
||||
break;
|
||||
default:
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> copy OTA0 to OTA1 -> reboot --//--
|
||||
// 3 Stage: run OTA1 -> check it -> corrupt ota sector2 -> reboot --//--
|
||||
// 4 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, currupt ota_sec2, OTA0", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow3, test_flow3, test_flow3, test_flow3);
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_FACTORY_RESET
|
||||
#define STORAGE_NAMESPACE "update_ota"
|
||||
|
||||
static void test_flow4(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
nvs_handle handle = 0;
|
||||
int boot_count_nvs = 0;
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
|
||||
TEST_ESP_OK(nvs_flash_erase());
|
||||
TEST_ESP_OK(nvs_flash_init());
|
||||
TEST_ESP_OK(nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &handle));
|
||||
TEST_ESP_OK(nvs_set_i32(handle, "boot_count", boot_count));
|
||||
TEST_ESP_OK(nvs_commit(handle));
|
||||
nvs_close(handle);
|
||||
nvs_flash_deinit();
|
||||
|
||||
copy_current_app_to_next_part_and_reboot(cur_app);
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
|
||||
TEST_ESP_OK(nvs_flash_init());
|
||||
TEST_ESP_OK(nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &handle));
|
||||
TEST_ESP_OK(nvs_get_i32(handle, "boot_count", &boot_count_nvs));
|
||||
TEST_ASSERT_EQUAL(boot_count_nvs + 1, boot_count);
|
||||
nvs_close(handle);
|
||||
nvs_flash_deinit();
|
||||
|
||||
set_output_pin(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET);
|
||||
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 4:
|
||||
reset_output_pin(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET);
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
|
||||
int boot_count_nvs;
|
||||
TEST_ESP_OK(nvs_flash_init());
|
||||
TEST_ESP_OK(nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &handle));
|
||||
TEST_ESP_ERR(ESP_ERR_NVS_NOT_FOUND, nvs_get_i32(handle, "boot_count", &boot_count_nvs));
|
||||
nvs_close(handle);
|
||||
nvs_flash_deinit();
|
||||
|
||||
erase_ota_data();
|
||||
break;
|
||||
default:
|
||||
reset_output_pin(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET);
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> set_pin_factory_reset -> reboot --//--
|
||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, sets pin_factory_reset, factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow4, test_flow4, test_flow4);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_TEST
|
||||
static void test_flow5(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
|
||||
set_output_pin(CONFIG_BOOTLOADER_NUM_PIN_APP_TEST);
|
||||
|
||||
copy_partition(esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEST, NULL), cur_app);
|
||||
esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 3:
|
||||
reset_output_pin(CONFIG_BOOTLOADER_NUM_PIN_APP_TEST);
|
||||
ESP_LOGI(TAG, "Test");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_TEST, cur_app->subtype);
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
erase_ota_data();
|
||||
break;
|
||||
default:
|
||||
reset_output_pin(CONFIG_BOOTLOADER_NUM_PIN_APP_TEST);
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to Test and set pin_test_app -> reboot --//--
|
||||
// 3 Stage: run test -> check it -> reset pin_test_app -> reboot --//--
|
||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, test, factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow5, test_flow5, test_flow5);
|
||||
#endif
|
||||
@@ -1,6 +0,0 @@
|
||||
set(COMPONENT_ADD_INCLUDEDIRS asio/asio/include port/include)
|
||||
set(COMPONENT_SRCS "asio/asio/src/asio.cpp")
|
||||
|
||||
set(COMPONENT_REQUIRES lwip)
|
||||
|
||||
register_component()
|
||||
Submodule components/asio/asio deleted from 55efc179b7
@@ -1,6 +0,0 @@
|
||||
COMPONENT_ADD_INCLUDEDIRS := asio/asio/include port/include
|
||||
COMPONENT_PRIV_INCLUDEDIRS := private_include
|
||||
COMPONENT_SRCDIRS := asio/asio/src
|
||||
COMPONENT_OBJEXCLUDE := asio/asio/src/asio_ssl.o
|
||||
|
||||
COMPONENT_SUBMODULES += asio
|
||||
@@ -1,45 +0,0 @@
|
||||
// Copyright 2018 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_ASIO_CONFIG_H_
|
||||
#define _ESP_ASIO_CONFIG_H_
|
||||
|
||||
//
|
||||
// Enabling exceptions only when they are enabled in menuconfig
|
||||
//
|
||||
# include <sdkconfig.h>
|
||||
# ifndef CONFIG_CXX_EXCEPTIONS
|
||||
# define ASIO_NO_EXCEPTIONS
|
||||
# endif // CONFIG_CXX_EXCEPTIONS
|
||||
|
||||
//
|
||||
// LWIP compatifility inet and address macros/functions
|
||||
//
|
||||
# define LWIP_COMPAT_SOCKET_INET 1
|
||||
# define LWIP_COMPAT_SOCKET_ADDR 1
|
||||
|
||||
//
|
||||
// Specific ASIO feature flags
|
||||
//
|
||||
# define ASIO_DISABLE_SERIAL_PORT
|
||||
# define ASIO_SEPARATE_COMPILATION
|
||||
# define ASIO_STANDALONE
|
||||
# define ASIO_NO_TYPEID
|
||||
# define ASIO_DISABLE_SIGNAL
|
||||
# define ASIO_HAS_PTHREADS
|
||||
# define ASIO_DISABLE_EPOLL
|
||||
# define ASIO_DISABLE_EVENTFD
|
||||
# define ASIO_DISABLE_SIGNAL
|
||||
# define ASIO_DISABLE_SIGACTION
|
||||
|
||||
#endif // _ESP_ASIO_CONFIG_H_
|
||||
@@ -1,39 +0,0 @@
|
||||
|
||||
// Copyright 2018 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_EXCEPTION_H_
|
||||
#define _ESP_EXCEPTION_H_
|
||||
|
||||
//
|
||||
// This exception stub is enabled only if exceptions are disabled in menuconfig
|
||||
//
|
||||
#if !defined(CONFIG_CXX_EXCEPTIONS) && defined (ASIO_NO_EXCEPTIONS)
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
//
|
||||
// asio exception stub
|
||||
//
|
||||
namespace asio {
|
||||
namespace detail {
|
||||
template <typename Exception>
|
||||
void throw_exception(const Exception& e)
|
||||
{
|
||||
ESP_LOGE("esp32_asio_exception", "Caught exception: %s!", e.what());
|
||||
abort();
|
||||
}
|
||||
}}
|
||||
#endif // CONFIG_CXX_EXCEPTIONS==1 && defined (ASIO_NO_EXCEPTIONS)
|
||||
|
||||
#endif // _ESP_EXCEPTION_H_
|
||||
@@ -1,30 +0,0 @@
|
||||
if(CONFIG_AWS_IOT_SDK)
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include aws-iot-device-sdk-embedded-C/include")
|
||||
set(aws_sdk_dir aws-iot-device-sdk-embedded-C/src)
|
||||
set(COMPONENT_SRCS "${aws_sdk_dir}/aws_iot_jobs_interface.c"
|
||||
"${aws_sdk_dir}/aws_iot_jobs_json.c"
|
||||
"${aws_sdk_dir}/aws_iot_jobs_topics.c"
|
||||
"${aws_sdk_dir}/aws_iot_jobs_types.c"
|
||||
"${aws_sdk_dir}/aws_iot_json_utils.c"
|
||||
"${aws_sdk_dir}/aws_iot_mqtt_client.c"
|
||||
"${aws_sdk_dir}/aws_iot_mqtt_client_common_internal.c"
|
||||
"${aws_sdk_dir}/aws_iot_mqtt_client_connect.c"
|
||||
"${aws_sdk_dir}/aws_iot_mqtt_client_publish.c"
|
||||
"${aws_sdk_dir}/aws_iot_mqtt_client_subscribe.c"
|
||||
"${aws_sdk_dir}/aws_iot_mqtt_client_unsubscribe.c"
|
||||
"${aws_sdk_dir}/aws_iot_mqtt_client_yield.c"
|
||||
"${aws_sdk_dir}/aws_iot_shadow.c"
|
||||
"${aws_sdk_dir}/aws_iot_shadow_actions.c"
|
||||
"${aws_sdk_dir}/aws_iot_shadow_json.c"
|
||||
"${aws_sdk_dir}/aws_iot_shadow_records.c"
|
||||
"port/network_mbedtls_wrapper.c"
|
||||
"port/threads_freertos.c"
|
||||
"port/timer.c")
|
||||
else()
|
||||
message(STATUS "Building empty aws_iot component due to configuration")
|
||||
endif()
|
||||
|
||||
set(COMPONENT_REQUIRES "mbedtls")
|
||||
set(COMPONENT_PRIV_REQUIRES "jsmn")
|
||||
|
||||
register_component()
|
||||
@@ -83,77 +83,3 @@ config AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL
|
||||
Maximum delay between reconnection attempts. If the exponentially increased delay
|
||||
interval reaches this value, the client will stop automatically attempting to reconnect.
|
||||
|
||||
menu "Thing Shadow"
|
||||
depends on AWS_IOT_SDK
|
||||
|
||||
config AWS_IOT_OVERRIDE_THING_SHADOW_RX_BUFFER
|
||||
bool "Override Shadow RX buffer size"
|
||||
depends on AWS_IOT_SDK
|
||||
default n
|
||||
help
|
||||
Allows setting a different Thing Shadow RX buffer
|
||||
size. This is the maximum size of a Thing Shadow
|
||||
message in bytes, plus one.
|
||||
|
||||
If not overridden, the default value is the MQTT RX Buffer length plus one. If overriden, do not set higher than the default value.
|
||||
|
||||
config AWS_IOT_SHADOW_MAX_SIZE_OF_RX_BUFFER
|
||||
int "Maximum RX Buffer (bytes)"
|
||||
depends on AWS_IOT_OVERRIDE_THING_SHADOW_RX_BUFFER
|
||||
default 513
|
||||
range 32 65536
|
||||
help
|
||||
Allows setting a different Thing Shadow RX buffer size.
|
||||
This is the maximum size of a Thing Shadow message in bytes,
|
||||
plus one.
|
||||
|
||||
|
||||
config AWS_IOT_SHADOW_MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES
|
||||
int "Maximum unique client ID size (bytes)"
|
||||
depends on AWS_IOT_SDK
|
||||
default 80
|
||||
range 4 1000
|
||||
help
|
||||
Maximum size of the Unique Client Id.
|
||||
|
||||
config AWS_IOT_SHADOW_MAX_SIMULTANEOUS_ACKS
|
||||
int "Maximum simultaneous responses"
|
||||
depends on AWS_IOT_SDK
|
||||
default 10
|
||||
range 1 100
|
||||
help
|
||||
At any given time we will wait for this many responses. This will correlate to the rate at which the shadow actions are requested
|
||||
|
||||
config AWS_IOT_SHADOW_MAX_SIMULTANEOUS_THINGNAMES
|
||||
int "Maximum simultaneous Thing Name operations"
|
||||
depends on AWS_IOT_SDK
|
||||
default 10
|
||||
range 1 100
|
||||
help
|
||||
We could perform shadow action on any thing Name and this is maximum Thing Names we can act on at any given time
|
||||
|
||||
config AWS_IOT_SHADOW_MAX_JSON_TOKEN_EXPECTED
|
||||
int "Maximum expected JSON tokens"
|
||||
depends on AWS_IOT_SDK
|
||||
default 120
|
||||
help
|
||||
These are the max tokens that is expected to be in the Shadow JSON document. Includes the metadata which is published
|
||||
|
||||
config AWS_IOT_SHADOW_MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME
|
||||
int "Maximum topic length (not including Thing Name)"
|
||||
depends on AWS_IOT_SDK
|
||||
default 60
|
||||
range 10 1000
|
||||
help
|
||||
All shadow actions have to be published or subscribed to a topic which is of the format $aws/things/{thingName}/shadow/update/accepted. This refers to the size of the topic without the Thing Name
|
||||
|
||||
config AWS_IOT_SHADOW_MAX_SIZE_OF_THING_NAME
|
||||
int "Maximum Thing Name length"
|
||||
depends on AWS_IOT_SDK
|
||||
default 20
|
||||
range 4 1000
|
||||
help
|
||||
Maximum length of a Thing Name.
|
||||
|
||||
endmenu # Thing Shadow
|
||||
|
||||
|
||||
Submodule components/aws_iot/aws-iot-device-sdk-embedded-C updated: 299183238f...7132505b00
@@ -42,20 +42,15 @@
|
||||
#define AWS_IOT_MQTT_NUM_SUBSCRIBE_HANDLERS CONFIG_AWS_IOT_MQTT_NUM_SUBSCRIBE_HANDLERS ///< Maximum number of topic filters the MQTT client can handle at any given time. This should be increased appropriately when using Thing Shadow
|
||||
|
||||
// Thing Shadow specific configs
|
||||
#ifdef CONFIG_AWS_IOT_OVERRIDE_THING_SHADOW_RX_BUFFER
|
||||
#define SHADOW_MAX_SIZE_OF_RX_BUFFER CONFIG_AWS_IOT_SHADOW_MAX_SIZE_OF_RX_BUFFER ///< Maximum size of the SHADOW buffer to store the received Shadow message, including NULL terminating byte
|
||||
#else
|
||||
#define SHADOW_MAX_SIZE_OF_RX_BUFFER (AWS_IOT_MQTT_RX_BUF_LEN + 1)
|
||||
#endif
|
||||
|
||||
#define SHADOW_MAX_SIZE_OF_RX_BUFFER (AWS_IOT_MQTT_RX_BUF_LEN + 1) ///< Maximum size of the SHADOW buffer to store the received Shadow message
|
||||
#define MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES 80 ///< Maximum size of the Unique Client Id. For More info on the Client Id refer \ref response "Acknowledgments"
|
||||
#define MAX_SIZE_CLIENT_ID_WITH_SEQUENCE (MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES + 10) ///< This is size of the extra sequence number that will be appended to the Unique client Id
|
||||
#define MAX_SIZE_CLIENT_TOKEN_CLIENT_SEQUENCE (MAX_SIZE_CLIENT_ID_WITH_SEQUENCE + 20) ///< This is size of the the total clientToken key and value pair in the JSON
|
||||
#define MAX_ACKS_TO_COMEIN_AT_ANY_GIVEN_TIME CONFIG_AWS_IOT_SHADOW_MAX_SIMULTANEOUS_ACKS ///< At Any given time we will wait for this many responses. This will correlate to the rate at which the shadow actions are requested
|
||||
#define MAX_THINGNAME_HANDLED_AT_ANY_GIVEN_TIME CONFIG_AWS_IOT_SHADOW_MAX_SIMULTANEOUS_THINGNAMES ///< We could perform shadow action on any thing Name and this is maximum Thing Names we can act on at any given time
|
||||
#define MAX_JSON_TOKEN_EXPECTED CONFIG_AWS_IOT_SHADOW_MAX_JSON_TOKEN_EXPECTED ///< These are the max tokens that is expected to be in the Shadow JSON document. Include the metadata that gets published
|
||||
#define MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME CONFIG_AWS_IOT_SHADOW_MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME ///< All shadow actions have to be published or subscribed to a topic which is of the formablogt $aws/things/{thingName}/shadow/update/accepted. This refers to the size of the topic without the Thing Name
|
||||
#define MAX_SIZE_OF_THING_NAME CONFIG_AWS_IOT_SHADOW_MAX_SIZE_OF_THING_NAME ///< The Thing Name should not be bigger than this value. Modify this if the Thing Name needs to be bigger
|
||||
#define MAX_ACKS_TO_COMEIN_AT_ANY_GIVEN_TIME 10 ///< At Any given time we will wait for this many responses. This will correlate to the rate at which the shadow actions are requested
|
||||
#define MAX_THINGNAME_HANDLED_AT_ANY_GIVEN_TIME 10 ///< We could perform shadow action on any thing Name and this is maximum Thing Names we can act on at any given time
|
||||
#define MAX_JSON_TOKEN_EXPECTED 120 ///< These are the max tokens that is expected to be in the Shadow JSON document. Include the metadata that gets published
|
||||
#define MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME 60 ///< All shadow actions have to be published or subscribed to a topic which is of the formablogt $aws/things/{thingName}/shadow/update/accepted. This refers to the size of the topic without the Thing Name
|
||||
#define MAX_SIZE_OF_THING_NAME 20 ///< The Thing Name should not be bigger than this value. Modify this if the Thing Name needs to be bigger
|
||||
#define MAX_SHADOW_TOPIC_LENGTH_BYTES (MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME + MAX_SIZE_OF_THING_NAME) ///< This size includes the length of topic with Thing Name
|
||||
|
||||
// Auto Reconnect specific config
|
||||
|
||||
@@ -236,15 +236,6 @@ IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params) {
|
||||
|
||||
mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), pNetwork->tlsConnectParams.timeout_ms);
|
||||
|
||||
/* Use the AWS IoT ALPN extension for MQTT, if port 443 is requested */
|
||||
if (pNetwork->tlsConnectParams.DestinationPort == 443) {
|
||||
const char *alpnProtocols[] = { "x-amzn-mqtt-ca", NULL };
|
||||
if ((ret = mbedtls_ssl_conf_alpn_protocols(&(tlsDataParams->conf), alpnProtocols)) != 0) {
|
||||
ESP_LOGE(TAG, "failed! mbedtls_ssl_conf_alpn_protocols returned -0x%x", -ret);
|
||||
return SSL_CONNECTION_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if((ret = mbedtls_ssl_setup(&(tlsDataParams->ssl), &(tlsDataParams->conf))) != 0) {
|
||||
ESP_LOGE(TAG, "failed! mbedtls_ssl_setup returned -0x%x", -ret);
|
||||
return SSL_CONNECTION_ERROR;
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# bootloader component logic is all in project_include.cmake,
|
||||
# and subproject/CMakeLists.txt.
|
||||
#
|
||||
# This file is only included so the build system finds the
|
||||
# component
|
||||
|
||||
|
||||
@@ -62,161 +62,14 @@ config BOOTLOADER_VDDSDIO_BOOST_1_9V
|
||||
bool "1.9V"
|
||||
endchoice
|
||||
|
||||
config BOOTLOADER_FACTORY_RESET
|
||||
bool "GPIO triggers factory reset"
|
||||
default N
|
||||
help
|
||||
Allows to reset the device to factory settings:
|
||||
- clear one or more data partitions;
|
||||
- boot from "factory" partition.
|
||||
The factory reset will occur if there is a GPIO input pulled low while device starts up.
|
||||
See settings below.
|
||||
|
||||
config BOOTLOADER_NUM_PIN_FACTORY_RESET
|
||||
int "Number of the GPIO input for factory reset"
|
||||
depends on BOOTLOADER_FACTORY_RESET
|
||||
range 0 39
|
||||
default 4
|
||||
help
|
||||
The selected GPIO will be configured as an input with internal pull-up enabled.
|
||||
To trigger a factory reset, this GPIO must be pulled low on reset.
|
||||
Note that GPIO34-39 do not have an internal pullup and an external one must be provided.
|
||||
|
||||
config BOOTLOADER_OTA_DATA_ERASE
|
||||
bool "Clear OTA data on factory reset (select factory partition)"
|
||||
depends on BOOTLOADER_FACTORY_RESET
|
||||
help
|
||||
The device will boot from "factory" partition (or OTA slot 0 if no factory partition is present) after a factory reset.
|
||||
|
||||
config BOOTLOADER_DATA_FACTORY_RESET
|
||||
string "Comma-separated names of partitions to clear on factory reset"
|
||||
depends on BOOTLOADER_FACTORY_RESET
|
||||
default "nvs"
|
||||
help
|
||||
Allows customers to select which data partitions will be erased while factory reset.
|
||||
|
||||
Specify the names of partitions as a comma-delimited with optional spaces for readability. (Like this: "nvs, phy_init, ...")
|
||||
Make sure that the name specified in the partition table and here are the same.
|
||||
Partitions of type "app" cannot be specified here.
|
||||
|
||||
config BOOTLOADER_APP_TEST
|
||||
bool "GPIO triggers boot from test app partition"
|
||||
default N
|
||||
help
|
||||
Allows to run the test app from "TEST" partition.
|
||||
A boot from "test" partition will occur if there is a GPIO input pulled low while device starts up.
|
||||
See settings below.
|
||||
|
||||
config BOOTLOADER_NUM_PIN_APP_TEST
|
||||
int "Number of the GPIO input to boot TEST partition"
|
||||
depends on BOOTLOADER_APP_TEST
|
||||
range 0 39
|
||||
default 18
|
||||
help
|
||||
The selected GPIO will be configured as an input with internal pull-up enabled.
|
||||
To trigger a test app, this GPIO must be pulled low on reset.
|
||||
After the GPIO input is deactivated and the device reboots, the old application will boot.
|
||||
(factory or OTA[x]).
|
||||
Note that GPIO34-39 do not have an internal pullup and an external one must be provided.
|
||||
|
||||
config BOOTLOADER_HOLD_TIME_GPIO
|
||||
int "Hold time of GPIO for reset/test mode (seconds)"
|
||||
depends on BOOTLOADER_FACTORY_RESET || BOOTLOADER_APP_TEST
|
||||
default 5
|
||||
help
|
||||
The GPIO must be held low continuously for this period of time after reset
|
||||
before a factory reset or test partition boot (as applicable) is performed.
|
||||
|
||||
config BOOTLOADER_WDT_ENABLE
|
||||
bool "Use RTC watchdog in start code"
|
||||
default y
|
||||
help
|
||||
Tracks the execution time of startup code.
|
||||
If the execution time is exceeded, the RTC_WDT will restart system.
|
||||
It is also useful to prevent a lock up in start code caused by an unstable power source.
|
||||
NOTE: Tracks the execution time starts from the bootloader code - re-set timeout, while selecting the source for slow_clk - and ends calling app_main.
|
||||
Re-set timeout is needed due to WDT uses a SLOW_CLK clock source. After changing a frequency slow_clk a time of WDT needs to re-set for new frequency.
|
||||
slow_clk depends on ESP32_RTC_CLOCK_SOURCE (INTERNAL_RC or EXTERNAL_CRYSTAL).
|
||||
|
||||
config BOOTLOADER_WDT_DISABLE_IN_USER_CODE
|
||||
bool "Allows RTC watchdog disable in user code"
|
||||
depends on BOOTLOADER_WDT_ENABLE
|
||||
default n
|
||||
help
|
||||
If it is set, the client must itself reset or disable rtc_wdt in their code (app_main()).
|
||||
Otherwise rtc_wdt will be disabled before calling app_main function.
|
||||
Use function rtc_wdt_feed() for resetting counter of rtc_wdt.
|
||||
Use function rtc_wdt_disable() for disabling rtc_wdt.
|
||||
|
||||
config BOOTLOADER_WDT_TIME_MS
|
||||
int "Timeout for RTC watchdog (ms)"
|
||||
depends on BOOTLOADER_WDT_ENABLE
|
||||
default 9000
|
||||
range 0 120000
|
||||
help
|
||||
Verify that this parameter is correct and more then the execution time.
|
||||
Pay attention to options such as reset to factory, trigger test partition and encryption on boot
|
||||
- these options can increase the execution time.
|
||||
Note: RTC_WDT will reset while encryption operations will be performed.
|
||||
|
||||
endmenu # Bootloader
|
||||
|
||||
|
||||
menu "Security features"
|
||||
|
||||
# These three are the actual options to check in code,
|
||||
# selected by the displayed options
|
||||
config SECURE_SIGNED_ON_BOOT
|
||||
bool
|
||||
default y
|
||||
depends on SECURE_BOOT_ENABLED || SECURE_SIGNED_ON_BOOT_NO_SECURE_BOOT
|
||||
|
||||
config SECURE_SIGNED_ON_UPDATE
|
||||
bool
|
||||
default y
|
||||
depends on SECURE_BOOT_ENABLED || SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
|
||||
config SECURE_SIGNED_APPS
|
||||
bool
|
||||
default y
|
||||
depends on SECURE_SIGNED_ON_BOOT || SECURE_SIGNED_ON_UPDATE
|
||||
|
||||
|
||||
config SECURE_SIGNED_APPS_NO_SECURE_BOOT
|
||||
bool "Require signed app images"
|
||||
default n
|
||||
depends on !SECURE_BOOT_ENABLED
|
||||
help
|
||||
Require apps to be signed to verify their integrity.
|
||||
|
||||
This option uses the same app signature scheme as hardware secure boot, but unlike hardware secure boot it does not prevent the bootloader from being physically updated. This means that the device can be secured against remote network access, but not physical access. Compared to using hardware Secure Boot this option is much simpler to implement.
|
||||
|
||||
config SECURE_SIGNED_ON_BOOT_NO_SECURE_BOOT
|
||||
bool "Bootloader verifies app signatures"
|
||||
default n
|
||||
depends on SECURE_SIGNED_APPS_NO_SECURE_BOOT
|
||||
help
|
||||
If this option is set, the bootloader will be compiled with code to verify that an app is signed before booting it.
|
||||
|
||||
If hardware secure boot is enabled, this option is always enabled and cannot be disabled.
|
||||
If hardware secure boot is not enabled, this option doesn't add significant security by itself so most users will want to leave it disabled.
|
||||
|
||||
config SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
bool "Verify app signature on update"
|
||||
default y
|
||||
depends on SECURE_SIGNED_APPS_NO_SECURE_BOOT
|
||||
help
|
||||
If this option is set, any OTA updated apps will have the signature verified before being considered valid.
|
||||
|
||||
When enabled, the signature is automatically checked whenever the esp_ota_ops.h APIs are used for OTA updates,
|
||||
or esp_image_format.h APIs are used to verify apps.
|
||||
|
||||
If hardware secure boot is enabled, this option is always enabled and cannot be disabled.
|
||||
If hardware secure boot is not enabled, this option still adds significant security against network-based attackers by preventing spoofing of OTA updates.
|
||||
|
||||
config SECURE_BOOT_ENABLED
|
||||
bool "Enable hardware secure boot in bootloader (READ DOCS FIRST)"
|
||||
default n
|
||||
bool "Enable secure boot in bootloader (READ DOCS FIRST)"
|
||||
default N
|
||||
help
|
||||
Build a bootloader which enables secure boot on first boot.
|
||||
|
||||
@@ -224,7 +77,7 @@ config SECURE_BOOT_ENABLED
|
||||
|
||||
When enabling secure boot, JTAG and ROM BASIC Interpreter are permanently disabled by default.
|
||||
|
||||
Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
|
||||
Refer to https://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling.
|
||||
|
||||
choice SECURE_BOOTLOADER_MODE
|
||||
bool "Secure bootloader mode"
|
||||
@@ -251,12 +104,12 @@ endchoice
|
||||
|
||||
config SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
bool "Sign binaries during build"
|
||||
depends on SECURE_SIGNED_APPS
|
||||
depends on SECURE_BOOT_ENABLED
|
||||
default y
|
||||
help
|
||||
Once secure boot or signed app requirement is enabled, app images are required to be signed.
|
||||
Once secure boot is enabled, bootloader will only boot if partition table and app image are signed.
|
||||
|
||||
If enabled (default), these binary files are signed as part of the build process. The file named in "Secure boot private signing key" will be used to sign the image.
|
||||
If enabled, these binary files are signed as part of the build process. The file named in "Secure boot private signing key" will be used to sign the image.
|
||||
|
||||
If disabled, unsigned app/partition data will be built. They must be signed manually using espsecure.py (for example, on a remote signing server.)
|
||||
|
||||
@@ -265,7 +118,7 @@ config SECURE_BOOT_SIGNING_KEY
|
||||
depends on SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
default secure_boot_signing_key.pem
|
||||
help
|
||||
Path to the key file used to sign app images.
|
||||
Path to the key file used to sign partition tables and app images for secure boot. Once secure boot is enabled, bootloader will only boot if partition table and app image are signed.
|
||||
|
||||
Key file is an ECDSA private key (NIST256p curve) in PEM format.
|
||||
|
||||
@@ -278,38 +131,17 @@ config SECURE_BOOT_SIGNING_KEY
|
||||
|
||||
config SECURE_BOOT_VERIFICATION_KEY
|
||||
string "Secure boot public signature verification key"
|
||||
depends on SECURE_SIGNED_APPS && !SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
depends on SECURE_BOOT_ENABLED && !SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
default signature_verification_key.bin
|
||||
help
|
||||
Path to a public key file used to verify signed images. This key is compiled into the bootloader and/or app,
|
||||
to verify app images.
|
||||
Path to a public key file used to verify signed images. This key is compiled into the bootloader,
|
||||
and may also be used to verify signatures on OTA images after download.
|
||||
|
||||
Key file is in raw binary format, and can be extracted from a
|
||||
PEM formatted private key using the espsecure.py
|
||||
extract_public_key command.
|
||||
|
||||
Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
|
||||
|
||||
choice SECURE_BOOTLOADER_KEY_ENCODING
|
||||
bool "Hardware Key Encoding"
|
||||
depends on SECURE_BOOTLOADER_REFLASHABLE
|
||||
default SECURE_BOOTLOADER_NO_ENCODING
|
||||
help
|
||||
|
||||
In reflashable secure bootloader mode, a hardware key is derived from the signing key (with SHA-256) and can be written to efuse
|
||||
with espefuse.py.
|
||||
|
||||
Normally this is a 256-bit key, but if 3/4 Coding Scheme is used on the device then the efuse key is truncated to 192 bits.
|
||||
|
||||
This configuration item doesn't change any firmware code, it only changes the size of key binary which is generated at build time.
|
||||
|
||||
config SECURE_BOOTLOADER_KEY_ENCODING_256BIT
|
||||
bool "No encoding (256 bit key)"
|
||||
|
||||
config SECURE_BOOTLOADER_KEY_ENCODING_192BIT
|
||||
bool "3/4 encoding (192 bit key)"
|
||||
|
||||
endchoice
|
||||
Refer to https://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling.
|
||||
|
||||
config SECURE_BOOT_INSECURE
|
||||
bool "Allow potentially insecure options"
|
||||
@@ -320,7 +152,7 @@ config SECURE_BOOT_INSECURE
|
||||
|
||||
Only enable these options if you are very sure.
|
||||
|
||||
Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
|
||||
Refer to https://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling.
|
||||
|
||||
config FLASH_ENCRYPTION_ENABLED
|
||||
bool "Enable flash encryption on boot (READ DOCS FIRST)"
|
||||
@@ -331,7 +163,7 @@ config FLASH_ENCRYPTION_ENABLED
|
||||
Note: After first boot, the system will be permanently encrypted. Re-flashing an encrypted
|
||||
system is complicated and not always possible.
|
||||
|
||||
Read https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html before enabling.
|
||||
Read https://esp-idf.readthedocs.io/en/latest/security/flash-encryption.html before enabling.
|
||||
|
||||
config FLASH_ENCRYPTION_INSECURE
|
||||
bool "Allow potentially insecure options"
|
||||
@@ -378,13 +210,6 @@ config SECURE_BOOT_ALLOW_JTAG
|
||||
|
||||
Only set this option in testing environments.
|
||||
|
||||
config SECURE_BOOT_ALLOW_SHORT_APP_PARTITION
|
||||
bool "Allow app partition length not 64KB aligned"
|
||||
depends on SECURE_BOOT_INSECURE
|
||||
help
|
||||
If not set (default), app partition size must be a multiple of 64KB. App images are padded to 64KB length, and the bootloader checks any trailing bytes after the signature (before the next 64KB boundary) have not been written. This is because flash cache maps entire 64KB pages into the address space. This prevents an attacker from appending unverified data after the app image in the flash, causing it to be mapped into the address space.
|
||||
|
||||
Setting this option allows the app partition length to be unaligned, and disables padding of the app image to this length. It is generally not recommended to set this option, unless you have a legacy partitioning scheme which doesn't support 64KB aligned partition lengths.
|
||||
|
||||
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_ENCRYPT
|
||||
bool "Leave UART bootloader encryption enabled"
|
||||
|
||||
@@ -32,8 +32,7 @@ BOOTLOADER_MAKE= +\
|
||||
V=$(V) \
|
||||
BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
|
||||
TEST_COMPONENTS= \
|
||||
TESTS_ALL= \
|
||||
EXCLUDE_COMPONENTS=
|
||||
TESTS_ALL=
|
||||
|
||||
.PHONY: bootloader-clean bootloader-flash bootloader-list-components bootloader $(BOOTLOADER_BIN)
|
||||
|
||||
@@ -49,14 +48,14 @@ ifndef CONFIG_SECURE_BOOT_ENABLED
|
||||
# If secure boot disabled, bootloader flashing is integrated
|
||||
# with 'make flash' and no warnings are printed.
|
||||
|
||||
bootloader: $(BOOTLOADER_BIN) | check_python_dependencies
|
||||
bootloader: $(BOOTLOADER_BIN)
|
||||
@echo $(SEPARATOR)
|
||||
@echo "Bootloader built. Default flash command is:"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) $(BOOTLOADER_OFFSET) $^"
|
||||
|
||||
ESPTOOL_ALL_FLASH_ARGS += $(BOOTLOADER_OFFSET) $(BOOTLOADER_BIN)
|
||||
|
||||
bootloader-flash: $(BOOTLOADER_BIN) $(call prereq_if_explicit,erase_flash) | check_python_dependencies
|
||||
bootloader-flash: $(BOOTLOADER_BIN) $(call prereq_if_explicit,erase_flash)
|
||||
$(ESPTOOLPY_WRITE_FLASH) 0x1000 $^
|
||||
|
||||
else ifdef CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||
@@ -67,7 +66,7 @@ else ifdef CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||
# The flashing command is deliberately printed without an auto-reset
|
||||
# step, so the device doesn't immediately reset to flash itself.
|
||||
|
||||
bootloader: $(BOOTLOADER_BIN) | check_python_dependencies
|
||||
bootloader: $(BOOTLOADER_BIN)
|
||||
@echo $(SEPARATOR)
|
||||
@echo "Bootloader built. One-time flash command is:"
|
||||
@echo "$(subst hard_reset,no_reset,$(ESPTOOLPY_WRITE_FLASH)) $(BOOTLOADER_OFFSET) $(BOOTLOADER_BIN)"
|
||||
@@ -78,18 +77,12 @@ else ifdef CONFIG_SECURE_BOOTLOADER_REFLASHABLE
|
||||
# Reflashable secure bootloader
|
||||
# generates a digest binary (bootloader + digest)
|
||||
|
||||
ifdef CONFIG_SECURE_BOOTLOADER_KEY_ENCODING_192BIT
|
||||
KEY_DIGEST_LEN=192
|
||||
else
|
||||
KEY_DIGEST_LEN=256
|
||||
endif
|
||||
|
||||
BOOTLOADER_DIGEST_BIN := $(BOOTLOADER_BUILD_DIR)/bootloader-reflash-digest.bin
|
||||
SECURE_BOOTLOADER_KEY := $(BOOTLOADER_BUILD_DIR)/secure-bootloader-key-$(KEY_DIGEST_LEN).bin
|
||||
SECURE_BOOTLOADER_KEY := $(BOOTLOADER_BUILD_DIR)/secure-bootloader-key.bin
|
||||
|
||||
ifdef CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
$(SECURE_BOOTLOADER_KEY): $(SECURE_BOOT_SIGNING_KEY) | check_python_dependencies
|
||||
$(ESPSECUREPY) digest_private_key --keylen $(KEY_DIGEST_LEN) -k $< $@
|
||||
$(SECURE_BOOTLOADER_KEY): $(SECURE_BOOT_SIGNING_KEY)
|
||||
$(ESPSECUREPY) digest_private_key -k $< $@
|
||||
else
|
||||
$(SECURE_BOOTLOADER_KEY):
|
||||
@echo "No pre-generated key for a reflashable secure bootloader is available, due to signing configuration."
|
||||
@@ -111,9 +104,9 @@ bootloader: $(BOOTLOADER_DIGEST_BIN)
|
||||
@echo "* After first boot, only re-flashes of this kind (with same key) will be accepted."
|
||||
@echo "* Not recommended to re-use the same secure boot keyfile on multiple production devices."
|
||||
|
||||
$(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOTLOADER_KEY) | check_python_dependencies
|
||||
$(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOTLOADER_KEY)
|
||||
@echo "DIGEST $(notdir $@)"
|
||||
$(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOTLOADER_KEY) -o $@ $<
|
||||
$(Q) $(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOTLOADER_KEY) -o $@ $<
|
||||
|
||||
else # CONFIG_SECURE_BOOT_ENABLED && !CONFIG_SECURE_BOOTLOADER_REFLASHABLE && !CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||
bootloader:
|
||||
@@ -122,7 +115,7 @@ bootloader:
|
||||
endif
|
||||
|
||||
ifndef CONFIG_SECURE_BOOT_ENABLED
|
||||
# don't build bootloader by default if secure boot is enabled
|
||||
# don't build bootloader by default is secure boot is enabled
|
||||
all_binaries: $(BOOTLOADER_BIN)
|
||||
endif
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
if(BOOTLOADER_BUILD)
|
||||
return() # don't keep recursing!
|
||||
endif()
|
||||
|
||||
# Glue to build the bootloader subproject binary as an external
|
||||
# cmake project under this one
|
||||
#
|
||||
#
|
||||
set(bootloader_build_dir "${CMAKE_BINARY_DIR}/bootloader")
|
||||
set(bootloader_binary_files
|
||||
"${bootloader_build_dir}/bootloader.elf"
|
||||
"${bootloader_build_dir}/bootloader.bin"
|
||||
"${bootloader_build_dir}/bootloader.map"
|
||||
)
|
||||
|
||||
externalproject_add(bootloader
|
||||
# TODO: support overriding the bootloader in COMPONENT_PATHS
|
||||
SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/subproject"
|
||||
BINARY_DIR "${bootloader_build_dir}"
|
||||
CMAKE_ARGS -DSDKCONFIG=${SDKCONFIG} -DIDF_PATH=${IDF_PATH}
|
||||
-DEXTRA_COMPONENT_DIRS=${CMAKE_CURRENT_LIST_DIR}
|
||||
INSTALL_COMMAND ""
|
||||
BUILD_ALWAYS 1 # no easy way around this...
|
||||
BUILD_BYPRODUCTS ${bootloader_binary_files}
|
||||
)
|
||||
|
||||
# this is a hack due to an (annoying) shortcoming in cmake, it can't
|
||||
# extend the 'clean' target to the external project
|
||||
# see thread: https://cmake.org/pipermail/cmake/2016-December/064660.html
|
||||
#
|
||||
# So for now we just have the top-level build remove the final build products...
|
||||
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
|
||||
ADDITIONAL_MAKE_CLEAN_FILES
|
||||
${bootloader_binary_files})
|
||||
@@ -1,28 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
if(NOT SDKCONFIG)
|
||||
message(FATAL_ERROR "Bootloader subproject expects the SDKCONFIG variable to be passed "
|
||||
"in by the parent build process.")
|
||||
endif()
|
||||
|
||||
if(NOT IDF_PATH)
|
||||
message(FATAL_ERROR "Bootloader subproject expects the IDF_PATH variable to be passed "
|
||||
"in by the parent build process.")
|
||||
endif()
|
||||
|
||||
set(COMPONENTS bootloader esptool_py esp32 partition_table soc bootloader_support log spi_flash micro-ecc soc main)
|
||||
set(BOOTLOADER_BUILD 1)
|
||||
add_definitions(-DBOOTLOADER_BUILD=1)
|
||||
|
||||
set(COMPONENT_REQUIRES_COMMON log esp32 soc)
|
||||
|
||||
include("${IDF_PATH}/tools/cmake/project.cmake")
|
||||
project(bootloader)
|
||||
|
||||
target_linker_script(bootloader.elf
|
||||
"main/esp32.bootloader.ld"
|
||||
"main/esp32.bootloader.rom.ld")
|
||||
# Imported from esp32 component
|
||||
target_linker_script(bootloader.elf ${ESP32_BOOTLOADER_LINKER_SCRIPTS})
|
||||
|
||||
target_link_libraries(bootloader.elf gcc)
|
||||
@@ -1,4 +0,0 @@
|
||||
set(COMPONENT_SRCS "bootloader_start.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "")
|
||||
set(COMPONENT_REQUIRES "bootloader bootloader_support")
|
||||
register_component()
|
||||
@@ -41,12 +41,6 @@ typedef struct {
|
||||
|
||||
bool flash_encrypt(bootloader_state_t *bs);
|
||||
|
||||
/* Indices used by index_to_partition are the OTA index
|
||||
number, or these special constants */
|
||||
#define FACTORY_INDEX (-1)
|
||||
#define TEST_APP_INDEX (-2)
|
||||
#define INVALID_INDEX (-99)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,19 +8,12 @@ Linker file used to link the bootloader.
|
||||
The main purpose is to make sure the bootloader can load into main memory
|
||||
without overwriting itself.
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
/* I/O */
|
||||
dport0_seg (RW) : org = 0x3FF00000, len = 0x10
|
||||
/* IRAM POOL1, used for APP CPU cache. Bootloader runs from here during the final stage of loading the app because APP CPU is still held in reset, the main app enables APP CPU cache */
|
||||
iram_loader_seg (RWX) : org = 0x40078000, len = 0x8000 /* 32KB, APP CPU cache */
|
||||
/* 63kB, IRAM. We skip the first 1k to prevent the entry point being
|
||||
placed into the same range as exception vectors in the app.
|
||||
This leads to idf_monitor decoding ROM bootloader "entry 0x40080xxx"
|
||||
message as one of the exception vectors, which looks scary to users.
|
||||
*/
|
||||
iram_seg (RWX) : org = 0x40080400, len = 0xfc00
|
||||
/* IRAM POOL1, used for APP CPU cache. We can abuse it in bootloader because APP CPU is still held in reset, the main app enables APP CPU cache */
|
||||
iram_seg (RWX) : org = 0x40078000, len = 0x8000
|
||||
/* 64k at the end of DRAM, after ROM bootloader stack */
|
||||
dram_seg (RW) : org = 0x3FFF0000, len = 0x10000
|
||||
}
|
||||
@@ -31,36 +24,7 @@ ENTRY(call_start_cpu0);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
.iram_loader.text :
|
||||
{
|
||||
. = ALIGN (16);
|
||||
_loader_text_start = ABSOLUTE(.);
|
||||
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
|
||||
*liblog.a:(.literal .text .literal.* .text.*)
|
||||
*libgcc.a:(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_common.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:efuse.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:secure_boot_signatures.*(.literal .text .literal.* .text.*)
|
||||
*libmicro-ecc.a:*.*(.literal .text .literal.* .text.*)
|
||||
*libspi_flash.a:*.*(.literal .text .literal.* .text.*)
|
||||
*libsoc.a:rtc_wdt.*(.literal .text .literal.* .text.*)
|
||||
*(.fini.literal)
|
||||
*(.fini)
|
||||
*(.gnu.version)
|
||||
_loader_text_end = ABSOLUTE(.);
|
||||
} > iram_loader_seg
|
||||
|
||||
.iram.text :
|
||||
.iram1.text :
|
||||
{
|
||||
. = ALIGN (16);
|
||||
*(.entry.text)
|
||||
@@ -124,13 +88,13 @@ SECTIONS
|
||||
. = (. + 3) & ~ 3;
|
||||
/* C++ constructor and destructor tables, properly ordered: */
|
||||
__init_array_start = ABSOLUTE(.);
|
||||
KEEP (*crtbegin.*(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
__init_array_end = ABSOLUTE(.);
|
||||
KEEP (*crtbegin.*(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
/* C++ exception handlers table: */
|
||||
@@ -157,7 +121,7 @@ SECTIONS
|
||||
_stext = .;
|
||||
_text_start = ABSOLUTE(.);
|
||||
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||
*(.iram .iram.*) /* catch stray IRAM_ATTR */
|
||||
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
|
||||
*(.fini.literal)
|
||||
*(.fini)
|
||||
*(.gnu.version)
|
||||
|
||||
@@ -1,4 +1 @@
|
||||
PROVIDE ( ets_update_cpu_frequency = 0x40008550 ); /* Updates g_ticks_per_us on the current CPU only; not on the other core */
|
||||
PROVIDE ( MD5Final = 0x4005db1c );
|
||||
PROVIDE ( MD5Init = 0x4005da7c );
|
||||
PROVIDE ( MD5Update = 0x4005da9c );
|
||||
|
||||
@@ -121,15 +121,10 @@ static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8
|
||||
|
||||
/* dummy_len_plus values defined in ROM for SPI flash configuration */
|
||||
extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
||||
uint32_t bootloader_read_flash_id()
|
||||
{
|
||||
uint32_t id = execute_flash_command(CMD_RDID, 0, 0, 24);
|
||||
id = ((id & 0xff) << 16) | ((id >> 16) & 0xff) | (id & 0xff00);
|
||||
return id;
|
||||
}
|
||||
|
||||
void bootloader_enable_qio_mode(void)
|
||||
{
|
||||
uint32_t old_ctrl_reg;
|
||||
uint32_t raw_flash_id;
|
||||
uint8_t mfg_id;
|
||||
uint16_t flash_id;
|
||||
@@ -138,11 +133,20 @@ void bootloader_enable_qio_mode(void)
|
||||
ESP_LOGD(TAG, "Probing for QIO mode enable...");
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
|
||||
raw_flash_id = g_rom_flashchip.device_id;
|
||||
/* Set up some of the SPIFLASH user/ctrl variables which don't change
|
||||
while we're probing using execute_flash_command() */
|
||||
old_ctrl_reg = SPIFLASH.ctrl.val;
|
||||
SPIFLASH.ctrl.val = SPI_WP_REG; // keep WP high while idle, otherwise leave DIO mode
|
||||
SPIFLASH.user.usr_dummy = 0;
|
||||
SPIFLASH.user.usr_addr = 0;
|
||||
SPIFLASH.user.usr_command = 1;
|
||||
SPIFLASH.user2.usr_command_bitlen = 7;
|
||||
|
||||
raw_flash_id = execute_flash_command(CMD_RDID, 0, 0, 24);
|
||||
ESP_LOGD(TAG, "Raw SPI flash chip id 0x%x", raw_flash_id);
|
||||
|
||||
mfg_id = (raw_flash_id >> 16) & 0xFF;
|
||||
flash_id = raw_flash_id & 0xFFFF;
|
||||
mfg_id = raw_flash_id & 0xFF;
|
||||
flash_id = (raw_flash_id >> 16) | (raw_flash_id & 0xFF00);
|
||||
ESP_LOGD(TAG, "Manufacturer ID 0x%02x chip ID 0x%04x", mfg_id, flash_id);
|
||||
|
||||
for (i = 0; i < NUM_CHIPS-1; i++) {
|
||||
@@ -157,9 +161,13 @@ void bootloader_enable_qio_mode(void)
|
||||
ESP_LOGI(TAG, "Enabling default flash chip QIO");
|
||||
}
|
||||
|
||||
enable_qio_mode(chip_data[i].read_status_fn,
|
||||
chip_data[i].write_status_fn,
|
||||
chip_data[i].status_qio_bit);
|
||||
esp_err_t res = enable_qio_mode(chip_data[i].read_status_fn,
|
||||
chip_data[i].write_status_fn,
|
||||
chip_data[i].status_qio_bit);
|
||||
if (res != ESP_OK) {
|
||||
// Restore SPI flash CTRL setting, to keep us in DIO/DOUT mode
|
||||
SPIFLASH.ctrl.val = old_ctrl_reg;
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
|
||||
@@ -173,15 +181,13 @@ static esp_err_t enable_qio_mode(read_status_fn_t read_status_fn,
|
||||
// spiconfig specifies a custom efuse pin configuration. This config defines all pins -except- WP,
|
||||
// which is compiled into the bootloader instead.
|
||||
//
|
||||
// Most commonly an overriden pin mapping means ESP32-D2WD or ESP32-PICOD4.
|
||||
//Warn if chip is ESP32-D2WD/ESP32-PICOD4 but someone has changed the WP pin
|
||||
//assignment from that chip's WP pin.
|
||||
uint32_t pkg_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
|
||||
if (CONFIG_BOOTLOADER_SPI_WP_PIN != ESP32_D2WD_WP_GPIO &&
|
||||
(pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5 ||
|
||||
pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2 ||
|
||||
pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4)) {
|
||||
ESP_LOGW(TAG, "Chip is ESP32-D2WD/ESP32-PICOD4 but flash WP pin is different value to internal flash");
|
||||
// Most commonly an overriden pin mapping means ESP32-D2WD. Warn if chip is ESP32-D2WD
|
||||
// but someone has changed the WP pin assignment from that chip's WP pin.
|
||||
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_RESERVE);
|
||||
uint32_t pkg_ver = chip_ver & 0x7;
|
||||
const int PKG_VER_ESP32_D2WD = 2; // TODO: use chip detection API once available
|
||||
if (pkg_ver == PKG_VER_ESP32_D2WD && CONFIG_BOOTLOADER_SPI_WP_PIN != ESP32_D2WD_WP_GPIO) {
|
||||
ESP_LOGW(TAG, "Chip is ESP32-D2WD but flash WP pin is different value to internal flash");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,13 +279,6 @@ static void write_status_8b_xmc25qu64a(unsigned new_status)
|
||||
|
||||
static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len)
|
||||
{
|
||||
uint32_t old_ctrl_reg = SPIFLASH.ctrl.val;
|
||||
SPIFLASH.ctrl.val = SPI_WP_REG_M; // keep WP high while idle, otherwise leave DIO mode
|
||||
SPIFLASH.user.usr_dummy = 0;
|
||||
SPIFLASH.user.usr_addr = 0;
|
||||
SPIFLASH.user.usr_command = 1;
|
||||
SPIFLASH.user2.usr_command_bitlen = 7;
|
||||
|
||||
SPIFLASH.user2.usr_command_value = command;
|
||||
SPIFLASH.user.usr_miso = miso_len > 0;
|
||||
SPIFLASH.miso_dlen.usr_miso_dbitlen = miso_len ? (miso_len - 1) : 0;
|
||||
@@ -302,6 +301,5 @@ static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8
|
||||
while(SPIFLASH.cmd.usr != 0)
|
||||
{ }
|
||||
|
||||
SPIFLASH.ctrl.val = old_ctrl_reg;
|
||||
return SPIFLASH.data_buf[0];
|
||||
}
|
||||
@@ -24,14 +24,6 @@ extern "C" {
|
||||
*/
|
||||
void bootloader_enable_qio_mode(void);
|
||||
|
||||
/**
|
||||
* @brief Read flash ID by sending 0x9F command
|
||||
* @return flash raw ID
|
||||
* mfg_id = (ID >> 16) & 0xFF;
|
||||
flash_id = ID & 0xffff;
|
||||
*/
|
||||
uint32_t bootloader_read_flash_id();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
set(COMPONENT_SRCS "src/bootloader_clock.c"
|
||||
"src/bootloader_common.c"
|
||||
"src/bootloader_flash.c"
|
||||
"src/bootloader_random.c"
|
||||
"src/bootloader_sha.c"
|
||||
"src/bootloader_utility.c"
|
||||
"src/efuse.c"
|
||||
"src/esp_image_format.c"
|
||||
"src/flash_encrypt.c"
|
||||
"src/flash_partitions.c"
|
||||
"src/flash_qio_mode.c"
|
||||
"src/secure_boot.c"
|
||||
"src/secure_boot_signatures.c")
|
||||
|
||||
if(${BOOTLOADER_BUILD})
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include include_bootloader")
|
||||
set(COMPONENT_REQUIRES)
|
||||
set(COMPONENT_PRIV_REQUIRES spi_flash micro-ecc)
|
||||
list(APPEND COMPONENT_SRCS "src/bootloader_init.c")
|
||||
else()
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||
set(COMPONENT_PRIV_INCLUDEDIRS "include_bootloader")
|
||||
set(COMPONENT_REQUIRES)
|
||||
set(COMPONENT_PRIV_REQUIRES spi_flash mbedtls micro-ecc)
|
||||
endif()
|
||||
|
||||
register_component()
|
||||
14
components/bootloader_support/component.mk
Normal file → Executable file
14
components/bootloader_support/component.mk
Normal file → Executable file
@@ -1,22 +1,18 @@
|
||||
COMPONENT_ADD_INCLUDEDIRS := include
|
||||
COMPONENT_PRIV_INCLUDEDIRS := include_priv
|
||||
|
||||
ifdef IS_BOOTLOADER_BUILD
|
||||
# share "include_bootloader" headers with bootloader main component
|
||||
COMPONENT_ADD_INCLUDEDIRS += include_bootloader
|
||||
else
|
||||
COMPONENT_PRIV_INCLUDEDIRS := include_bootloader
|
||||
# share "private" headers with the bootloader component
|
||||
# eventual goal: all functionality that needs this lives in bootloader_support
|
||||
COMPONENT_ADD_INCLUDEDIRS += include_priv
|
||||
endif
|
||||
|
||||
COMPONENT_SRCDIRS := src
|
||||
|
||||
ifndef IS_BOOTLOADER_BUILD
|
||||
COMPONENT_OBJEXCLUDE := src/bootloader_init.o
|
||||
endif
|
||||
|
||||
#
|
||||
# Secure boot signing key support
|
||||
#
|
||||
ifdef CONFIG_SECURE_SIGNED_APPS
|
||||
ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
|
||||
# this path is created relative to the component build directory
|
||||
SECURE_BOOT_VERIFICATION_KEY := $(abspath signature_verification_key.bin)
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
#include "esp_flash_data_types.h"
|
||||
|
||||
/// Type of hold a GPIO in low state
|
||||
typedef enum {
|
||||
GPIO_LONG_HOLD = 1, /*!< The long hold GPIO */
|
||||
GPIO_SHORT_HOLD = -1, /*!< The short hold GPIO */
|
||||
GPIO_NOT_HOLD = 0 /*!< If the GPIO input is not low */
|
||||
} esp_comm_gpio_hold_t;
|
||||
|
||||
/**
|
||||
* @brief Calculate crc for the OTA data partition.
|
||||
*
|
||||
* @param[in] ota_data The OTA data partition.
|
||||
* @return Returns crc value.
|
||||
*/
|
||||
uint32_t bootloader_common_ota_select_crc(const esp_ota_select_entry_t *s);
|
||||
|
||||
/**
|
||||
* @brief Verifies the validity of the OTA data partition
|
||||
*
|
||||
* @param[in] ota_data The OTA data partition.
|
||||
* @return Returns true on valid, false otherwise.
|
||||
*/
|
||||
bool bootloader_common_ota_select_valid(const esp_ota_select_entry_t *s);
|
||||
|
||||
/**
|
||||
* @brief Check if the GPIO input is a long hold or a short hold.
|
||||
*
|
||||
* Number of the GPIO input will be configured as an input with internal pull-up enabled.
|
||||
* If the GPIO input is held low continuously for delay_sec period then it is a long hold.
|
||||
* If the GPIO input is held low for less period then it is a short hold.
|
||||
*
|
||||
* @param[in] num_pin Number of the GPIO input.
|
||||
* @param[in] delay_sec Input must be driven low for at least this long, continuously.
|
||||
* @return esp_comm_gpio_hold_t Defines type of hold a GPIO in low state.
|
||||
*/
|
||||
esp_comm_gpio_hold_t bootloader_common_check_long_hold_gpio(uint32_t num_pin, uint32_t delay_sec);
|
||||
|
||||
/**
|
||||
* @brief Erase the partition data that is specified in the transferred list.
|
||||
*
|
||||
* @param[in] list_erase String containing a list of cleared partitions. Like this "nvs, phy". The string must be null-terminal.
|
||||
* @param[in] ota_data_erase If true then the OTA data partition will be cleared (if there is it in partition table).
|
||||
* @return Returns true on success, false otherwise.
|
||||
*/
|
||||
bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_data_erase);
|
||||
|
||||
/**
|
||||
* @brief Determines if the list contains the label
|
||||
*
|
||||
* @param[in] list A string of names delimited by commas or spaces. Like this "nvs, phy, data". The string must be null-terminated.
|
||||
* @param[in] label The substring that will be searched in the list.
|
||||
* @return Returns true if the list contains the label, false otherwise.
|
||||
*/
|
||||
bool bootloader_common_label_search(const char *list, char *label);
|
||||
|
||||
/**
|
||||
* @brief Calculates a sha-256 for a given partition or returns a appended digest.
|
||||
*
|
||||
* This function can be used to return the SHA-256 digest of application, bootloader and data partitions.
|
||||
* For apps with SHA-256 appended to the app image, the result is the appended SHA-256 value for the app image content.
|
||||
* The hash is verified before returning, if app content is invalid then the function returns ESP_ERR_IMAGE_INVALID.
|
||||
* For apps without SHA-256 appended to the image, the result is the SHA-256 of all bytes in the app image.
|
||||
* For other partition types, the result is the SHA-256 of the entire partition.
|
||||
*
|
||||
* @param[in] address Address of partition.
|
||||
* @param[in] size Size of partition.
|
||||
* @param[in] type Type of partition. For applications the type is 0, otherwise type is data.
|
||||
* @param[out] out_sha_256 Returned SHA-256 digest for a given partition.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: In case of successful operation.
|
||||
* - ESP_ERR_INVALID_ARG: The size was 0 or the sha_256 was NULL.
|
||||
* - ESP_ERR_NO_MEM: Cannot allocate memory for sha256 operation.
|
||||
* - ESP_ERR_IMAGE_INVALID: App partition doesn't contain a valid app image.
|
||||
* - ESP_FAIL: An allocation error occurred.
|
||||
*/
|
||||
esp_err_t bootloader_common_get_sha256_of_partition(uint32_t address, uint32_t size, int type, uint8_t *out_sha_256);
|
||||
@@ -1,34 +0,0 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* @brief Check if half-open intervals overlap
|
||||
*
|
||||
* @param start1 interval 1 start
|
||||
* @param end1 interval 1 end
|
||||
* @param start2 interval 2 start
|
||||
* @param end2 interval 2 end
|
||||
* @return true iff [start1; end1) overlaps [start2; end2)
|
||||
*/
|
||||
static inline bool bootloader_util_regions_overlap(
|
||||
const intptr_t start1, const intptr_t end1,
|
||||
const intptr_t start2, const intptr_t end2)
|
||||
{
|
||||
return (end1 > start2 && end2 > start1) ||
|
||||
!(end1 <= start2 || end2 <= start1);
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
#define _ESP_EFUSE_H
|
||||
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -59,38 +58,6 @@ void esp_efuse_reset(void);
|
||||
*/
|
||||
void esp_efuse_disable_basic_rom_console(void);
|
||||
|
||||
/* @brief Encode one or more sets of 6 byte sequences into
|
||||
* 8 bytes suitable for 3/4 Coding Scheme.
|
||||
*
|
||||
* This function is only useful if the CODING_SCHEME efuse
|
||||
* is set to value 1 for 3/4 Coding Scheme.
|
||||
*
|
||||
* @param[in] in_bytes Pointer to a sequence of bytes to encode for 3/4 Coding Scheme. Must have length in_bytes_len. After being written to hardware, these bytes will read back as little-endian words.
|
||||
* @param[out] out_words Pointer to array of words suitable for writing to efuse write registers. Array must contain 2 words (8 bytes) for every 6 bytes in in_bytes_len. Can be a pointer to efuse write registers.
|
||||
* @param in_bytes_len. Length of array pointed to by in_bytes, in bytes. Must be a multiple of 6.
|
||||
*
|
||||
* @return ESP_ERR_INVALID_ARG if either pointer is null or in_bytes_len is not a multiple of 6. ESP_OK otherwise.
|
||||
*/
|
||||
esp_err_t esp_efuse_apply_34_encoding(const uint8_t *in_bytes, uint32_t *out_words, size_t in_bytes_len);
|
||||
|
||||
/* @brief Write random data to efuse key block write registers
|
||||
*
|
||||
* @note Caller is responsible for ensuring efuse
|
||||
* block is empty and not write protected, before calling.
|
||||
*
|
||||
* @note Behaviour depends on coding scheme: a 256-bit key is
|
||||
* generated and written for Coding Scheme "None", a 192-bit key
|
||||
* is generated, extended to 256-bits by the Coding Scheme,
|
||||
* and then writtten for 3/4 Coding Scheme.
|
||||
*
|
||||
* @note This function does not burn the new values, caller should
|
||||
* call esp_efuse_burn_new_values() when ready to do this.
|
||||
*
|
||||
* @param blk_wdata0_reg Address of the first data write register
|
||||
* in the block
|
||||
*/
|
||||
void esp_efuse_write_random_key(uint32_t blk_wdata0_reg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
#include <stdbool.h>
|
||||
#include "esp_attr.h"
|
||||
#include "esp_err.h"
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
#include "esp_spi_flash.h"
|
||||
#endif
|
||||
#include "soc/efuse_reg.h"
|
||||
|
||||
/**
|
||||
@@ -85,8 +83,6 @@ static inline /** @cond */ IRAM_ATTR /** @endcond */ bool esp_flash_encryption_e
|
||||
* @note Take care not to power off the device while this function
|
||||
* is running, or the partition currently being encrypted will be lost.
|
||||
*
|
||||
* @note RTC_WDT will reset while encryption operations will be performed (if RTC_WDT is configured).
|
||||
*
|
||||
* @return ESP_OK if all operations succeeded, ESP_ERR_INVALID_STATE
|
||||
* if a fatal error occured during encryption of all partitions.
|
||||
*/
|
||||
@@ -95,7 +91,6 @@ esp_err_t esp_flash_encrypt_check_and_update(void);
|
||||
|
||||
/** @brief Encrypt-in-place a block of flash sectors
|
||||
*
|
||||
* @note This function resets RTC_WDT between operations with sectors.
|
||||
* @param src_addr Source offset in flash. Should be multiple of 4096 bytes.
|
||||
* @param data_length Length of data to encrypt in bytes. Will be rounded up to next multiple of 4096 bytes.
|
||||
*
|
||||
@@ -104,14 +99,4 @@ esp_err_t esp_flash_encrypt_check_and_update(void);
|
||||
*/
|
||||
esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length);
|
||||
|
||||
/** @brief Write protect FLASH_CRYPT_CNT
|
||||
*
|
||||
* Intended to be called as a part of boot process if flash encryption
|
||||
* is enabled but secure boot is not used. This should protect against
|
||||
* serial re-flashing of an unauthorised code in absence of secure boot.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
void esp_flash_write_protect_crypt_cnt();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,17 +17,17 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_flash_data_types.h"
|
||||
#include <stdbool.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/* Pre-partition table fixed flash offsets */
|
||||
#define ESP_BOOTLOADER_DIGEST_OFFSET 0x0
|
||||
#define ESP_BOOTLOADER_OFFSET 0x1000 /* Offset of bootloader image. Has matching value in bootloader KConfig.projbuild file. */
|
||||
#define ESP_PARTITION_TABLE_OFFSET CONFIG_PARTITION_TABLE_OFFSET /* Offset of partition table. Backwards-compatible name.*/
|
||||
#define ESP_BOOTLOADER_SIZE (ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET)
|
||||
#define ESP_PARTITION_TABLE_OFFSET 0x8000 /* Offset of partition table. Has matching value in partition_table Kconfig.projbuild file. */
|
||||
|
||||
#define ESP_PARTITION_TABLE_MAX_LEN 0xC00 /* Maximum length of partition table data */
|
||||
#define ESP_PARTITION_TABLE_MAX_ENTRIES (ESP_PARTITION_TABLE_MAX_LEN / sizeof(esp_partition_info_t)) /* Maximum length of partition table data, including terminating entry */
|
||||
|
||||
/* @brief Verify the partition table
|
||||
/* @brief Verify the partition table (does not include verifying secure boot cryptographic signature)
|
||||
*
|
||||
* @param partition_table Pointer to at least ESP_PARTITION_TABLE_MAX_ENTRIES of potential partition table data. (ESP_PARTITION_TABLE_MAX_LEN bytes.)
|
||||
* @param log_errors Log errors if the partition table is invalid.
|
||||
@@ -35,13 +35,6 @@
|
||||
*
|
||||
* @return ESP_OK on success, ESP_ERR_INVALID_STATE if partition table is not valid.
|
||||
*/
|
||||
esp_err_t esp_partition_table_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions);
|
||||
|
||||
|
||||
/* This function is included for compatibility with the ESP-IDF v3.x API */
|
||||
inline static __attribute__((deprecated)) esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions)
|
||||
{
|
||||
return esp_partition_table_verify(partition_table, log_errors, num_partitions);
|
||||
}
|
||||
esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -36,7 +36,7 @@ typedef enum {
|
||||
} esp_image_spi_mode_t;
|
||||
|
||||
/* SPI flash clock frequency */
|
||||
typedef enum {
|
||||
enum {
|
||||
ESP_IMAGE_SPI_SPEED_40M,
|
||||
ESP_IMAGE_SPI_SPEED_26M,
|
||||
ESP_IMAGE_SPI_SPEED_20M,
|
||||
@@ -81,8 +81,6 @@ typedef struct {
|
||||
|
||||
_Static_assert(sizeof(esp_image_header_t) == 24, "binary image header should be 24 bytes");
|
||||
|
||||
#define ESP_IMAGE_HASH_LEN 32 /* Length of the appended SHA-256 digest */
|
||||
|
||||
/* Header of binary image segment */
|
||||
typedef struct {
|
||||
uint32_t load_addr;
|
||||
@@ -98,12 +96,11 @@ typedef struct {
|
||||
esp_image_segment_header_t segments[ESP_IMAGE_MAX_SEGMENTS]; /* Per-segment header data */
|
||||
uint32_t segment_data[ESP_IMAGE_MAX_SEGMENTS]; /* Data offsets for each segment */
|
||||
uint32_t image_len; /* Length of image on flash, in bytes */
|
||||
uint8_t image_digest[32]; /* appended SHA-256 digest */
|
||||
} esp_image_metadata_t;
|
||||
|
||||
/* Mode selection for esp_image_load() */
|
||||
typedef enum {
|
||||
ESP_IMAGE_VERIFY, /* Verify image contents, load metadata. Print errors. */
|
||||
ESP_IMAGE_VERIFY, /* Verify image contents, load metadata. Print errorsors. */
|
||||
ESP_IMAGE_VERIFY_SILENT, /* Verify image contents, load metadata. Don't print errors. */
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
ESP_IMAGE_LOAD, /* Verify image contents, load to memory. Print errors. */
|
||||
@@ -113,11 +110,6 @@ typedef enum {
|
||||
/**
|
||||
* @brief Verify and (optionally, in bootloader mode) load an app image.
|
||||
*
|
||||
* This name is deprecated and is included for compatibility with the ESP-IDF v3.x API.
|
||||
* It will be removed in V4.0 version.
|
||||
* Function has been renamed to esp_image_verify().
|
||||
* Use function esp_image_verify() to verify a image. And use function bootloader_load_image() to load image from a bootloader space.
|
||||
*
|
||||
* If encryption is enabled, data will be transparently decrypted.
|
||||
*
|
||||
* @param mode Mode of operation (verify, silent verify, or load).
|
||||
@@ -138,60 +130,7 @@ typedef enum {
|
||||
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
|
||||
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
|
||||
*/
|
||||
esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data) __attribute__((deprecated));
|
||||
|
||||
/**
|
||||
* @brief Verify an app image.
|
||||
*
|
||||
* If encryption is enabled, data will be transparently decrypted.
|
||||
*
|
||||
* @param mode Mode of operation (verify, silent verify, or load).
|
||||
* @param part Partition to load the app from.
|
||||
* @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
|
||||
* 'start_addr' member should be set (to the start address of the image.)
|
||||
* Other fields will all be initialised by this function.
|
||||
*
|
||||
* Image validation checks:
|
||||
* - Magic byte.
|
||||
* - Partition smaller than 16MB.
|
||||
* - All segments & image fit in partition.
|
||||
* - 8 bit image checksum is valid.
|
||||
* - SHA-256 of image is valid (if image has this appended).
|
||||
* - (Signature) if signature verification is enabled.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if verify or load was successful
|
||||
* - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
|
||||
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
|
||||
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
|
||||
*/
|
||||
esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data);
|
||||
|
||||
/**
|
||||
* @brief Verify and load an app image (available only in space of bootloader).
|
||||
*
|
||||
* If encryption is enabled, data will be transparently decrypted.
|
||||
*
|
||||
* @param part Partition to load the app from.
|
||||
* @param[inout] data Pointer to the image metadata structure which is be filled in by this function.
|
||||
* 'start_addr' member should be set (to the start address of the image.)
|
||||
* Other fields will all be initialised by this function.
|
||||
*
|
||||
* Image validation checks:
|
||||
* - Magic byte.
|
||||
* - Partition smaller than 16MB.
|
||||
* - All segments & image fit in partition.
|
||||
* - 8 bit image checksum is valid.
|
||||
* - SHA-256 of image is valid (if image has this appended).
|
||||
* - (Signature) if signature verification is enabled.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if verify or load was successful
|
||||
* - ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs
|
||||
* - ESP_ERR_IMAGE_INVALID if the image appears invalid.
|
||||
* - ESP_ERR_INVALID_ARG if the partition or data pointers are invalid.
|
||||
*/
|
||||
esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data);
|
||||
esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data);
|
||||
|
||||
/**
|
||||
* @brief Verify the bootloader image.
|
||||
@@ -203,16 +142,6 @@ esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metad
|
||||
*/
|
||||
esp_err_t esp_image_verify_bootloader(uint32_t *length);
|
||||
|
||||
/**
|
||||
* @brief Verify the bootloader image.
|
||||
*
|
||||
* @param[out] Metadata for the image. Only valid if result is ESP_OK.
|
||||
*
|
||||
* @return As per esp_image_load_metadata().
|
||||
*/
|
||||
esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data);
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t drom_addr;
|
||||
uint32_t drom_load_addr;
|
||||
|
||||
@@ -17,14 +17,6 @@
|
||||
#include <esp_err.h>
|
||||
#include "soc/efuse_reg.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
#if !defined(CONFIG_SECURE_SIGNED_ON_BOOT) || !defined(CONFIG_SECURE_SIGNED_ON_UPDATE) || !defined(CONFIG_SECURE_SIGNED_APPS)
|
||||
#error "internal sdkconfig error, secure boot should always enable all signature options"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
/* @brief Prepares hardware for work.
|
||||
*
|
||||
* Setting up:
|
||||
* - Disable Cache access for both CPUs;
|
||||
* - Initialise cache mmu;
|
||||
* - Setting up pins and mode for SD, SPI, UART, Clocking.
|
||||
|
||||
* @return ESP_OK - If the setting is successful.
|
||||
* ESP_FAIL - If the setting is not successful.
|
||||
*/
|
||||
esp_err_t bootloader_init();
|
||||
@@ -1,56 +0,0 @@
|
||||
// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#pragma once
|
||||
|
||||
/* Provide a SHA256 API for bootloader_support code,
|
||||
that can be used from bootloader or app code.
|
||||
|
||||
This header is available to source code in the bootloader & bootloader_support components only.
|
||||
Use mbedTLS APIs or include hwcrypto/sha.h to calculate SHA256 in IDF apps.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
typedef void *bootloader_sha256_handle_t;
|
||||
|
||||
bootloader_sha256_handle_t bootloader_sha256_start();
|
||||
|
||||
void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len);
|
||||
|
||||
void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest);
|
||||
|
||||
/**
|
||||
* @brief Converts an array to a printable string.
|
||||
*
|
||||
* This function is useful for printing SHA-256 digest.
|
||||
* \code{c}
|
||||
* // Example of using. image_hash will be printed
|
||||
* #define HASH_LEN 32 // SHA-256 digest length
|
||||
* ...
|
||||
* char hash_print[HASH_LEN * 2 + 1];
|
||||
* hash_print[HASH_LEN * 2] = 0;
|
||||
* bootloader_sha256_hex_to_str(hash_print, image_hash, HASH_LEN);
|
||||
* ESP_LOGI(TAG, %s", hash_print);
|
||||
* \endcode
|
||||
|
||||
* @param[out] out_str Output string
|
||||
* @param[in] in_array_hex Pointer to input array
|
||||
* @param[in] len Length of input array
|
||||
*
|
||||
* @return ESP_OK: Successful
|
||||
* ESP_ERR_INVALID_ARG: Error in the passed arguments
|
||||
*/
|
||||
esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len);
|
||||
@@ -1,64 +0,0 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#pragma once
|
||||
|
||||
#include "esp_image_format.h"
|
||||
|
||||
/**
|
||||
* @brief Load partition table.
|
||||
*
|
||||
* Parse partition table, get useful data such as location of
|
||||
* OTA data partition, factory app partition, and test app partition.
|
||||
*
|
||||
* @param[out] bs Bootloader state structure used to save read data.
|
||||
* @return Return true if the partition table was succesfully loaded and MD5 checksum is valid.
|
||||
*/
|
||||
bool bootloader_utility_load_partition_table(bootloader_state_t* bs);
|
||||
|
||||
/**
|
||||
* @brief Return the index of the selected boot partition.
|
||||
*
|
||||
* This is the preferred boot partition, as determined by the partition table &
|
||||
* any OTA sequence number found in OTA data.
|
||||
* This partition will only be booted if it contains a valid app image, otherwise load_boot_image() will search
|
||||
* for a valid partition using this selection as the starting point.
|
||||
*
|
||||
* @param[in] bs Bootloader state structure.
|
||||
* @return Returns the index on success, INVALID_INDEX otherwise.
|
||||
*/
|
||||
int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs);
|
||||
|
||||
/**
|
||||
* @brief Load the selected partition and start application.
|
||||
*
|
||||
* Start from partition 'start_index', if not bootable then work backwards to FACTORY_INDEX
|
||||
* (ie try any OTA slots in descending order and then the factory partition).
|
||||
* If still nothing, start from 'start_index + 1' and work up to highest numbered OTA partition.
|
||||
* If still nothing, try TEST_APP_INDEX.
|
||||
* Everything this function calls must be located in the iram_loader_seg segment.
|
||||
*
|
||||
* @param[in] bs Bootloader state structure.
|
||||
* @param[in] start_index The index from which the search for images begins.
|
||||
*/
|
||||
__attribute__((noreturn)) void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Software reset the ESP32
|
||||
*
|
||||
* Bootloader code should call this in the case that it cannot proceed.
|
||||
*
|
||||
* It is not recommended to call this function from an app (if called, the app will abort).
|
||||
*/
|
||||
__attribute__((noreturn)) void bootloader_reset(void);
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "esp_spi_flash.h"
|
||||
|
||||
#define FLASH_SECTOR_SIZE 0x1000
|
||||
#define FLASH_BLOCK_SIZE 0x10000
|
||||
|
||||
/* Provide a Flash API for bootloader_support code,
|
||||
that can be used from bootloader or app code.
|
||||
@@ -101,31 +100,4 @@ esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool
|
||||
*/
|
||||
esp_err_t bootloader_flash_erase_sector(size_t sector);
|
||||
|
||||
/**
|
||||
* @brief Erase the Flash range.
|
||||
*
|
||||
* @param start_addr start address of flash offset
|
||||
* @param size sector aligned size to be erased
|
||||
*
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size);
|
||||
|
||||
/* Cache MMU block size */
|
||||
#define MMU_BLOCK_SIZE 0x00010000
|
||||
|
||||
/* Cache MMU address mask (MMU tables ignore bits which are zero) */
|
||||
#define MMU_FLASH_MASK (~(MMU_BLOCK_SIZE - 1))
|
||||
|
||||
/**
|
||||
* @brief Calculate the number of cache pages to map
|
||||
* @param size size of data to map
|
||||
* @param vaddr virtual address where data will be mapped
|
||||
* @return number of cache MMU pages required to do the mapping
|
||||
*/
|
||||
static inline uint32_t bootloader_cache_pages_to_map(uint32_t size, uint32_t vaddr)
|
||||
{
|
||||
return (size + (vaddr - (vaddr & MMU_FLASH_MASK)) + MMU_BLOCK_SIZE - 1) / MMU_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
#endif
|
||||
32
components/bootloader_support/include_priv/bootloader_sha.h
Normal file
32
components/bootloader_support/include_priv/bootloader_sha.h
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#pragma once
|
||||
|
||||
/* Provide a SHA256 API for bootloader_support code,
|
||||
that can be used from bootloader or app code.
|
||||
|
||||
This header is available to source code in the bootloader & bootloader_support components only.
|
||||
Use mbedTLS APIs or include hwcrypto/sha.h to calculate SHA256 in IDF apps.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef void *bootloader_sha256_handle_t;
|
||||
|
||||
bootloader_sha256_handle_t bootloader_sha256_start();
|
||||
|
||||
void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len);
|
||||
|
||||
void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest);
|
||||
@@ -29,22 +29,22 @@ void bootloader_clock_configure()
|
||||
uart_tx_wait_idle(0);
|
||||
|
||||
/* Set CPU to 80MHz. Keep other clocks unmodified. */
|
||||
int cpu_freq_mhz = 80;
|
||||
rtc_cpu_freq_t cpu_freq = RTC_CPU_FREQ_80M;
|
||||
|
||||
/* On ESP32 rev 0, switching to 80/160 MHz if clock was previously set to
|
||||
/* On ESP32 rev 0, switching to 80MHz if clock was previously set to
|
||||
* 240 MHz may cause the chip to lock up (see section 3.5 of the errata
|
||||
* document). For rev. 0, switch to 240 instead if it has been enabled
|
||||
* previously.
|
||||
* document). For rev. 0, switch to 240 instead if it was chosen in
|
||||
* menuconfig.
|
||||
*/
|
||||
uint32_t chip_ver_reg = REG_READ(EFUSE_BLK0_RDATA3_REG);
|
||||
if ((chip_ver_reg & EFUSE_RD_CHIP_VER_REV1_M) == 0 &&
|
||||
DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL) == DPORT_CPUPERIOD_SEL_240) {
|
||||
cpu_freq_mhz = 240;
|
||||
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240) {
|
||||
cpu_freq = RTC_CPU_FREQ_240M;
|
||||
}
|
||||
|
||||
rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT();
|
||||
clk_cfg.xtal_freq = CONFIG_ESP32_XTAL_FREQ;
|
||||
clk_cfg.cpu_freq_mhz = cpu_freq_mhz;
|
||||
clk_cfg.cpu_freq = cpu_freq;
|
||||
clk_cfg.slow_freq = rtc_clk_slow_freq_get();
|
||||
clk_cfg.fast_freq = rtc_clk_fast_freq_get();
|
||||
rtc_clk_init(clk_cfg);
|
||||
@@ -55,7 +55,7 @@ void bootloader_clock_configure()
|
||||
*/
|
||||
#ifdef CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
|
||||
if (!rtc_clk_32k_enabled()) {
|
||||
rtc_clk_32k_bootstrap(CONFIG_ESP32_RTC_XTAL_BOOTSTRAP_CYCLES);
|
||||
rtc_clk_32k_bootstrap();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include "string.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/crc.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/gpio.h"
|
||||
#include "esp_flash_data_types.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_common.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "bootloader_sha.h"
|
||||
|
||||
#define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */
|
||||
|
||||
static const char* TAG = "boot_comm";
|
||||
|
||||
uint32_t bootloader_common_ota_select_crc(const esp_ota_select_entry_t *s)
|
||||
{
|
||||
return crc32_le(UINT32_MAX, (uint8_t*)&s->ota_seq, 4);
|
||||
}
|
||||
|
||||
bool bootloader_common_ota_select_valid(const esp_ota_select_entry_t *s)
|
||||
{
|
||||
return s->ota_seq != UINT32_MAX && s->crc == bootloader_common_ota_select_crc(s);
|
||||
}
|
||||
|
||||
esp_comm_gpio_hold_t bootloader_common_check_long_hold_gpio(uint32_t num_pin, uint32_t delay_sec)
|
||||
{
|
||||
gpio_pad_select_gpio(num_pin);
|
||||
if (GPIO_PIN_MUX_REG[num_pin]) {
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[num_pin]);
|
||||
}
|
||||
gpio_pad_pullup(num_pin);
|
||||
uint32_t tm_start = esp_log_early_timestamp();
|
||||
if (GPIO_INPUT_GET(num_pin) == 1) {
|
||||
return GPIO_NOT_HOLD;
|
||||
}
|
||||
do {
|
||||
if (GPIO_INPUT_GET(num_pin) != 0) {
|
||||
return GPIO_SHORT_HOLD;
|
||||
}
|
||||
} while (delay_sec > ((esp_log_early_timestamp() - tm_start) / 1000L));
|
||||
return GPIO_LONG_HOLD;
|
||||
}
|
||||
|
||||
// Search for a label in the list. list = "nvs1, nvs2, otadata, nvs"; label = "nvs".
|
||||
bool bootloader_common_label_search(const char *list, char *label)
|
||||
{
|
||||
if (list == NULL || label == NULL) {
|
||||
return false;
|
||||
}
|
||||
const char *sub_list_start_like_label = strstr(list, label);
|
||||
while (sub_list_start_like_label != NULL) {
|
||||
|
||||
// ["," or " "] + label + ["," or " " or "\0"]
|
||||
// first character before the label found there must be a delimiter ["," or " "].
|
||||
int idx_first = sub_list_start_like_label - list;
|
||||
if (idx_first == 0 || (idx_first != 0 && (list[idx_first - 1] == ',' || list[idx_first - 1] == ' '))) {
|
||||
// next character after the label found there must be a delimiter ["," or " " or "\0"].
|
||||
int len_label = strlen(label);
|
||||
if (sub_list_start_like_label[len_label] == 0 ||
|
||||
sub_list_start_like_label[len_label] == ',' ||
|
||||
sub_list_start_like_label[len_label] == ' ') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// [start_delim] + label + [end_delim] was not found.
|
||||
// Position is moving to next delimiter if it is not the end of list.
|
||||
int pos_delim = strcspn(sub_list_start_like_label, ", ");
|
||||
if (pos_delim == strlen(sub_list_start_like_label)) {
|
||||
break;
|
||||
}
|
||||
sub_list_start_like_label = strstr(&sub_list_start_like_label[pos_delim], label);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_data_erase)
|
||||
{
|
||||
const esp_partition_info_t *partitions;
|
||||
const char *marker;
|
||||
esp_err_t err;
|
||||
int num_partitions;
|
||||
bool ret = true;
|
||||
|
||||
partitions = bootloader_mmap(ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN);
|
||||
if (!partitions) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN);
|
||||
return false;
|
||||
}
|
||||
ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_OFFSET, (intptr_t)partitions);
|
||||
|
||||
err = esp_partition_table_verify(partitions, true, &num_partitions);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to verify partition table");
|
||||
ret = false;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "## Label Usage Offset Length Cleaned");
|
||||
for (int i = 0; i < num_partitions; i++) {
|
||||
const esp_partition_info_t *partition = &partitions[i];
|
||||
char label[sizeof(partition->label) + 1] = {0};
|
||||
if (partition->type == PART_TYPE_DATA) {
|
||||
bool fl_ota_data_erase = false;
|
||||
if (ota_data_erase == true && partition->subtype == PART_SUBTYPE_DATA_OTA) {
|
||||
fl_ota_data_erase = true;
|
||||
}
|
||||
// partition->label is not null-terminated string.
|
||||
strncpy(label, (char *)&partition->label, sizeof(label) - 1);
|
||||
if (fl_ota_data_erase == true || (bootloader_common_label_search(list_erase, label) == true)) {
|
||||
err = bootloader_flash_erase_range(partition->pos.offset, partition->pos.size);
|
||||
if (err != ESP_OK) {
|
||||
ret = false;
|
||||
marker = "err";
|
||||
} else {
|
||||
marker = "yes";
|
||||
}
|
||||
} else {
|
||||
marker = "no";
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "%2d %-16s data %08x %08x [%s]", i, partition->label,
|
||||
partition->pos.offset, partition->pos.size, marker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bootloader_munmap(partitions);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t bootloader_common_get_sha256_of_partition (uint32_t address, uint32_t size, int type, uint8_t *out_sha_256)
|
||||
{
|
||||
if (out_sha_256 == NULL || size == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (type == PART_TYPE_APP) {
|
||||
const esp_partition_pos_t partition_pos = {
|
||||
.offset = address,
|
||||
.size = size,
|
||||
};
|
||||
esp_image_metadata_t data;
|
||||
// Function esp_image_verify() verifies and fills the structure data.
|
||||
// here important to get: image_digest, image_len, hash_appended.
|
||||
if (esp_image_verify(ESP_IMAGE_VERIFY_SILENT, &partition_pos, &data) != ESP_OK) {
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
if (data.image.hash_appended) {
|
||||
memcpy(out_sha_256, data.image_digest, ESP_PARTITION_HASH_LEN);
|
||||
return ESP_OK;
|
||||
}
|
||||
// If image doesn't have a appended hash then hash calculates for entire image.
|
||||
size = data.image_len;
|
||||
}
|
||||
// If image is type by data then hash is calculated for entire image.
|
||||
const void *partition_bin = bootloader_mmap(address, size);
|
||||
if (partition_bin == NULL) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", address, size);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
bootloader_sha256_handle_t sha_handle = bootloader_sha256_start();
|
||||
if (sha_handle == NULL) {
|
||||
bootloader_munmap(partition_bin);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
bootloader_sha256_data(sha_handle, partition_bin, size);
|
||||
bootloader_sha256_finish(sha_handle, out_sha_256);
|
||||
|
||||
bootloader_munmap(partition_bin);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -73,11 +73,6 @@ esp_err_t bootloader_flash_erase_sector(size_t sector)
|
||||
return spi_flash_erase_sector(sector);
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
|
||||
{
|
||||
return spi_flash_erase_range(start_addr, size);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Bootloader version, uses ROM functions only */
|
||||
#include <soc/dport_reg.h>
|
||||
@@ -91,6 +86,8 @@ static const char *TAG = "bootloader_flash";
|
||||
*/
|
||||
#define MMU_BLOCK0_VADDR 0x3f400000
|
||||
#define MMU_BLOCK50_VADDR 0x3f720000
|
||||
#define MMU_FLASH_MASK 0xffff0000
|
||||
#define MMU_BLOCK_SIZE 0x00010000
|
||||
|
||||
static bool mapped;
|
||||
|
||||
@@ -110,11 +107,10 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
|
||||
}
|
||||
|
||||
uint32_t src_addr_aligned = src_addr & MMU_FLASH_MASK;
|
||||
uint32_t count = bootloader_cache_pages_to_map(size, src_addr);
|
||||
uint32_t count = (size + (src_addr - src_addr_aligned) + 0xffff) / MMU_BLOCK_SIZE;
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Flush(0);
|
||||
ESP_LOGD(TAG, "mmu set paddr=%08x count=%d size=%x src_addr=%x src_addr_aligned=%x",
|
||||
src_addr & MMU_FLASH_MASK, count, size, src_addr, src_addr_aligned );
|
||||
ESP_LOGD(TAG, "mmu set paddr=%08x count=%d", src_addr_aligned, count );
|
||||
int e = cache_flash_mmu_set(0, 0, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count);
|
||||
if (e != 0) {
|
||||
ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e);
|
||||
@@ -251,28 +247,4 @@ esp_err_t bootloader_flash_erase_sector(size_t sector)
|
||||
return spi_to_esp_err(esp_rom_spiflash_erase_sector(sector));
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
|
||||
{
|
||||
if (start_addr % FLASH_SECTOR_SIZE != 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (size % FLASH_SECTOR_SIZE != 0) {
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
size_t start = start_addr / FLASH_SECTOR_SIZE;
|
||||
size_t end = start + size / FLASH_SECTOR_SIZE;
|
||||
const size_t sectors_per_block = FLASH_BLOCK_SIZE / FLASH_SECTOR_SIZE;
|
||||
|
||||
esp_rom_spiflash_result_t rc = ESP_ROM_SPIFLASH_RESULT_OK;
|
||||
for (size_t sector = start; sector != end && rc == ESP_ROM_SPIFLASH_RESULT_OK; ) {
|
||||
if (sector % sectors_per_block == 0 && end - sector >= sectors_per_block) {
|
||||
rc = esp_rom_spiflash_erase_block(sector / sectors_per_block);
|
||||
sector += sectors_per_block;
|
||||
} else {
|
||||
rc = esp_rom_spiflash_erase_sector(sector);
|
||||
++sector;
|
||||
}
|
||||
}
|
||||
return spi_to_esp_err(rc);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,557 +0,0 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "rom/cache.h"
|
||||
#include "rom/efuse.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/crc.h"
|
||||
#include "rom/rtc.h"
|
||||
#include "rom/uart.h"
|
||||
#include "rom/gpio.h"
|
||||
#include "rom/secure_boot.h"
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/rtc_wdt.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_random.h"
|
||||
#include "bootloader_config.h"
|
||||
#include "bootloader_clock.h"
|
||||
|
||||
#include "flash_qio_mode.h"
|
||||
|
||||
extern int _bss_start;
|
||||
extern int _bss_end;
|
||||
extern int _data_start;
|
||||
extern int _data_end;
|
||||
|
||||
static const char* TAG = "boot";
|
||||
|
||||
static esp_err_t bootloader_main();
|
||||
static void print_flash_info(const esp_image_header_t* pfhdr);
|
||||
static void update_flash_config(const esp_image_header_t* pfhdr);
|
||||
static void vddsdio_configure();
|
||||
static void flash_gpio_configure(const esp_image_header_t* pfhdr);
|
||||
static void uart_console_configure(void);
|
||||
static void wdt_reset_check(void);
|
||||
|
||||
|
||||
esp_err_t bootloader_init()
|
||||
{
|
||||
cpu_configure_region_protection();
|
||||
cpu_init_memctl();
|
||||
|
||||
/* Sanity check that static RAM is after the stack */
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
int *sp = get_sp();
|
||||
assert(&_bss_start <= &_bss_end);
|
||||
assert(&_data_start <= &_data_end);
|
||||
assert(sp < &_bss_start);
|
||||
assert(sp < &_data_start);
|
||||
}
|
||||
#endif
|
||||
|
||||
//Clear bss
|
||||
memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
|
||||
|
||||
/* completely reset MMU for both CPUs
|
||||
(in case serial bootloader was running) */
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Read_Disable(1);
|
||||
Cache_Flush(0);
|
||||
Cache_Flush(1);
|
||||
mmu_init(0);
|
||||
DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
|
||||
mmu_init(1);
|
||||
DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
|
||||
/* (above steps probably unnecessary for most serial bootloader
|
||||
usage, all that's absolutely needed is that we unmask DROM0
|
||||
cache on the following two lines - normal ROM boot exits with
|
||||
DROM0 cache unmasked, but serial bootloader exits with it
|
||||
masked. However can't hurt to be thorough and reset
|
||||
everything.)
|
||||
|
||||
The lines which manipulate DPORT_APP_CACHE_MMU_IA_CLR bit are
|
||||
necessary to work around a hardware bug.
|
||||
*/
|
||||
DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DROM0);
|
||||
DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0);
|
||||
|
||||
if(bootloader_main() != ESP_OK){
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t bootloader_main()
|
||||
{
|
||||
vddsdio_configure();
|
||||
/* Read and keep flash ID, for further use. */
|
||||
g_rom_flashchip.device_id = bootloader_read_flash_id();
|
||||
esp_image_header_t fhdr;
|
||||
if (bootloader_flash_read(ESP_BOOTLOADER_OFFSET, &fhdr, sizeof(esp_image_header_t), true) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed to load bootloader header!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
flash_gpio_configure(&fhdr);
|
||||
#if (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240)
|
||||
//Check if ESP32 is rated for a CPU frequency of 160MHz only
|
||||
if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_RATED) &&
|
||||
REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_LOW)) {
|
||||
ESP_LOGE(TAG, "Chip CPU frequency rated for 160MHz. Modify CPU frequency in menuconfig");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
bootloader_clock_configure();
|
||||
uart_console_configure();
|
||||
wdt_reset_check();
|
||||
ESP_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER);
|
||||
|
||||
ESP_LOGI(TAG, "compile time " __TIME__ );
|
||||
ets_set_appcpu_boot_addr(0);
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
|
||||
ESP_LOGD(TAG, "Enabling RTCWDT(%d ms)", CONFIG_BOOTLOADER_WDT_TIME_MS);
|
||||
rtc_wdt_protect_off();
|
||||
rtc_wdt_disable();
|
||||
rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_3_2us);
|
||||
rtc_wdt_set_length_of_reset_signal(RTC_WDT_CPU_RESET_SIG, RTC_WDT_LENGTH_3_2us);
|
||||
rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_RTC);
|
||||
rtc_wdt_set_time(RTC_WDT_STAGE0, CONFIG_BOOTLOADER_WDT_TIME_MS);
|
||||
rtc_wdt_enable();
|
||||
rtc_wdt_protect_on();
|
||||
#else
|
||||
/* disable watch dog here */
|
||||
rtc_wdt_disable();
|
||||
#endif
|
||||
REG_SET_FIELD(TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY, TIMG_WDT_WKEY_VALUE);
|
||||
REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
|
||||
|
||||
#ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
|
||||
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
||||
if(spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) {
|
||||
ESP_LOGE(TAG, "SPI flash pins are overridden. \"Enable SPI flash ROM driver patched functions\" must be enabled in menuconfig");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_rom_spiflash_unlock();
|
||||
|
||||
ESP_LOGI(TAG, "Enabling RNG early entropy source...");
|
||||
bootloader_random_enable();
|
||||
|
||||
#if CONFIG_FLASHMODE_QIO || CONFIG_FLASHMODE_QOUT
|
||||
bootloader_enable_qio_mode();
|
||||
#endif
|
||||
|
||||
print_flash_info(&fhdr);
|
||||
|
||||
update_flash_config(&fhdr);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void update_flash_config(const esp_image_header_t* pfhdr)
|
||||
{
|
||||
uint32_t size;
|
||||
switch(pfhdr->spi_size) {
|
||||
case ESP_IMAGE_FLASH_SIZE_1MB:
|
||||
size = 1;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_2MB:
|
||||
size = 2;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_4MB:
|
||||
size = 4;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_8MB:
|
||||
size = 8;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_16MB:
|
||||
size = 16;
|
||||
break;
|
||||
default:
|
||||
size = 2;
|
||||
}
|
||||
Cache_Read_Disable( 0 );
|
||||
// Set flash chip size
|
||||
esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
|
||||
// TODO: set mode
|
||||
// TODO: set frequency
|
||||
Cache_Flush(0);
|
||||
Cache_Read_Enable( 0 );
|
||||
}
|
||||
|
||||
static void print_flash_info(const esp_image_header_t* phdr)
|
||||
{
|
||||
#if (BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_NOTICE)
|
||||
|
||||
ESP_LOGD(TAG, "magic %02x", phdr->magic );
|
||||
ESP_LOGD(TAG, "segments %02x", phdr->segment_count );
|
||||
ESP_LOGD(TAG, "spi_mode %02x", phdr->spi_mode );
|
||||
ESP_LOGD(TAG, "spi_speed %02x", phdr->spi_speed );
|
||||
ESP_LOGD(TAG, "spi_size %02x", phdr->spi_size );
|
||||
|
||||
const char* str;
|
||||
switch ( phdr->spi_speed ) {
|
||||
case ESP_IMAGE_SPI_SPEED_40M:
|
||||
str = "40MHz";
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_26M:
|
||||
str = "26.7MHz";
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_20M:
|
||||
str = "20MHz";
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_80M:
|
||||
str = "80MHz";
|
||||
break;
|
||||
default:
|
||||
str = "20MHz";
|
||||
break;
|
||||
}
|
||||
ESP_LOGI(TAG, "SPI Speed : %s", str );
|
||||
|
||||
/* SPI mode could have been set to QIO during boot already,
|
||||
so test the SPI registers not the flash header */
|
||||
uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0));
|
||||
if (spi_ctrl & SPI_FREAD_QIO) {
|
||||
str = "QIO";
|
||||
} else if (spi_ctrl & SPI_FREAD_QUAD) {
|
||||
str = "QOUT";
|
||||
} else if (spi_ctrl & SPI_FREAD_DIO) {
|
||||
str = "DIO";
|
||||
} else if (spi_ctrl & SPI_FREAD_DUAL) {
|
||||
str = "DOUT";
|
||||
} else if (spi_ctrl & SPI_FASTRD_MODE) {
|
||||
str = "FAST READ";
|
||||
} else {
|
||||
str = "SLOW READ";
|
||||
}
|
||||
ESP_LOGI(TAG, "SPI Mode : %s", str );
|
||||
|
||||
switch ( phdr->spi_size ) {
|
||||
case ESP_IMAGE_FLASH_SIZE_1MB:
|
||||
str = "1MB";
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_2MB:
|
||||
str = "2MB";
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_4MB:
|
||||
str = "4MB";
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_8MB:
|
||||
str = "8MB";
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_16MB:
|
||||
str = "16MB";
|
||||
break;
|
||||
default:
|
||||
str = "2MB";
|
||||
break;
|
||||
}
|
||||
ESP_LOGI(TAG, "SPI Flash Size : %s", str );
|
||||
#endif
|
||||
}
|
||||
|
||||
static void vddsdio_configure()
|
||||
{
|
||||
#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V
|
||||
rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
|
||||
if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { // VDDSDIO regulator is enabled @ 1.8V
|
||||
cfg.drefh = 3;
|
||||
cfg.drefm = 3;
|
||||
cfg.drefl = 3;
|
||||
cfg.force = 1;
|
||||
rtc_vddsdio_set_config(cfg);
|
||||
ets_delay_us(10); // wait for regulator to become stable
|
||||
}
|
||||
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
|
||||
}
|
||||
|
||||
#define FLASH_CLK_IO 6
|
||||
#define FLASH_CS_IO 11
|
||||
#define FLASH_SPIQ_IO 7
|
||||
#define FLASH_SPID_IO 8
|
||||
#define FLASH_SPIWP_IO 10
|
||||
#define FLASH_SPIHD_IO 9
|
||||
#define FLASH_IO_MATRIX_DUMMY_40M 1
|
||||
#define FLASH_IO_MATRIX_DUMMY_80M 2
|
||||
#define FLASH_IO_DRIVE_GD_WITH_1V8PSRAM 3
|
||||
|
||||
/*
|
||||
* Bootloader reads SPI configuration from bin header, so that
|
||||
* the burning configuration can be different with compiling configuration.
|
||||
*/
|
||||
static void IRAM_ATTR flash_gpio_configure(const esp_image_header_t* pfhdr)
|
||||
{
|
||||
int spi_cache_dummy = 0;
|
||||
int drv = 2;
|
||||
switch (pfhdr->spi_mode) {
|
||||
case ESP_IMAGE_SPI_MODE_QIO:
|
||||
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_MODE_DIO:
|
||||
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN; //qio 3
|
||||
break;
|
||||
case ESP_IMAGE_SPI_MODE_QOUT:
|
||||
case ESP_IMAGE_SPI_MODE_DOUT:
|
||||
default:
|
||||
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
|
||||
break;
|
||||
}
|
||||
|
||||
/* dummy_len_plus values defined in ROM for SPI flash configuration */
|
||||
extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
||||
switch (pfhdr->spi_speed) {
|
||||
case ESP_IMAGE_SPI_SPEED_80M:
|
||||
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_80M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_80M;
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M,
|
||||
SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||
drv = 3;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_40M:
|
||||
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_40M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_40M;
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M,
|
||||
SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
|
||||
uint32_t pkg_ver = chip_ver & 0x7;
|
||||
|
||||
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
|
||||
// For ESP32D2WD the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
|
||||
// For ESP32PICOD2 the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
|
||||
// For ESP32PICOD4 the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else {
|
||||
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
||||
if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) {
|
||||
gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0);
|
||||
gpio_matrix_out(FLASH_SPIQ_IO, SPIQ_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(FLASH_SPIQ_IO, SPIQ_IN_IDX, 0);
|
||||
gpio_matrix_out(FLASH_SPID_IO, SPID_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(FLASH_SPID_IO, SPID_IN_IDX, 0);
|
||||
gpio_matrix_out(FLASH_SPIWP_IO, SPIWP_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(FLASH_SPIWP_IO, SPIWP_IN_IDX, 0);
|
||||
gpio_matrix_out(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0);
|
||||
//select pin function gpio
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
|
||||
// flash clock signal should come from IO MUX.
|
||||
// set drive ability for clock
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
|
||||
#if CONFIG_SPIRAM_TYPE_ESPPSRAM32
|
||||
uint32_t flash_id = g_rom_flashchip.device_id;
|
||||
if (flash_id == FLASH_ID_GD25LQ32C) {
|
||||
// Set drive ability for 1.8v flash in 80Mhz.
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void uart_console_configure(void)
|
||||
{
|
||||
#if CONFIG_CONSOLE_UART_NONE
|
||||
ets_install_putc1(NULL);
|
||||
ets_install_putc2(NULL);
|
||||
#else // CONFIG_CONSOLE_UART_NONE
|
||||
const int uart_num = CONFIG_CONSOLE_UART_NUM;
|
||||
|
||||
uartAttach();
|
||||
ets_install_uart_printf();
|
||||
|
||||
// Wait for UART FIFO to be empty.
|
||||
uart_tx_wait_idle(0);
|
||||
|
||||
#if CONFIG_CONSOLE_UART_CUSTOM
|
||||
// Some constants to make the following code less upper-case
|
||||
const int uart_tx_gpio = CONFIG_CONSOLE_UART_TX_GPIO;
|
||||
const int uart_rx_gpio = CONFIG_CONSOLE_UART_RX_GPIO;
|
||||
// Switch to the new UART (this just changes UART number used for
|
||||
// ets_printf in ROM code).
|
||||
uart_tx_switch(uart_num);
|
||||
// If console is attached to UART1 or if non-default pins are used,
|
||||
// need to reconfigure pins using GPIO matrix
|
||||
if (uart_num != 0 || uart_tx_gpio != 1 || uart_rx_gpio != 3) {
|
||||
// Change pin mode for GPIO1/3 from UART to GPIO
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_GPIO3);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_GPIO1);
|
||||
// Route GPIO signals to/from pins
|
||||
// (arrays should be optimized away by the compiler)
|
||||
const uint32_t tx_idx_list[3] = { U0TXD_OUT_IDX, U1TXD_OUT_IDX, U2TXD_OUT_IDX };
|
||||
const uint32_t rx_idx_list[3] = { U0RXD_IN_IDX, U1RXD_IN_IDX, U2RXD_IN_IDX };
|
||||
const uint32_t uart_reset[3] = { DPORT_UART_RST, DPORT_UART1_RST, DPORT_UART2_RST };
|
||||
const uint32_t tx_idx = tx_idx_list[uart_num];
|
||||
const uint32_t rx_idx = rx_idx_list[uart_num];
|
||||
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[uart_rx_gpio]);
|
||||
gpio_pad_pullup(uart_rx_gpio);
|
||||
|
||||
gpio_matrix_out(uart_tx_gpio, tx_idx, 0, 0);
|
||||
gpio_matrix_in(uart_rx_gpio, rx_idx, 0);
|
||||
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, uart_reset[uart_num]);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, uart_reset[uart_num]);
|
||||
}
|
||||
#endif // CONFIG_CONSOLE_UART_CUSTOM
|
||||
|
||||
// Set configured UART console baud rate
|
||||
const int uart_baud = CONFIG_CONSOLE_UART_BAUDRATE;
|
||||
uart_div_modify(uart_num, (rtc_clk_apb_freq_get() << 4) / uart_baud);
|
||||
|
||||
#endif // CONFIG_CONSOLE_UART_NONE
|
||||
}
|
||||
|
||||
static void wdt_reset_cpu0_info_enable(void)
|
||||
{
|
||||
//We do not reset core1 info here because it didn't work before cpu1 was up. So we put it into call_start_cpu1.
|
||||
DPORT_REG_SET_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_PDEBUG_ENABLE | DPORT_PRO_CPU_RECORD_ENABLE);
|
||||
DPORT_REG_CLR_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_RECORD_ENABLE);
|
||||
}
|
||||
|
||||
static void wdt_reset_info_dump(int cpu)
|
||||
{
|
||||
uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
|
||||
lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0;
|
||||
const char *cpu_name = cpu ? "APP" : "PRO";
|
||||
|
||||
if (cpu == 0) {
|
||||
stat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_STATUS_REG);
|
||||
pid = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PID_REG);
|
||||
inst = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGINST_REG);
|
||||
dstat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGSTATUS_REG);
|
||||
data = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGDATA_REG);
|
||||
pc = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGPC_REG);
|
||||
lsstat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0STAT_REG);
|
||||
lsaddr = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0ADDR_REG);
|
||||
lsdata = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0DATA_REG);
|
||||
|
||||
} else {
|
||||
stat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_STATUS_REG);
|
||||
pid = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PID_REG);
|
||||
inst = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGINST_REG);
|
||||
dstat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGSTATUS_REG);
|
||||
data = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGDATA_REG);
|
||||
pc = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGPC_REG);
|
||||
lsstat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0STAT_REG);
|
||||
lsaddr = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0ADDR_REG);
|
||||
lsdata = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0DATA_REG);
|
||||
}
|
||||
if (DPORT_RECORD_PDEBUGINST_SZ(inst) == 0 &&
|
||||
DPORT_RECORD_PDEBUGSTATUS_BBCAUSE(dstat) == DPORT_RECORD_PDEBUGSTATUS_BBCAUSE_WAITI) {
|
||||
ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%x (waiti mode)", cpu_name, pc);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%x", cpu_name, pc);
|
||||
}
|
||||
ESP_LOGD(TAG, "WDT reset info: %s CPU STATUS 0x%08x", cpu_name, stat);
|
||||
ESP_LOGD(TAG, "WDT reset info: %s CPU PID 0x%08x", cpu_name, pid);
|
||||
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGINST 0x%08x", cpu_name, inst);
|
||||
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGSTATUS 0x%08x", cpu_name, dstat);
|
||||
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGDATA 0x%08x", cpu_name, data);
|
||||
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGPC 0x%08x", cpu_name, pc);
|
||||
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0STAT 0x%08x", cpu_name, lsstat);
|
||||
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0ADDR 0x%08x", cpu_name, lsaddr);
|
||||
ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0DATA 0x%08x", cpu_name, lsdata);
|
||||
}
|
||||
|
||||
static void wdt_reset_check(void)
|
||||
{
|
||||
int wdt_rst = 0;
|
||||
RESET_REASON rst_reas[2];
|
||||
|
||||
rst_reas[0] = rtc_get_reset_reason(0);
|
||||
rst_reas[1] = rtc_get_reset_reason(1);
|
||||
if (rst_reas[0] == RTCWDT_SYS_RESET || rst_reas[0] == TG0WDT_SYS_RESET || rst_reas[0] == TG1WDT_SYS_RESET ||
|
||||
rst_reas[0] == TGWDT_CPU_RESET || rst_reas[0] == RTCWDT_CPU_RESET) {
|
||||
ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
|
||||
wdt_rst = 1;
|
||||
}
|
||||
if (rst_reas[1] == RTCWDT_SYS_RESET || rst_reas[1] == TG0WDT_SYS_RESET || rst_reas[1] == TG1WDT_SYS_RESET ||
|
||||
rst_reas[1] == TGWDT_CPU_RESET || rst_reas[1] == RTCWDT_CPU_RESET) {
|
||||
ESP_LOGW(TAG, "APP CPU has been reset by WDT.");
|
||||
wdt_rst = 1;
|
||||
}
|
||||
if (wdt_rst) {
|
||||
// if reset by WDT dump info from trace port
|
||||
wdt_reset_info_dump(0);
|
||||
wdt_reset_info_dump(1);
|
||||
}
|
||||
wdt_reset_cpu0_info_enable();
|
||||
}
|
||||
|
||||
void __assert_func(const char *file, int line, const char *func, const char *expr)
|
||||
{
|
||||
ESP_LOGE(TAG, "Assert failed in %s, %s:%d (%s)", func, file, line, expr);
|
||||
while(1) {}
|
||||
}
|
||||
|
||||
void abort()
|
||||
{
|
||||
#if !CONFIG_ESP32_PANIC_SILENT_REBOOT
|
||||
ets_printf("abort() was called at PC 0x%08x\r\n", (intptr_t)__builtin_return_address(0) - 3);
|
||||
#endif
|
||||
if (esp_cpu_in_ocd_debug_mode()) {
|
||||
__asm__ ("break 0,0");
|
||||
}
|
||||
while(1) {}
|
||||
}
|
||||
@@ -23,23 +23,19 @@
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
#include "esp_system.h"
|
||||
#endif
|
||||
|
||||
void bootloader_fill_random(void *buffer, size_t length)
|
||||
{
|
||||
return esp_fill_random(buffer, length);
|
||||
}
|
||||
|
||||
#else
|
||||
void bootloader_fill_random(void *buffer, size_t length)
|
||||
{
|
||||
uint8_t *buffer_bytes = (uint8_t *)buffer;
|
||||
uint32_t random;
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
uint32_t start, now;
|
||||
|
||||
assert(buffer != NULL);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (i == 0 || i % 4 == 0) { /* redundant check is for a compiler warning */
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
/* in bootloader with ADC feeding HWRNG, we accumulate 1
|
||||
bit of entropy per 40 APB cycles (==80 CPU cycles.)
|
||||
|
||||
@@ -53,12 +49,14 @@ void bootloader_fill_random(void *buffer, size_t length)
|
||||
random ^= REG_READ(WDEV_RND_REG);
|
||||
RSR(CCOUNT, now);
|
||||
} while(now - start < 80*32*2); /* extra factor of 2 is precautionary */
|
||||
#else
|
||||
random = esp_random();
|
||||
#endif
|
||||
}
|
||||
|
||||
buffer_bytes[i] = random >> ((i % 4) * 8);
|
||||
}
|
||||
}
|
||||
#endif // BOOTLOADER_BUILD
|
||||
|
||||
void bootloader_random_enable(void)
|
||||
{
|
||||
|
||||
@@ -28,10 +28,7 @@ bootloader_sha256_handle_t bootloader_sha256_start()
|
||||
return NULL;
|
||||
}
|
||||
mbedtls_sha256_init(ctx);
|
||||
int ret = mbedtls_sha256_starts_ret(ctx, false);
|
||||
if (ret != 0) {
|
||||
return NULL;
|
||||
}
|
||||
mbedtls_sha256_starts(ctx, false);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@@ -39,8 +36,7 @@ void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data,
|
||||
{
|
||||
assert(handle != NULL);
|
||||
mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)handle;
|
||||
int ret = mbedtls_sha256_update_ret(ctx, data, data_len);
|
||||
assert(ret == 0);
|
||||
mbedtls_sha256_update(ctx, data, data_len);
|
||||
}
|
||||
|
||||
void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest)
|
||||
@@ -48,8 +44,7 @@ void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest
|
||||
assert(handle != NULL);
|
||||
mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)handle;
|
||||
if (digest != NULL) {
|
||||
int ret = mbedtls_sha256_finish_ret(ctx, digest);
|
||||
assert(ret == 0);
|
||||
mbedtls_sha256_finish(ctx, digest);
|
||||
}
|
||||
mbedtls_sha256_free(ctx);
|
||||
free(handle);
|
||||
@@ -169,21 +164,3 @@ void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len)
|
||||
{
|
||||
if (out_str == NULL || in_array_hex == NULL || len == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
for (int i = 0; i < len; i++) {
|
||||
for (int shift = 0; shift < 2; shift++) {
|
||||
uint8_t nibble = (in_array_hex[i] >> (shift ? 0 : 4)) & 0x0F;
|
||||
if (nibble < 10) {
|
||||
out_str[i*2+shift] = '0' + nibble;
|
||||
} else {
|
||||
out_str[i*2+shift] = 'a' + nibble - 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -1,498 +0,0 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "rom/cache.h"
|
||||
#include "rom/efuse.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/crc.h"
|
||||
#include "rom/rtc.h"
|
||||
#include "rom/uart.h"
|
||||
#include "rom/gpio.h"
|
||||
#include "rom/secure_boot.h"
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_random.h"
|
||||
#include "bootloader_config.h"
|
||||
#include "bootloader_common.h"
|
||||
#include "bootloader_utility.h"
|
||||
#include "bootloader_sha.h"
|
||||
|
||||
static const char* TAG = "boot";
|
||||
|
||||
/* Reduce literal size for some generic string literals */
|
||||
#define MAP_ERR_MSG "Image contains multiple %s segments. Only the last one will be mapped."
|
||||
|
||||
static void load_image(const esp_image_metadata_t* image_data);
|
||||
static void unpack_load_app(const esp_image_metadata_t *data);
|
||||
static void set_cache_and_start_app(uint32_t drom_addr,
|
||||
uint32_t drom_load_addr,
|
||||
uint32_t drom_size,
|
||||
uint32_t irom_addr,
|
||||
uint32_t irom_load_addr,
|
||||
uint32_t irom_size,
|
||||
uint32_t entry_addr);
|
||||
|
||||
bool bootloader_utility_load_partition_table(bootloader_state_t* bs)
|
||||
{
|
||||
const esp_partition_info_t *partitions;
|
||||
const char *partition_usage;
|
||||
esp_err_t err;
|
||||
int num_partitions;
|
||||
|
||||
partitions = bootloader_mmap(ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN);
|
||||
if (!partitions) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN);
|
||||
return false;
|
||||
}
|
||||
ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_OFFSET, (intptr_t)partitions);
|
||||
|
||||
err = esp_partition_table_verify(partitions, true, &num_partitions);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to verify partition table");
|
||||
return false;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Partition Table:");
|
||||
ESP_LOGI(TAG, "## Label Usage Type ST Offset Length");
|
||||
|
||||
for(int i = 0; i < num_partitions; i++) {
|
||||
const esp_partition_info_t *partition = &partitions[i];
|
||||
ESP_LOGD(TAG, "load partition table entry 0x%x", (intptr_t)partition);
|
||||
ESP_LOGD(TAG, "type=%x subtype=%x", partition->type, partition->subtype);
|
||||
partition_usage = "unknown";
|
||||
|
||||
/* valid partition table */
|
||||
switch(partition->type) {
|
||||
case PART_TYPE_APP: /* app partition */
|
||||
switch(partition->subtype) {
|
||||
case PART_SUBTYPE_FACTORY: /* factory binary */
|
||||
bs->factory = partition->pos;
|
||||
partition_usage = "factory app";
|
||||
break;
|
||||
case PART_SUBTYPE_TEST: /* test binary */
|
||||
bs->test = partition->pos;
|
||||
partition_usage = "test app";
|
||||
break;
|
||||
default:
|
||||
/* OTA binary */
|
||||
if ((partition->subtype & ~PART_SUBTYPE_OTA_MASK) == PART_SUBTYPE_OTA_FLAG) {
|
||||
bs->ota[partition->subtype & PART_SUBTYPE_OTA_MASK] = partition->pos;
|
||||
++bs->app_count;
|
||||
partition_usage = "OTA app";
|
||||
}
|
||||
else {
|
||||
partition_usage = "Unknown app";
|
||||
}
|
||||
break;
|
||||
}
|
||||
break; /* PART_TYPE_APP */
|
||||
case PART_TYPE_DATA: /* data partition */
|
||||
switch(partition->subtype) {
|
||||
case PART_SUBTYPE_DATA_OTA: /* ota data */
|
||||
bs->ota_info = partition->pos;
|
||||
partition_usage = "OTA data";
|
||||
break;
|
||||
case PART_SUBTYPE_DATA_RF:
|
||||
partition_usage = "RF data";
|
||||
break;
|
||||
case PART_SUBTYPE_DATA_WIFI:
|
||||
partition_usage = "WiFi data";
|
||||
break;
|
||||
case PART_SUBTYPE_DATA_NVS_KEYS:
|
||||
partition_usage = "NVS keys";
|
||||
break;
|
||||
default:
|
||||
partition_usage = "Unknown data";
|
||||
break;
|
||||
}
|
||||
break; /* PARTITION_USAGE_DATA */
|
||||
default: /* other partition type */
|
||||
break;
|
||||
}
|
||||
|
||||
/* print partition type info */
|
||||
ESP_LOGI(TAG, "%2d %-16s %-16s %02x %02x %08x %08x", i, partition->label, partition_usage,
|
||||
partition->type, partition->subtype,
|
||||
partition->pos.offset, partition->pos.size);
|
||||
}
|
||||
|
||||
bootloader_munmap(partitions);
|
||||
|
||||
ESP_LOGI(TAG,"End of partition table");
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Given a partition index, return the partition position data from the bootloader_state_t structure */
|
||||
static esp_partition_pos_t index_to_partition(const bootloader_state_t *bs, int index)
|
||||
{
|
||||
if (index == FACTORY_INDEX) {
|
||||
return bs->factory;
|
||||
}
|
||||
|
||||
if (index == TEST_APP_INDEX) {
|
||||
return bs->test;
|
||||
}
|
||||
|
||||
if (index >= 0 && index < MAX_OTA_SLOTS && index < bs->app_count) {
|
||||
return bs->ota[index];
|
||||
}
|
||||
|
||||
esp_partition_pos_t invalid = { 0 };
|
||||
return invalid;
|
||||
}
|
||||
|
||||
static void log_invalid_app_partition(int index)
|
||||
{
|
||||
const char *not_bootable = " is not bootable"; /* save a few string literal bytes */
|
||||
switch(index) {
|
||||
case FACTORY_INDEX:
|
||||
ESP_LOGE(TAG, "Factory app partition%s", not_bootable);
|
||||
break;
|
||||
case TEST_APP_INDEX:
|
||||
ESP_LOGE(TAG, "Factory test app partition%s", not_bootable);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "OTA app partition slot %d%s", index, not_bootable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs)
|
||||
{
|
||||
esp_ota_select_entry_t sa,sb;
|
||||
const esp_ota_select_entry_t *ota_select_map;
|
||||
|
||||
if (bs->ota_info.offset != 0) {
|
||||
// partition table has OTA data partition
|
||||
if (bs->ota_info.size < 2 * SPI_SEC_SIZE) {
|
||||
ESP_LOGE(TAG, "ota_info partition size %d is too small (minimum %d bytes)", bs->ota_info.size, sizeof(esp_ota_select_entry_t));
|
||||
return INVALID_INDEX; // can't proceed
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "OTA data offset 0x%x", bs->ota_info.offset);
|
||||
ota_select_map = bootloader_mmap(bs->ota_info.offset, bs->ota_info.size);
|
||||
if (!ota_select_map) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", bs->ota_info.offset, bs->ota_info.size);
|
||||
return INVALID_INDEX; // can't proceed
|
||||
}
|
||||
memcpy(&sa, ota_select_map, sizeof(esp_ota_select_entry_t));
|
||||
memcpy(&sb, (uint8_t *)ota_select_map + SPI_SEC_SIZE, sizeof(esp_ota_select_entry_t));
|
||||
bootloader_munmap(ota_select_map);
|
||||
|
||||
ESP_LOGD(TAG, "OTA sequence values A 0x%08x B 0x%08x", sa.ota_seq, sb.ota_seq);
|
||||
if ((sa.ota_seq == UINT32_MAX && sb.ota_seq == UINT32_MAX) || (bs->app_count == 0)) {
|
||||
ESP_LOGD(TAG, "OTA sequence numbers both empty (all-0xFF) or partition table does not have bootable ota_apps (app_count=%d)", bs->app_count);
|
||||
if (bs->factory.offset != 0) {
|
||||
ESP_LOGI(TAG, "Defaulting to factory image");
|
||||
return FACTORY_INDEX;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "No factory image, trying OTA 0");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
bool ota_valid = false;
|
||||
const char *ota_msg;
|
||||
int ota_seq; // Raw OTA sequence number. May be more than # of OTA slots
|
||||
if(bootloader_common_ota_select_valid(&sa) && bootloader_common_ota_select_valid(&sb)) {
|
||||
ota_valid = true;
|
||||
ota_msg = "Both OTA values";
|
||||
ota_seq = MAX(sa.ota_seq, sb.ota_seq) - 1;
|
||||
} else if(bootloader_common_ota_select_valid(&sa)) {
|
||||
ota_valid = true;
|
||||
ota_msg = "Only OTA sequence A is";
|
||||
ota_seq = sa.ota_seq - 1;
|
||||
} else if(bootloader_common_ota_select_valid(&sb)) {
|
||||
ota_valid = true;
|
||||
ota_msg = "Only OTA sequence B is";
|
||||
ota_seq = sb.ota_seq - 1;
|
||||
}
|
||||
|
||||
if (ota_valid) {
|
||||
int ota_slot = ota_seq % bs->app_count; // Actual OTA partition selection
|
||||
ESP_LOGD(TAG, "%s valid. Mapping seq %d -> OTA slot %d", ota_msg, ota_seq, ota_slot);
|
||||
return ota_slot;
|
||||
} else if (bs->factory.offset != 0) {
|
||||
ESP_LOGE(TAG, "ota data partition invalid, falling back to factory");
|
||||
return FACTORY_INDEX;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "ota data partition invalid and no factory, will try all partitions");
|
||||
return FACTORY_INDEX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise, start from factory app partition and let the search logic
|
||||
// proceed from there
|
||||
return FACTORY_INDEX;
|
||||
}
|
||||
|
||||
/* Return true if a partition has a valid app image that was successfully loaded */
|
||||
static bool try_load_partition(const esp_partition_pos_t *partition, esp_image_metadata_t *data)
|
||||
{
|
||||
if (partition->size == 0) {
|
||||
ESP_LOGD(TAG, "Can't boot from zero-length partition");
|
||||
return false;
|
||||
}
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
if (bootloader_load_image(partition, data) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Loaded app from partition at offset 0x%x",
|
||||
partition->offset);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#define TRY_LOG_FORMAT "Trying partition index %d offs 0x%x size 0x%x"
|
||||
|
||||
void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index)
|
||||
{
|
||||
int index = start_index;
|
||||
esp_partition_pos_t part;
|
||||
esp_image_metadata_t image_data;
|
||||
|
||||
if(start_index == TEST_APP_INDEX) {
|
||||
if (try_load_partition(&bs->test, &image_data)) {
|
||||
load_image(&image_data);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "No bootable test partition in the partition table");
|
||||
bootloader_reset();
|
||||
}
|
||||
}
|
||||
|
||||
/* work backwards from start_index, down to the factory app */
|
||||
for(index = start_index; index >= FACTORY_INDEX; index--) {
|
||||
part = index_to_partition(bs, index);
|
||||
if (part.size == 0) {
|
||||
continue;
|
||||
}
|
||||
ESP_LOGD(TAG, TRY_LOG_FORMAT, index, part.offset, part.size);
|
||||
if (try_load_partition(&part, &image_data)) {
|
||||
load_image(&image_data);
|
||||
}
|
||||
log_invalid_app_partition(index);
|
||||
}
|
||||
|
||||
/* failing that work forwards from start_index, try valid OTA slots */
|
||||
for(index = start_index + 1; index < bs->app_count; index++) {
|
||||
part = index_to_partition(bs, index);
|
||||
if (part.size == 0) {
|
||||
continue;
|
||||
}
|
||||
ESP_LOGD(TAG, TRY_LOG_FORMAT, index, part.offset, part.size);
|
||||
if (try_load_partition(&part, &image_data)) {
|
||||
load_image(&image_data);
|
||||
}
|
||||
log_invalid_app_partition(index);
|
||||
}
|
||||
|
||||
if (try_load_partition(&bs->test, &image_data)) {
|
||||
ESP_LOGW(TAG, "Falling back to test app as only bootable partition");
|
||||
load_image(&image_data);
|
||||
}
|
||||
|
||||
ESP_LOGE(TAG, "No bootable app partitions in the partition table");
|
||||
bzero(&image_data, sizeof(esp_image_metadata_t));
|
||||
bootloader_reset();
|
||||
}
|
||||
|
||||
// Copy loaded segments to RAM, set up caches for mapped segments, and start application.
|
||||
static void load_image(const esp_image_metadata_t* image_data)
|
||||
{
|
||||
#if defined(CONFIG_SECURE_BOOT_ENABLED) || defined(CONFIG_FLASH_ENCRYPTION_ENABLED)
|
||||
esp_err_t err;
|
||||
#endif
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
/* Generate secure digest from this bootloader to protect future
|
||||
modifications */
|
||||
ESP_LOGI(TAG, "Checking secure boot...");
|
||||
err = esp_secure_boot_permanently_enable();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Bootloader digest generation failed (%d). SECURE BOOT IS NOT ENABLED.", err);
|
||||
/* Allow booting to continue, as the failure is probably
|
||||
due to user-configured EFUSEs for testing...
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED
|
||||
/* encrypt flash */
|
||||
ESP_LOGI(TAG, "Checking flash encryption...");
|
||||
bool flash_encryption_enabled = esp_flash_encryption_enabled();
|
||||
err = esp_flash_encrypt_check_and_update();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Flash encryption check failed (%d).", err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!flash_encryption_enabled && esp_flash_encryption_enabled()) {
|
||||
/* Flash encryption was just enabled for the first time,
|
||||
so issue a system reset to ensure flash encryption
|
||||
cache resets properly */
|
||||
ESP_LOGI(TAG, "Resetting with flash encryption enabled...");
|
||||
bootloader_reset();
|
||||
}
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "Disabling RNG early entropy source...");
|
||||
bootloader_random_disable();
|
||||
|
||||
// copy loaded segments to RAM, set up caches for mapped segments, and start application
|
||||
unpack_load_app(image_data);
|
||||
}
|
||||
|
||||
static void unpack_load_app(const esp_image_metadata_t* data)
|
||||
{
|
||||
uint32_t drom_addr = 0;
|
||||
uint32_t drom_load_addr = 0;
|
||||
uint32_t drom_size = 0;
|
||||
uint32_t irom_addr = 0;
|
||||
uint32_t irom_load_addr = 0;
|
||||
uint32_t irom_size = 0;
|
||||
|
||||
// Find DROM & IROM addresses, to configure cache mappings
|
||||
for (int i = 0; i < data->image.segment_count; i++) {
|
||||
const esp_image_segment_header_t *header = &data->segments[i];
|
||||
if (header->load_addr >= SOC_DROM_LOW && header->load_addr < SOC_DROM_HIGH) {
|
||||
if (drom_addr != 0) {
|
||||
ESP_LOGE(TAG, MAP_ERR_MSG, "DROM");
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Mapping segment %d as %s", i, "DROM");
|
||||
}
|
||||
drom_addr = data->segment_data[i];
|
||||
drom_load_addr = header->load_addr;
|
||||
drom_size = header->data_len;
|
||||
}
|
||||
if (header->load_addr >= SOC_IROM_LOW && header->load_addr < SOC_IROM_HIGH) {
|
||||
if (irom_addr != 0) {
|
||||
ESP_LOGE(TAG, MAP_ERR_MSG, "IROM");
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Mapping segment %d as %s", i, "IROM");
|
||||
}
|
||||
irom_addr = data->segment_data[i];
|
||||
irom_load_addr = header->load_addr;
|
||||
irom_size = header->data_len;
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "calling set_cache_and_start_app");
|
||||
set_cache_and_start_app(drom_addr,
|
||||
drom_load_addr,
|
||||
drom_size,
|
||||
irom_addr,
|
||||
irom_load_addr,
|
||||
irom_size,
|
||||
data->image.entry_addr);
|
||||
}
|
||||
|
||||
static void set_cache_and_start_app(
|
||||
uint32_t drom_addr,
|
||||
uint32_t drom_load_addr,
|
||||
uint32_t drom_size,
|
||||
uint32_t irom_addr,
|
||||
uint32_t irom_load_addr,
|
||||
uint32_t irom_size,
|
||||
uint32_t entry_addr)
|
||||
{
|
||||
int rc;
|
||||
ESP_LOGD(TAG, "configure drom and irom and start");
|
||||
Cache_Read_Disable( 0 );
|
||||
Cache_Flush( 0 );
|
||||
|
||||
/* Clear the MMU entries that are already set up,
|
||||
so the new app only has the mappings it creates.
|
||||
*/
|
||||
for (int i = 0; i < DPORT_FLASH_MMU_TABLE_SIZE; i++) {
|
||||
DPORT_PRO_FLASH_MMU_TABLE[i] = DPORT_FLASH_MMU_TABLE_INVALID_VAL;
|
||||
}
|
||||
|
||||
uint32_t drom_load_addr_aligned = drom_load_addr & MMU_FLASH_MASK;
|
||||
uint32_t drom_page_count = bootloader_cache_pages_to_map(drom_size, drom_load_addr);
|
||||
ESP_LOGV(TAG, "d mmu set paddr=%08x vaddr=%08x size=%d n=%d",
|
||||
drom_addr & MMU_FLASH_MASK, drom_load_addr_aligned, drom_size, drom_page_count);
|
||||
rc = cache_flash_mmu_set(0, 0, drom_load_addr_aligned, drom_addr & MMU_FLASH_MASK, 64, drom_page_count);
|
||||
ESP_LOGV(TAG, "rc=%d", rc);
|
||||
rc = cache_flash_mmu_set(1, 0, drom_load_addr_aligned, drom_addr & MMU_FLASH_MASK, 64, drom_page_count);
|
||||
ESP_LOGV(TAG, "rc=%d", rc);
|
||||
|
||||
uint32_t irom_load_addr_aligned = irom_load_addr & MMU_FLASH_MASK;
|
||||
uint32_t irom_page_count = bootloader_cache_pages_to_map(irom_size, irom_load_addr);
|
||||
ESP_LOGV(TAG, "i mmu set paddr=%08x vaddr=%08x size=%d n=%d",
|
||||
irom_addr & MMU_FLASH_MASK, irom_load_addr_aligned, irom_size, irom_page_count);
|
||||
rc = cache_flash_mmu_set(0, 0, irom_load_addr_aligned, irom_addr & MMU_FLASH_MASK, 64, irom_page_count);
|
||||
ESP_LOGV(TAG, "rc=%d", rc);
|
||||
rc = cache_flash_mmu_set(1, 0, irom_load_addr_aligned, irom_addr & MMU_FLASH_MASK, 64, irom_page_count);
|
||||
ESP_LOGV(TAG, "rc=%d", rc);
|
||||
|
||||
DPORT_REG_CLR_BIT( DPORT_PRO_CACHE_CTRL1_REG,
|
||||
(DPORT_PRO_CACHE_MASK_IRAM0) | (DPORT_PRO_CACHE_MASK_IRAM1 & 0) |
|
||||
(DPORT_PRO_CACHE_MASK_IROM0 & 0) | DPORT_PRO_CACHE_MASK_DROM0 |
|
||||
DPORT_PRO_CACHE_MASK_DRAM1 );
|
||||
|
||||
DPORT_REG_CLR_BIT( DPORT_APP_CACHE_CTRL1_REG,
|
||||
(DPORT_APP_CACHE_MASK_IRAM0) | (DPORT_APP_CACHE_MASK_IRAM1 & 0) |
|
||||
(DPORT_APP_CACHE_MASK_IROM0 & 0) | DPORT_APP_CACHE_MASK_DROM0 |
|
||||
DPORT_APP_CACHE_MASK_DRAM1 );
|
||||
|
||||
Cache_Read_Enable( 0 );
|
||||
|
||||
// Application will need to do Cache_Flush(1) and Cache_Read_Enable(1)
|
||||
|
||||
ESP_LOGD(TAG, "start: 0x%08x", entry_addr);
|
||||
typedef void (*entry_t)(void) __attribute__((noreturn));
|
||||
entry_t entry = ((entry_t) entry_addr);
|
||||
|
||||
// TODO: we have used quite a bit of stack at this point.
|
||||
// use "movsp" instruction to reset stack back to where ROM stack starts.
|
||||
(*entry)();
|
||||
}
|
||||
|
||||
|
||||
void bootloader_reset(void)
|
||||
{
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
uart_tx_flush(0); /* Ensure any buffered log output is displayed */
|
||||
uart_tx_flush(1);
|
||||
ets_delay_us(1000); /* Allow last byte to leave FIFO */
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
|
||||
while (1) { } /* This line will never be reached, used to keep gcc happy */
|
||||
#else
|
||||
abort(); /* This function should really not be called from application code */
|
||||
#endif
|
||||
}
|
||||
@@ -13,8 +13,6 @@
|
||||
// limitations under the License.
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_log.h"
|
||||
#include <string.h>
|
||||
#include "bootloader_random.h"
|
||||
|
||||
#define EFUSE_CONF_WRITE 0x5A5A /* efuse_pgm_op_ena, force no rd/wr disable */
|
||||
#define EFUSE_CONF_READ 0x5AA5 /* efuse_read_op_ena, release force */
|
||||
@@ -60,55 +58,3 @@ void esp_efuse_disable_basic_rom_console(void)
|
||||
esp_efuse_burn_new_values();
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_apply_34_encoding(const uint8_t *in_bytes, uint32_t *out_words, size_t in_bytes_len)
|
||||
{
|
||||
if (in_bytes == NULL || out_words == NULL || in_bytes_len % 6 != 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
while (in_bytes_len > 0) {
|
||||
uint8_t out[8];
|
||||
uint8_t xor = 0;
|
||||
uint8_t mul = 0;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
xor ^= in_bytes[i];
|
||||
mul += (i + 1) * __builtin_popcount(in_bytes[i]);
|
||||
}
|
||||
|
||||
memcpy(out, in_bytes, 6); // Data bytes
|
||||
out[6] = xor;
|
||||
out[7] = mul;
|
||||
|
||||
memcpy(out_words, out, 8);
|
||||
|
||||
in_bytes_len -= 6;
|
||||
in_bytes += 6;
|
||||
out_words += 2;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_efuse_write_random_key(uint32_t blk_wdata0_reg)
|
||||
{
|
||||
uint32_t buf[8];
|
||||
uint8_t raw[24];
|
||||
uint32_t coding_scheme = REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_CODING_SCHEME_M;
|
||||
|
||||
if (coding_scheme == EFUSE_CODING_SCHEME_VAL_NONE) {
|
||||
bootloader_fill_random(buf, sizeof(buf));
|
||||
} else { // 3/4 Coding Scheme
|
||||
bootloader_fill_random(raw, sizeof(raw));
|
||||
esp_err_t r = esp_efuse_apply_34_encoding(raw, buf, sizeof(raw));
|
||||
assert(r == ESP_OK);
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "Writing random values to address 0x%08x", blk_wdata0_reg);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ESP_LOGV(TAG, "EFUSE_BLKx_WDATA%d_REG = 0x%08x", i, buf[i]);
|
||||
REG_WRITE(blk_wdata0_reg + 4*i, buf[i]);
|
||||
}
|
||||
bzero(buf, sizeof(buf));
|
||||
bzero(raw, sizeof(raw));
|
||||
}
|
||||
|
||||
@@ -23,25 +23,10 @@
|
||||
#include <bootloader_flash.h>
|
||||
#include <bootloader_random.h>
|
||||
#include <bootloader_sha.h>
|
||||
#include "bootloader_util.h"
|
||||
|
||||
/* Checking signatures as part of verifying images is necessary:
|
||||
- Always if secure boot is enabled
|
||||
- Differently in bootloader and/or app, depending on kconfig
|
||||
*/
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
#ifdef CONFIG_SECURE_SIGNED_ON_BOOT
|
||||
#define SECURE_BOOT_CHECK_SIGNATURE
|
||||
#endif
|
||||
#else /* !BOOTLOADER_BUILD */
|
||||
#ifdef CONFIG_SECURE_SIGNED_ON_UPDATE
|
||||
#define SECURE_BOOT_CHECK_SIGNATURE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static const char *TAG = "esp_image";
|
||||
|
||||
#define HASH_LEN ESP_IMAGE_HASH_LEN
|
||||
#define HASH_LEN 32 /* SHA-256 digest length */
|
||||
|
||||
#define SIXTEEN_MB 0x1000000
|
||||
#define ESP_ROM_CHECKSUM_INITIAL 0xEF
|
||||
@@ -57,10 +42,6 @@ static const char *TAG = "esp_image";
|
||||
(Means loaded code isn't executable until after the secure boot check.)
|
||||
*/
|
||||
static uint32_t ram_obfs_value[2];
|
||||
|
||||
/* Range of IRAM used by the loader, defined in ld script */
|
||||
extern int _loader_text_start;
|
||||
extern int _loader_text_end;
|
||||
#endif
|
||||
|
||||
/* Return true if load_addr is an address the bootloader should load into */
|
||||
@@ -94,7 +75,7 @@ static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t
|
||||
static esp_err_t __attribute__((unused)) verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data);
|
||||
static esp_err_t __attribute__((unused)) verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data);
|
||||
|
||||
static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
|
||||
esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
|
||||
{
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
bool do_load = (mode == ESP_IMAGE_LOAD);
|
||||
@@ -126,7 +107,7 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
||||
}
|
||||
|
||||
// Calculate SHA-256 of image if secure boot is on, or if image has a hash appended
|
||||
#ifdef SECURE_BOOT_CHECK_SIGNATURE
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
if (1) {
|
||||
#else
|
||||
if (data->image.hash_appended) {
|
||||
@@ -147,7 +128,7 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
||||
|
||||
err = verify_image_header(data->start_addr, &data->image, silent);
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (data->image.segment_count > ESP_IMAGE_MAX_SEGMENTS) {
|
||||
@@ -176,12 +157,11 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
||||
|
||||
data->image_len = end_addr - data->start_addr;
|
||||
ESP_LOGV(TAG, "image start 0x%08x end of last section 0x%08x", data->start_addr, end_addr);
|
||||
if (!esp_cpu_in_ocd_debug_mode()) {
|
||||
err = verify_checksum(sha_handle, checksum_word, data);
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
err = verify_checksum(sha_handle, checksum_word, data);
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (data->image_len > part->size) {
|
||||
FAIL_LOAD("Image length %d doesn't fit in partition length %d", data->image_len, part->size);
|
||||
}
|
||||
@@ -193,32 +173,21 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
||||
rewritten the header - rely on esptool.py having verified the bootloader at flashing time, instead.
|
||||
*/
|
||||
if (!is_bootloader) {
|
||||
#ifdef SECURE_BOOT_CHECK_SIGNATURE
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
// secure boot images have a signature appended
|
||||
err = verify_secure_boot_signature(sha_handle, data);
|
||||
#else
|
||||
// No secure boot, but SHA-256 can be appended for basic corruption detection
|
||||
if (sha_handle != NULL && !esp_cpu_in_ocd_debug_mode()) {
|
||||
if (sha_handle != NULL) {
|
||||
err = verify_simple_hash(sha_handle, data);
|
||||
}
|
||||
#endif // SECURE_BOOT_CHECK_SIGNATURE
|
||||
#endif // CONFIG_SECURE_BOOT_ENABLED
|
||||
} else { // is_bootloader
|
||||
// bootloader may still have a sha256 digest handle open
|
||||
if (sha_handle != NULL) {
|
||||
bootloader_sha256_finish(sha_handle, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (data->image.hash_appended) {
|
||||
const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
|
||||
if (hash == NULL) {
|
||||
err = ESP_FAIL;
|
||||
goto err;
|
||||
}
|
||||
memcpy(data->image_digest, hash, HASH_LEN);
|
||||
bootloader_munmap(hash);
|
||||
}
|
||||
|
||||
sha_handle = NULL;
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
@@ -254,22 +223,6 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data)
|
||||
{
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
return image_load(ESP_IMAGE_LOAD, part, data);
|
||||
#else
|
||||
return ESP_FAIL;
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
|
||||
{
|
||||
return image_load(mode, part, data);
|
||||
}
|
||||
|
||||
esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data) __attribute__((alias("esp_image_verify")));
|
||||
|
||||
static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
@@ -333,41 +286,18 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme
|
||||
(do_load)?"load":(is_mapping)?"map":"");
|
||||
}
|
||||
|
||||
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
/* Before loading segment, check it doesn't clobber bootloader RAM. */
|
||||
if (do_load) {
|
||||
const intptr_t load_end = load_addr + data_len;
|
||||
if (load_end <= (intptr_t) SOC_DIRAM_DRAM_HIGH) {
|
||||
/* Writing to DRAM */
|
||||
/* Before loading segment, check it doesn't clobber bootloader RAM... */
|
||||
uint32_t end_addr = load_addr + data_len;
|
||||
if (end_addr < 0x40000000) {
|
||||
intptr_t sp = (intptr_t)get_sp();
|
||||
if (load_end > sp - STACK_LOAD_HEADROOM) {
|
||||
/* Bootloader .data/.rodata/.bss is above the stack, so this
|
||||
* also checks that we aren't overwriting these segments.
|
||||
*
|
||||
* TODO: This assumes specific arrangement of sections we have
|
||||
* in the ESP32. Rewrite this in a generic way to support other
|
||||
* layouts.
|
||||
*/
|
||||
ESP_LOGE(TAG, "Segment %d end address 0x%08x too high (bootloader stack 0x%08x limit 0x%08x)",
|
||||
index, load_end, sp, sp - STACK_LOAD_HEADROOM);
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
} else {
|
||||
/* Writing to IRAM */
|
||||
const intptr_t loader_iram_start = (intptr_t) &_loader_text_start;
|
||||
const intptr_t loader_iram_end = (intptr_t) &_loader_text_end;
|
||||
|
||||
if (bootloader_util_regions_overlap(loader_iram_start, loader_iram_end,
|
||||
load_addr, load_end)) {
|
||||
ESP_LOGE(TAG, "Segment %d (0x%08x-0x%08x) overlaps bootloader IRAM (0x%08x-0x%08x)",
|
||||
index, load_addr, load_end, loader_iram_start, loader_iram_end);
|
||||
if (end_addr > sp - STACK_LOAD_HEADROOM) {
|
||||
ESP_LOGE(TAG, "Segment %d end address 0x%08x too high (bootloader stack 0x%08x liimit 0x%08x)",
|
||||
index, end_addr, sp, sp - STACK_LOAD_HEADROOM);
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // BOOTLOADER_BUILD
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
uint32_t free_page_count = spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA);
|
||||
ESP_LOGD(TAG, "free data page_count 0x%08x",free_page_count);
|
||||
@@ -496,15 +426,11 @@ static bool should_load(uint32_t load_addr)
|
||||
|
||||
if (!load_rtc_memory) {
|
||||
if (load_addr >= SOC_RTC_IRAM_LOW && load_addr < SOC_RTC_IRAM_HIGH) {
|
||||
ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x\n", load_addr);
|
||||
return false;
|
||||
}
|
||||
if (load_addr >= SOC_RTC_DRAM_LOW && load_addr < SOC_RTC_DRAM_HIGH) {
|
||||
ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x\n", load_addr);
|
||||
ESP_LOGD(TAG, "Skipping RTC code segment at 0x%08x\n", load_addr);
|
||||
return false;
|
||||
}
|
||||
if (load_addr >= SOC_RTC_DATA_LOW && load_addr < SOC_RTC_DATA_HIGH) {
|
||||
ESP_LOGD(TAG, "Skipping RTC slow memory segment at 0x%08x\n", load_addr);
|
||||
ESP_LOGD(TAG, "Skipping RTC data segment at 0x%08x\n", load_addr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -515,28 +441,19 @@ static bool should_load(uint32_t load_addr)
|
||||
esp_err_t esp_image_verify_bootloader(uint32_t *length)
|
||||
{
|
||||
esp_image_metadata_t data;
|
||||
esp_err_t err = esp_image_verify_bootloader_data(&data);
|
||||
const esp_partition_pos_t bootloader_part = {
|
||||
.offset = ESP_BOOTLOADER_OFFSET,
|
||||
.size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET,
|
||||
};
|
||||
esp_err_t err = esp_image_load(ESP_IMAGE_VERIFY,
|
||||
&bootloader_part,
|
||||
&data);
|
||||
if (length != NULL) {
|
||||
*length = (err == ESP_OK) ? data.image_len : 0;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data)
|
||||
{
|
||||
if (data == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
const esp_partition_pos_t bootloader_part = {
|
||||
.offset = ESP_BOOTLOADER_OFFSET,
|
||||
.size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET,
|
||||
};
|
||||
return esp_image_verify(ESP_IMAGE_VERIFY,
|
||||
&bootloader_part,
|
||||
data);
|
||||
}
|
||||
|
||||
|
||||
static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data)
|
||||
{
|
||||
uint32_t unpadded_length = data->image_len;
|
||||
@@ -574,8 +491,6 @@ static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_han
|
||||
{
|
||||
uint8_t image_hash[HASH_LEN] = { 0 };
|
||||
|
||||
ESP_LOGI(TAG, "Verifying image signature...");
|
||||
|
||||
// For secure boot, we calculate the signature hash over the whole file, which includes any "simple" hash
|
||||
// appended to the image for corruption detection
|
||||
if (data->image.hash_appended) {
|
||||
@@ -640,9 +555,18 @@ static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_i
|
||||
static void debug_log_hash(const uint8_t *image_hash, const char *label)
|
||||
{
|
||||
#if BOOT_LOG_LEVEL >= LOG_LEVEL_DEBUG
|
||||
char hash_print[HASH_LEN * 2 + 1];
|
||||
hash_print[HASH_LEN * 2] = 0;
|
||||
bootloader_sha256_hex_to_str(hash_print, image_hash, HASH_LEN);
|
||||
ESP_LOGD(TAG, "%s: %s", label, hash_print);
|
||||
char hash_print[sizeof(image_hash)*2 + 1];
|
||||
hash_print[sizeof(image_hash)*2] = 0;
|
||||
for (int i = 0; i < sizeof(image_hash); i++) {
|
||||
for (int shift = 0; shift < 2; shift++) {
|
||||
uint8_t nibble = (image_hash[i] >> (shift ? 0 : 4)) & 0x0F;
|
||||
if (nibble < 10) {
|
||||
hash_print[i*2+shift] = '0' + nibble;
|
||||
} else {
|
||||
hash_print[i*2+shift] = 'a' + nibble - 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
ESP_LOGD(TAG, "%s: %s", label, hash_print);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <strings.h>
|
||||
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_random.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
@@ -23,7 +24,6 @@
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_log.h"
|
||||
#include "rom/secure_boot.h"
|
||||
#include "soc/rtc_wdt.h"
|
||||
|
||||
#include "rom/cache.h"
|
||||
#include "rom/spi_flash.h" /* TODO: Remove this */
|
||||
@@ -62,12 +62,6 @@ esp_err_t esp_flash_encrypt_check_and_update(void)
|
||||
|
||||
static esp_err_t initialise_flash_encryption(void)
|
||||
{
|
||||
uint32_t coding_scheme = REG_GET_FIELD(EFUSE_BLK0_RDATA6_REG, EFUSE_CODING_SCHEME);
|
||||
if (coding_scheme != EFUSE_CODING_SCHEME_VAL_NONE && coding_scheme != EFUSE_CODING_SCHEME_VAL_34) {
|
||||
ESP_LOGE(TAG, "Unknown/unsupported CODING_SCHEME value 0x%x", coding_scheme);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Before first flash encryption pass, need to initialise key & crypto config */
|
||||
|
||||
/* Generate key */
|
||||
@@ -85,7 +79,13 @@ static esp_err_t initialise_flash_encryption(void)
|
||||
&& REG_READ(EFUSE_BLK1_RDATA6_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA7_REG) == 0) {
|
||||
ESP_LOGI(TAG, "Generating new flash encryption key...");
|
||||
esp_efuse_write_random_key(EFUSE_BLK1_WDATA0_REG);
|
||||
uint32_t buf[8];
|
||||
bootloader_fill_random(buf, sizeof(buf));
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ESP_LOGV(TAG, "EFUSE_BLK1_WDATA%d_REG = 0x%08x", i, buf[i]);
|
||||
REG_WRITE(EFUSE_BLK1_WDATA0_REG + 4*i, buf[i]);
|
||||
}
|
||||
bzero(buf, sizeof(buf));
|
||||
esp_efuse_burn_new_values();
|
||||
|
||||
ESP_LOGI(TAG, "Read & write protecting new key...");
|
||||
@@ -163,7 +163,7 @@ static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_cry
|
||||
|
||||
/* If the last flash_crypt_cnt bit is burned or write-disabled, the
|
||||
device can't re-encrypt itself. */
|
||||
if (flash_crypt_wr_dis) {
|
||||
if (flash_crypt_wr_dis || flash_crypt_cnt == 0xFF) {
|
||||
ESP_LOGE(TAG, "Cannot re-encrypt data (FLASH_CRYPT_CNT 0x%02x write disabled %d", flash_crypt_cnt, flash_crypt_wr_dis);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@@ -200,8 +200,8 @@ static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_cry
|
||||
ESP_LOGD(TAG, "All flash regions checked for encryption pass");
|
||||
|
||||
/* Set least significant 0-bit in flash_crypt_cnt */
|
||||
int ffs_inv = __builtin_ffs((~flash_crypt_cnt) & EFUSE_RD_FLASH_CRYPT_CNT);
|
||||
/* ffs_inv shouldn't be zero, as zero implies flash_crypt_cnt == EFUSE_RD_FLASH_CRYPT_CNT (0x7F) */
|
||||
int ffs_inv = __builtin_ffs((~flash_crypt_cnt) & 0xFF);
|
||||
/* ffs_inv shouldn't be zero, as zero implies flash_crypt_cnt == 0xFF */
|
||||
uint32_t new_flash_crypt_cnt = flash_crypt_cnt + (1 << (ffs_inv - 1));
|
||||
ESP_LOGD(TAG, "FLASH_CRYPT_CNT 0x%x -> 0x%x", flash_crypt_cnt, new_flash_crypt_cnt);
|
||||
REG_SET_FIELD(EFUSE_BLK0_WDATA0_REG, EFUSE_FLASH_CRYPT_CNT, new_flash_crypt_cnt);
|
||||
@@ -254,7 +254,7 @@ static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partitio
|
||||
ESP_LOGE(TAG, "Failed to read partition table data");
|
||||
return err;
|
||||
}
|
||||
if (esp_partition_table_verify(partition_table, false, num_partitions) == ESP_OK) {
|
||||
if (esp_partition_table_basic_verify(partition_table, false, num_partitions) == ESP_OK) {
|
||||
ESP_LOGD(TAG, "partition table is plaintext. Encrypting...");
|
||||
esp_err_t err = esp_flash_encrypt_region(ESP_PARTITION_TABLE_OFFSET,
|
||||
FLASH_SECTOR_SIZE);
|
||||
@@ -281,12 +281,11 @@ static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partit
|
||||
if (partition->type == PART_TYPE_APP) {
|
||||
/* check if the partition holds a valid unencrypted app */
|
||||
esp_image_metadata_t data_ignored;
|
||||
err = esp_image_verify(ESP_IMAGE_VERIFY,
|
||||
err = esp_image_load(ESP_IMAGE_VERIFY,
|
||||
&partition->pos,
|
||||
&data_ignored);
|
||||
should_encrypt = (err == ESP_OK);
|
||||
} else if ((partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_OTA)
|
||||
|| (partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_NVS_KEYS)) {
|
||||
} else if (partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_OTA) {
|
||||
/* check if we have ota data partition and the partition should be encrypted unconditionally */
|
||||
should_encrypt = true;
|
||||
}
|
||||
@@ -318,7 +317,6 @@ esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length)
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < data_length; i += FLASH_SECTOR_SIZE) {
|
||||
rtc_wdt_feed();
|
||||
uint32_t sec_start = i + src_addr;
|
||||
err = bootloader_flash_read(sec_start, buf, FLASH_SECTOR_SIZE, false);
|
||||
if (err != ESP_OK) {
|
||||
@@ -339,13 +337,3 @@ esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length)
|
||||
ESP_LOGE(TAG, "flash operation failed: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
void esp_flash_write_protect_crypt_cnt()
|
||||
{
|
||||
uint32_t efuse_blk0 = REG_READ(EFUSE_BLK0_RDATA0_REG);
|
||||
bool flash_crypt_wr_dis = efuse_blk0 & EFUSE_WR_DIS_FLASH_CRYPT_CNT;
|
||||
if(!flash_crypt_wr_dis) {
|
||||
REG_WRITE(EFUSE_BLK0_WDATA0_REG, EFUSE_WR_DIS_FLASH_CRYPT_CNT);
|
||||
esp_efuse_burn_new_values();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,76 +11,50 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <string.h>
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "esp_log.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/md5_hash.h"
|
||||
#include "esp_flash_data_types.h"
|
||||
|
||||
static const char *TAG = "flash_parts";
|
||||
|
||||
esp_err_t esp_partition_table_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions)
|
||||
esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions)
|
||||
{
|
||||
int md5_found = 0;
|
||||
int num_parts;
|
||||
uint32_t chip_size = g_rom_flashchip.chip_size;
|
||||
*num_partitions = 0;
|
||||
int num_parts;
|
||||
uint32_t chip_size = g_rom_flashchip.chip_size;
|
||||
*num_partitions = 0;
|
||||
|
||||
for (num_parts = 0; num_parts < ESP_PARTITION_TABLE_MAX_ENTRIES; num_parts++) {
|
||||
const esp_partition_info_t *part = &partition_table[num_parts];
|
||||
for(num_parts = 0; num_parts < ESP_PARTITION_TABLE_MAX_ENTRIES; num_parts++) {
|
||||
const esp_partition_info_t *part = &partition_table[num_parts];
|
||||
|
||||
if (part->magic == ESP_PARTITION_MAGIC) {
|
||||
const esp_partition_pos_t *pos = &part->pos;
|
||||
if (pos->offset > chip_size || pos->offset + pos->size > chip_size) {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "partition %d invalid - offset 0x%x size 0x%x exceeds flash chip size 0x%x",
|
||||
num_parts, pos->offset, pos->size, chip_size);
|
||||
}
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
} else if (part->magic == ESP_PARTITION_MAGIC_MD5) {
|
||||
if (md5_found) {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "Only one MD5 checksum is allowed");
|
||||
}
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (part->magic == 0xFFFF
|
||||
&& part->type == PART_TYPE_END
|
||||
&& part->subtype == PART_SUBTYPE_END) {
|
||||
/* TODO: check md5 */
|
||||
ESP_LOGD(TAG, "partition table verified, %d entries", num_parts);
|
||||
*num_partitions = num_parts;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
struct MD5Context context;
|
||||
unsigned char digest[16];
|
||||
MD5Init(&context);
|
||||
MD5Update(&context, (unsigned char *) partition_table, num_parts * sizeof(esp_partition_info_t));
|
||||
MD5Final(digest, &context);
|
||||
|
||||
unsigned char *md5sum = ((unsigned char *) part) + 16; // skip the 2B magic number and the 14B fillup bytes
|
||||
|
||||
if (memcmp(md5sum, digest, sizeof(digest)) != 0) {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "Incorrect MD5 checksum");
|
||||
}
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
//MD5 checksum matches and we continue with the next interation in
|
||||
//order to detect the end of the partition table
|
||||
md5_found = 1;
|
||||
} else if (part->magic == 0xFFFF
|
||||
&& part->type == PART_TYPE_END
|
||||
&& part->subtype == PART_SUBTYPE_END) {
|
||||
ESP_LOGD(TAG, "partition table verified, %d entries", num_parts);
|
||||
*num_partitions = num_parts - md5_found; //do not count the partition where the MD5 checksum is held
|
||||
return ESP_OK;
|
||||
} else {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "partition %d invalid magic number 0x%x", num_parts, part->magic);
|
||||
}
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
if (part->magic != ESP_PARTITION_MAGIC) {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "partition %d invalid magic number 0x%x", num_parts, part->magic);
|
||||
}
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "partition table has no terminating entry, not valid");
|
||||
const esp_partition_pos_t *pos = &part->pos;
|
||||
if (pos->offset > chip_size || pos->offset + pos->size > chip_size) {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "partition %d invalid - offset 0x%x size 0x%x exceeds flash chip size 0x%x",
|
||||
num_parts, pos->offset, pos->size, chip_size);
|
||||
}
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "partition table has no terminating entry, not valid");
|
||||
}
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ static bool secure_boot_generate(uint32_t image_len){
|
||||
const uint32_t *image;
|
||||
|
||||
/* hardware secure boot engine only takes full blocks, so round up the
|
||||
image length. The additional data should all be 0xFF (or the appended SHA, if it falls in the same block).
|
||||
image length. The additional data should all be 0xFF.
|
||||
*/
|
||||
if (image_len % sizeof(digest.iv) != 0) {
|
||||
image_len = (image_len / sizeof(digest.iv) + 1) * sizeof(digest.iv);
|
||||
@@ -104,21 +104,14 @@ static inline void burn_efuses()
|
||||
|
||||
esp_err_t esp_secure_boot_permanently_enable(void) {
|
||||
esp_err_t err;
|
||||
uint32_t image_len = 0;
|
||||
if (esp_secure_boot_enabled())
|
||||
{
|
||||
ESP_LOGI(TAG, "bootloader secure boot is already enabled, continuing..");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint32_t coding_scheme = REG_GET_FIELD(EFUSE_BLK0_RDATA6_REG, EFUSE_CODING_SCHEME);
|
||||
if (coding_scheme != EFUSE_CODING_SCHEME_VAL_NONE && coding_scheme != EFUSE_CODING_SCHEME_VAL_34) {
|
||||
ESP_LOGE(TAG, "Unknown/unsupported CODING_SCHEME value 0x%x", coding_scheme);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Verify the bootloader */
|
||||
esp_image_metadata_t bootloader_data = { 0 };
|
||||
err = esp_image_verify_bootloader_data(&bootloader_data);
|
||||
err = esp_image_verify_bootloader(&image_len);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "bootloader image appears invalid! error %d", err);
|
||||
return err;
|
||||
@@ -138,7 +131,13 @@ esp_err_t esp_secure_boot_permanently_enable(void) {
|
||||
&& REG_READ(EFUSE_BLK2_RDATA6_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK2_RDATA7_REG) == 0) {
|
||||
ESP_LOGI(TAG, "Generating new secure boot key...");
|
||||
esp_efuse_write_random_key(EFUSE_BLK2_WDATA0_REG);
|
||||
uint32_t buf[8];
|
||||
bootloader_fill_random(buf, sizeof(buf));
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ESP_LOGV(TAG, "EFUSE_BLK2_WDATA%d_REG = 0x%08x", i, buf[i]);
|
||||
REG_WRITE(EFUSE_BLK2_WDATA0_REG + 4*i, buf[i]);
|
||||
}
|
||||
bzero(buf, sizeof(buf));
|
||||
burn_efuses();
|
||||
ESP_LOGI(TAG, "Read & write protecting new key...");
|
||||
REG_WRITE(EFUSE_BLK0_WDATA0_REG, EFUSE_WR_DIS_BLK2 | EFUSE_RD_DIS_BLK2);
|
||||
@@ -151,11 +150,6 @@ esp_err_t esp_secure_boot_permanently_enable(void) {
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Generating secure boot digest...");
|
||||
uint32_t image_len = bootloader_data.image_len;
|
||||
if(bootloader_data.image.hash_appended) {
|
||||
/* Secure boot digest doesn't cover the hash */
|
||||
image_len -= ESP_IMAGE_HASH_LEN;
|
||||
}
|
||||
if (false == secure_boot_generate(image_len)){
|
||||
ESP_LOGE(TAG, "secure boot generation failed");
|
||||
return ESP_FAIL;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "rom/sha.h"
|
||||
typedef SHA_CTX sha_context;
|
||||
#else
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "hwcrypto/sha.h"
|
||||
#endif
|
||||
|
||||
static const char* TAG = "secure_boot";
|
||||
@@ -57,8 +57,8 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
||||
bootloader_sha256_data(handle, data, length);
|
||||
bootloader_sha256_finish(handle, digest);
|
||||
#else
|
||||
/* Use thread-safe mbedTLS version */
|
||||
mbedtls_sha256_ret(data, length, digest, 0);
|
||||
/* Use thread-safe esp-idf SHA function */
|
||||
esp_sha(SHA2_256, data, length, digest);
|
||||
#endif
|
||||
|
||||
// Map the signature block and verify the signature
|
||||
@@ -84,13 +84,10 @@ esp_err_t esp_secure_boot_verify_signature_block(const esp_secure_boot_sig_block
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Verifying secure boot signature");
|
||||
|
||||
is_valid = uECC_verify(signature_verification_key_start,
|
||||
image_digest,
|
||||
DIGEST_LEN,
|
||||
sig_block->signature,
|
||||
uECC_secp256r1());
|
||||
ESP_LOGD(TAG, "Verification result %d", is_valid);
|
||||
return is_valid ? ESP_OK : ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
set(COMPONENT_SRCDIRS ".")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
|
||||
set(COMPONENT_REQUIRES unity bootloader_support app_update)
|
||||
|
||||
register_component()
|
||||
@@ -1,94 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <strings.h>
|
||||
#include "esp_efuse.h"
|
||||
#include "unity.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t unencoded[24];
|
||||
uint32_t encoded[8];
|
||||
} coding_scheme_test_t;
|
||||
|
||||
/* Randomly generated byte strings, encoded and written to ESP32
|
||||
using espefuse algorithm, then verified to have no encoding errors
|
||||
and correct readback.
|
||||
*/
|
||||
static const coding_scheme_test_t coding_scheme_data[] = {
|
||||
{
|
||||
.unencoded = { 0x96, 0xa9, 0xab, 0xb2, 0xda, 0xdd, 0x21, 0xd2, 0x35, 0x22, 0xd3, 0x30, 0x3b, 0xf8, 0xcb, 0x77, 0x8d, 0x8d, 0xf4, 0x96, 0x25, 0xc4, 0xb9, 0x94 },
|
||||
.encoded = { 0xb2aba996, 0x6821ddda, 0x2235d221, 0x430730d3, 0x77cbf83b, 0x627f8d8d, 0xc42596f4, 0x4dae94b9 },
|
||||
},
|
||||
{
|
||||
.unencoded = { 0x0e, 0x6b, 0x1a, 0x1d, 0xa5, 0x9f, 0x24, 0xcf, 0x91, 0x5b, 0xe7, 0xe1, 0x7c, 0x0a, 0x6e, 0xdc, 0x5e, 0x8e, 0xb1, 0xec, 0xd1, 0xf3, 0x75, 0x48 },
|
||||
.encoded = { 0x1d1a6b0e, 0x5e589fa5, 0x5b91cf24, 0x6127e1e7, 0xdc6e0a7c, 0x5d148e5e, 0xf3d1ecb1, 0x57424875 },
|
||||
},
|
||||
{
|
||||
.unencoded = { 0x0a, 0x79, 0x5a, 0x1c, 0xb1, 0x45, 0x71, 0x2c, 0xb3, 0xda, 0x9e, 0xdc, 0x76, 0x27, 0xf5, 0xca, 0xe7, 0x00, 0x39, 0x95, 0x6c, 0x53, 0xc2, 0x07 },
|
||||
.encoded = { 0x1c5a790a, 0x4ac145b1, 0xdab32c71, 0x6476dc9e, 0xcaf52776, 0x4d8900e7, 0x536c9539, 0x495607c2 },
|
||||
},
|
||||
{
|
||||
.unencoded = { 0x76, 0x46, 0x88, 0x2d, 0x4c, 0xe1, 0x50, 0x5d, 0xd6, 0x7c, 0x41, 0x15, 0xc6, 0x1f, 0xd4, 0x60, 0x10, 0x15, 0x2a, 0x72, 0x2d, 0x89, 0x93, 0x13 },
|
||||
.encoded = { 0x2d884676, 0x4838e14c, 0x7cd65d50, 0x4bf31541, 0x60d41fc6, 0x39681510, 0x892d722a, 0x497c1393 },
|
||||
},
|
||||
{
|
||||
.unencoded = { 0x32, 0xbc, 0x40, 0x92, 0x13, 0x37, 0x1a, 0xae, 0xb6, 0x00, 0xed, 0x30, 0xb8, 0x82, 0xee, 0xfc, 0xcf, 0x6d, 0x7f, 0xc5, 0xfa, 0x0e, 0xdd, 0x84 },
|
||||
.encoded = { 0x9240bc32, 0x49783713, 0x00b6ae1a, 0x46df30ed, 0xfcee82b8, 0x6e8a6dcf, 0x0efac57f, 0x571784dd },
|
||||
},
|
||||
{
|
||||
.unencoded = { 0x29, 0xb3, 0x04, 0x95, 0xf2, 0x3c, 0x81, 0xe6, 0x5a, 0xf3, 0x42, 0x82, 0xd1, 0x79, 0xe2, 0x12, 0xbe, 0xc3, 0xd4, 0x10, 0x63, 0x66, 0x9f, 0xe3 },
|
||||
.encoded = { 0x9504b329, 0x51c53cf2, 0xf35ae681, 0x460e8242, 0x12e279d1, 0x5825c3be, 0x666310d4, 0x5ebde39f },
|
||||
},
|
||||
{
|
||||
.unencoded = { 0xda, 0xda, 0x71, 0x4a, 0x62, 0x33, 0xdd, 0x31, 0x87, 0xf3, 0x70, 0x12, 0x33, 0x3b, 0x3b, 0xe9, 0xed, 0xc4, 0x6e, 0x6a, 0xc7, 0xd5, 0x85, 0xfc },
|
||||
.encoded = { 0x4a71dada, 0x4e6a3362, 0xf38731dd, 0x4bfa1270, 0xe93b3b33, 0x61f3c4ed, 0xd5c76a6e, 0x636ffc85 },
|
||||
},
|
||||
{
|
||||
.unencoded = { 0x45, 0x64, 0x51, 0x34, 0x1c, 0x82, 0x81, 0x77, 0xf8, 0x89, 0xb1, 0x15, 0x82, 0x94, 0xdd, 0x64, 0xa2, 0x46, 0x0e, 0xfb, 0x1a, 0x70, 0x4b, 0x9f },
|
||||
.encoded = { 0x34516445, 0x39da821c, 0x89f87781, 0x4f2315b1, 0x64dd9482, 0x474b46a2, 0x701afb0e, 0x5e4b9f4b },
|
||||
},
|
||||
{
|
||||
.unencoded = { 0x89, 0x87, 0x15, 0xb6, 0x66, 0x34, 0x49, 0x18, 0x8b, 0x7b, 0xb2, 0xf6, 0x96, 0x1e, 0x2e, 0xf1, 0x03, 0x9d, 0x4e, 0x16, 0x32, 0xd6, 0x23, 0x22 },
|
||||
.encoded = { 0xb6158789, 0x4eff3466, 0x7b8b1849, 0x63e5f6b2, 0xf12e1e96, 0x54c99d03, 0xd632164e, 0x42bd2223 },
|
||||
},
|
||||
{
|
||||
.unencoded = { 0xa7, 0xa0, 0xb5, 0x21, 0xd2, 0xa3, 0x9f, 0x65, 0xa9, 0xeb, 0x72, 0xa2, 0x2e, 0xa6, 0xfb, 0x9c, 0x48, 0x7e, 0x68, 0x08, 0x7a, 0xb1, 0x4f, 0xbc },
|
||||
.encoded = { 0x21b5a0a7, 0x4ce2a3d2, 0xeba9659f, 0x5868a272, 0x9cfba62e, 0x5fd97e48, 0xb17a0868, 0x5b58bc4f },
|
||||
},
|
||||
{
|
||||
.unencoded = { 0xf7, 0x05, 0xe3, 0x6c, 0xb1, 0x55, 0xcb, 0x2f, 0x8d, 0x3e, 0x0b, 0x2e, 0x3e, 0xb7, 0x02, 0xf5, 0x91, 0xb1, 0xfe, 0x8b, 0x58, 0x50, 0xb2, 0x40 },
|
||||
.encoded = { 0x6ce305f7, 0x569955b1, 0x3e8d2fcb, 0x56722e0b, 0xf502b73e, 0x535eb191, 0x50588bfe, 0x3a8f40b2 },
|
||||
},
|
||||
{
|
||||
.unencoded = { 0x0f, 0x93, 0xb0, 0xd5, 0x60, 0xba, 0x40, 0x2a, 0x62, 0xa6, 0x92, 0x82, 0xb8, 0x91, 0x2c, 0xd7, 0x23, 0xdc, 0x6f, 0x7f, 0x2f, 0xbe, 0x41, 0xf5 },
|
||||
.encoded = { 0xd5b0930f, 0x5123ba60, 0xa6622a40, 0x3bbe8292, 0xd72c91b8, 0x582ddc23, 0xbe2f7f6f, 0x6935f541 },
|
||||
},
|
||||
{
|
||||
.unencoded = { 0x7f, 0x0c, 0x99, 0xde, 0xff, 0x2e, 0xd2, 0x1c, 0x48, 0x98, 0x70, 0x85, 0x15, 0x01, 0x2a, 0xfb, 0xcd, 0xf2, 0xa0, 0xf9, 0x0e, 0xbc, 0x9f, 0x0c },
|
||||
.encoded = { 0xde990c7f, 0x6fe52eff, 0x98481cd2, 0x3deb8570, 0xfb2a0115, 0x61faf2cd, 0xbc0ef9a0, 0x55780c9f },
|
||||
},
|
||||
{
|
||||
.unencoded = { 0x9a, 0x10, 0x92, 0x03, 0x81, 0xfe, 0x41, 0x57, 0x77, 0x02, 0xcb, 0x20, 0x67, 0xa4, 0x97, 0xf3, 0xf8, 0xc7, 0x0d, 0x65, 0xcd, 0xfc, 0x15, 0xef },
|
||||
.encoded = { 0x0392109a, 0x4b64fe81, 0x02775741, 0x418820cb, 0xf397a467, 0x6998c7f8, 0xfccd650d, 0x6ba3ef15 },
|
||||
},
|
||||
};
|
||||
|
||||
TEST_CASE("Test 3/4 Coding Scheme Algorithm", "[bootloader_support]")
|
||||
{
|
||||
const int num_tests = sizeof(coding_scheme_data)/sizeof(coding_scheme_test_t);
|
||||
for (int i = 0; i < num_tests; i++) {
|
||||
uint32_t result[8];
|
||||
const coding_scheme_test_t *t = &coding_scheme_data[i];
|
||||
|
||||
printf("Test case %d...\n", i);
|
||||
esp_err_t r = esp_efuse_apply_34_encoding(t->unencoded, result, sizeof(t->unencoded));
|
||||
TEST_ASSERT_EQUAL_HEX(ESP_OK, r);
|
||||
TEST_ASSERT_EQUAL_HEX32_ARRAY(t->encoded, result, 8);
|
||||
|
||||
// Do the same, 6 bytes at a time
|
||||
for (int offs = 0; offs < sizeof(t->unencoded); offs += 6) {
|
||||
bzero(result, sizeof(result));
|
||||
r = esp_efuse_apply_34_encoding(t->unencoded + offs, result, 6);
|
||||
TEST_ASSERT_EQUAL_HEX(ESP_OK, r);
|
||||
TEST_ASSERT_EQUAL_HEX32_ARRAY(t->encoded + (offs / 6 * 2), result, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include <esp_types.h>
|
||||
#include <stdio.h>
|
||||
#include "string.h"
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
@@ -13,8 +12,7 @@
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "unity.h"
|
||||
#include "bootloader_common.h"
|
||||
#include "bootloader_util.h"
|
||||
|
||||
#include "esp_partition.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_image_format.h"
|
||||
@@ -26,7 +24,7 @@ TEST_CASE("Verify bootloader image in flash", "[bootloader_support]")
|
||||
.size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET,
|
||||
};
|
||||
esp_image_metadata_t data = { 0 };
|
||||
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_verify(ESP_IMAGE_VERIFY, &fake_bootloader_partition, &data));
|
||||
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_load(ESP_IMAGE_VERIFY, &fake_bootloader_partition, &data));
|
||||
TEST_ASSERT_NOT_EQUAL(0, data.image_len);
|
||||
|
||||
uint32_t bootloader_length = 0;
|
||||
@@ -44,72 +42,8 @@ TEST_CASE("Verify unit test app image", "[bootloader_support]")
|
||||
.size = running->size,
|
||||
};
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_verify(ESP_IMAGE_VERIFY, &running_pos, &data));
|
||||
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_load(ESP_IMAGE_VERIFY, &running_pos, &data));
|
||||
TEST_ASSERT_NOT_EQUAL(0, data.image_len);
|
||||
TEST_ASSERT_TRUE(data.image_len <= running->size);
|
||||
}
|
||||
|
||||
void check_label_search (int num_test, const char *list, const char *t_label, bool result)
|
||||
{
|
||||
// gen_esp32part.py trims up to 16 characters
|
||||
// and the string may not have a null terminal symbol.
|
||||
// below is cutting as it does the generator.
|
||||
char label[16 + 1] = {0};
|
||||
strncpy(label, t_label, sizeof(label) - 1);
|
||||
|
||||
bool ret = bootloader_common_label_search(list, label);
|
||||
if (ret != result) {
|
||||
printf("%d) %s | %s \n", num_test, list, label);
|
||||
}
|
||||
TEST_ASSERT_MESSAGE(ret == result, "Test failed");
|
||||
}
|
||||
|
||||
TEST_CASE("Test label_search", "[bootloader_support]")
|
||||
{
|
||||
TEST_ASSERT_FALSE(bootloader_common_label_search(NULL, NULL));
|
||||
TEST_ASSERT_FALSE(bootloader_common_label_search("nvs", NULL));
|
||||
|
||||
check_label_search(1, "nvs", "nvs", true);
|
||||
check_label_search(2, "nvs, ", "nvs", true);
|
||||
check_label_search(3, "nvs1", "nvs", false);
|
||||
check_label_search(3, "nvs1, ", "nvs", false);
|
||||
check_label_search(4, "nvs1nvs1, phy", "nvs1", false);
|
||||
check_label_search(5, "nvs1, nvs1, phy", "nvs1", true);
|
||||
check_label_search(6, "nvs12, nvs12, phy", "nvs1", false);
|
||||
check_label_search(7, "nvs12, nvs1, phy", "nvs1", true);
|
||||
check_label_search(8, "nvs12, nvs3, phy, nvs1","nvs1", true);
|
||||
check_label_search(9, "nvs1nvs1, phy, nvs", "nvs", true);
|
||||
check_label_search(10, "nvs1nvs1, phy, nvs1", "nvs", false);
|
||||
check_label_search(11, "nvs1, nvs, phy, nvs1", "nvs", true);
|
||||
check_label_search(12, "nvs1, nvs2, phy, nvs","nvs", true);
|
||||
check_label_search(13, "ota_data, backup_nvs", "nvs", false);
|
||||
check_label_search(14, "nvs1, nvs2, ota, nvs", "vs1", false);
|
||||
|
||||
check_label_search(20, "12345678901234, phy, nvs1", "12345678901234", true);
|
||||
check_label_search(21, "123456789012345, phy, nvs1", "123456789012345", true);
|
||||
check_label_search(22, "1234567890123456, phy, nvs1", "1234567890123456", true);
|
||||
check_label_search(23, "12345678901234567, phy, nvs1", "12345678901234567", false);
|
||||
check_label_search(24, "1234567890123456, phy, nvs1", "12345678901234567", true);
|
||||
check_label_search(25, "phy, 1234567890123456, nvs1", "12345678901234567", true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Test regions_overlap", "[bootloader_support]")
|
||||
{
|
||||
TEST_ASSERT( bootloader_util_regions_overlap(1, 2, 1, 2) );
|
||||
|
||||
TEST_ASSERT( bootloader_util_regions_overlap(1, 2, 0, 2) );
|
||||
TEST_ASSERT( bootloader_util_regions_overlap(1, 2, 1, 3) );
|
||||
TEST_ASSERT( bootloader_util_regions_overlap(1, 2, 0, 3) );
|
||||
|
||||
TEST_ASSERT( bootloader_util_regions_overlap(0, 2, 1, 2) );
|
||||
TEST_ASSERT( bootloader_util_regions_overlap(1, 3, 1, 2) );
|
||||
TEST_ASSERT( bootloader_util_regions_overlap(0, 3, 1, 2) );
|
||||
|
||||
TEST_ASSERT( !bootloader_util_regions_overlap(2, 3, 1, 2) );
|
||||
TEST_ASSERT( !bootloader_util_regions_overlap(1, 2, 2, 3) );
|
||||
|
||||
TEST_ASSERT( !bootloader_util_regions_overlap(3, 4, 1, 2) );
|
||||
TEST_ASSERT( !bootloader_util_regions_overlap(1, 2, 3, 4) );
|
||||
}
|
||||
|
||||
@@ -1,286 +0,0 @@
|
||||
if(CONFIG_BT_ENABLED)
|
||||
|
||||
set(COMPONENT_SRCS "bt.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS include)
|
||||
|
||||
if(CONFIG_BLUEDROID_ENABLED)
|
||||
|
||||
list(APPEND COMPONENT_PRIV_INCLUDEDIRS
|
||||
bluedroid/bta/include
|
||||
bluedroid/bta/ar/include
|
||||
bluedroid/bta/av/include
|
||||
bluedroid/bta/dm/include
|
||||
bluedroid/bta/gatt/include
|
||||
bluedroid/bta/hh/include
|
||||
bluedroid/bta/jv/include
|
||||
bluedroid/bta/sdp/include
|
||||
bluedroid/bta/sys/include
|
||||
bluedroid/device/include
|
||||
bluedroid/hci/include
|
||||
bluedroid/osi/include
|
||||
bluedroid/external/sbc/decoder/include
|
||||
bluedroid/external/sbc/encoder/include
|
||||
bluedroid/btc/profile/esp/blufi/include
|
||||
bluedroid/btc/profile/esp/include
|
||||
bluedroid/btc/profile/std/a2dp/include
|
||||
bluedroid/btc/profile/std/include
|
||||
bluedroid/btc/include
|
||||
bluedroid/stack/btm/include
|
||||
bluedroid/stack/gap/include
|
||||
bluedroid/stack/gatt/include
|
||||
bluedroid/stack/l2cap/include
|
||||
bluedroid/stack/sdp/include
|
||||
bluedroid/stack/smp/include
|
||||
bluedroid/stack/avct/include
|
||||
bluedroid/stack/avrc/include
|
||||
bluedroid/stack/avdt/include
|
||||
bluedroid/stack/a2dp/include
|
||||
bluedroid/stack/rfcomm/include
|
||||
bluedroid/stack/include
|
||||
bluedroid/common/include)
|
||||
|
||||
list(APPEND COMPONENT_ADD_INCLUDEDIRS bluedroid/api/include/api)
|
||||
|
||||
list(APPEND COMPONENT_SRCS "bluedroid/api/esp_a2dp_api.c"
|
||||
"bluedroid/api/esp_avrc_api.c"
|
||||
"bluedroid/api/esp_blufi_api.c"
|
||||
"bluedroid/api/esp_bt_device.c"
|
||||
"bluedroid/api/esp_bt_main.c"
|
||||
"bluedroid/api/esp_gap_ble_api.c"
|
||||
"bluedroid/api/esp_gap_bt_api.c"
|
||||
"bluedroid/api/esp_gatt_common_api.c"
|
||||
"bluedroid/api/esp_gattc_api.c"
|
||||
"bluedroid/api/esp_gatts_api.c"
|
||||
"bluedroid/api/esp_hf_client_api.c"
|
||||
"bluedroid/api/esp_spp_api.c"
|
||||
"bluedroid/bta/ar/bta_ar.c"
|
||||
"bluedroid/bta/av/bta_av_aact.c"
|
||||
"bluedroid/bta/av/bta_av_act.c"
|
||||
"bluedroid/bta/av/bta_av_api.c"
|
||||
"bluedroid/bta/av/bta_av_cfg.c"
|
||||
"bluedroid/bta/av/bta_av_ci.c"
|
||||
"bluedroid/bta/av/bta_av_main.c"
|
||||
"bluedroid/bta/av/bta_av_sbc.c"
|
||||
"bluedroid/bta/av/bta_av_ssm.c"
|
||||
"bluedroid/bta/dm/bta_dm_act.c"
|
||||
"bluedroid/bta/dm/bta_dm_api.c"
|
||||
"bluedroid/bta/dm/bta_dm_cfg.c"
|
||||
"bluedroid/bta/dm/bta_dm_ci.c"
|
||||
"bluedroid/bta/dm/bta_dm_co.c"
|
||||
"bluedroid/bta/dm/bta_dm_main.c"
|
||||
"bluedroid/bta/dm/bta_dm_pm.c"
|
||||
"bluedroid/bta/dm/bta_dm_sco.c"
|
||||
"bluedroid/bta/gatt/bta_gatt_common.c"
|
||||
"bluedroid/bta/gatt/bta_gattc_act.c"
|
||||
"bluedroid/bta/gatt/bta_gattc_api.c"
|
||||
"bluedroid/bta/gatt/bta_gattc_cache.c"
|
||||
"bluedroid/bta/gatt/bta_gattc_ci.c"
|
||||
"bluedroid/bta/gatt/bta_gattc_co.c"
|
||||
"bluedroid/bta/gatt/bta_gattc_main.c"
|
||||
"bluedroid/bta/gatt/bta_gattc_utils.c"
|
||||
"bluedroid/bta/gatt/bta_gatts_act.c"
|
||||
"bluedroid/bta/gatt/bta_gatts_api.c"
|
||||
"bluedroid/bta/gatt/bta_gatts_co.c"
|
||||
"bluedroid/bta/gatt/bta_gatts_main.c"
|
||||
"bluedroid/bta/gatt/bta_gatts_utils.c"
|
||||
"bluedroid/bta/hh/bta_hh_act.c"
|
||||
"bluedroid/bta/hh/bta_hh_api.c"
|
||||
"bluedroid/bta/hh/bta_hh_cfg.c"
|
||||
"bluedroid/bta/hh/bta_hh_le.c"
|
||||
"bluedroid/bta/hh/bta_hh_main.c"
|
||||
"bluedroid/bta/hh/bta_hh_utils.c"
|
||||
"bluedroid/bta/jv/bta_jv_act.c"
|
||||
"bluedroid/bta/jv/bta_jv_api.c"
|
||||
"bluedroid/bta/jv/bta_jv_cfg.c"
|
||||
"bluedroid/bta/jv/bta_jv_main.c"
|
||||
"bluedroid/bta/sdp/bta_sdp.c"
|
||||
"bluedroid/bta/sdp/bta_sdp_act.c"
|
||||
"bluedroid/bta/sdp/bta_sdp_api.c"
|
||||
"bluedroid/bta/sdp/bta_sdp_cfg.c"
|
||||
"bluedroid/bta/sys/bta_sys_conn.c"
|
||||
"bluedroid/bta/sys/bta_sys_main.c"
|
||||
"bluedroid/bta/sys/utl.c"
|
||||
"bluedroid/btc/core/btc_alarm.c"
|
||||
"bluedroid/btc/core/btc_ble_storage.c"
|
||||
"bluedroid/btc/core/btc_config.c"
|
||||
"bluedroid/btc/core/btc_dev.c"
|
||||
"bluedroid/btc/core/btc_dm.c"
|
||||
"bluedroid/btc/core/btc_main.c"
|
||||
"bluedroid/btc/core/btc_manage.c"
|
||||
"bluedroid/btc/core/btc_profile_queue.c"
|
||||
"bluedroid/btc/core/btc_sec.c"
|
||||
"bluedroid/btc/core/btc_sm.c"
|
||||
"bluedroid/btc/core/btc_storage.c"
|
||||
"bluedroid/btc/core/btc_task.c"
|
||||
"bluedroid/btc/core/btc_util.c"
|
||||
"bluedroid/btc/profile/esp/blufi/blufi_prf.c"
|
||||
"bluedroid/btc/profile/esp/blufi/blufi_protocol.c"
|
||||
"bluedroid/btc/profile/std/a2dp/bta_av_co.c"
|
||||
"bluedroid/btc/profile/std/a2dp/btc_a2dp.c"
|
||||
"bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c"
|
||||
"bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c"
|
||||
"bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c"
|
||||
"bluedroid/btc/profile/std/a2dp/btc_av.c"
|
||||
"bluedroid/btc/profile/std/avrc/btc_avrc.c"
|
||||
"bluedroid/btc/profile/std/gap/btc_gap_ble.c"
|
||||
"bluedroid/btc/profile/std/gap/btc_gap_bt.c"
|
||||
"bluedroid/btc/profile/std/gatt/btc_gatt_common.c"
|
||||
"bluedroid/btc/profile/std/gatt/btc_gatt_util.c"
|
||||
"bluedroid/btc/profile/std/gatt/btc_gattc.c"
|
||||
"bluedroid/btc/profile/std/gatt/btc_gatts.c"
|
||||
"bluedroid/btc/profile/std/spp/btc_spp.c"
|
||||
"bluedroid/device/bdaddr.c"
|
||||
"bluedroid/device/controller.c"
|
||||
"bluedroid/device/interop.c"
|
||||
"bluedroid/external/sbc/decoder/srce/alloc.c"
|
||||
"bluedroid/external/sbc/decoder/srce/bitalloc-sbc.c"
|
||||
"bluedroid/external/sbc/decoder/srce/bitalloc.c"
|
||||
"bluedroid/external/sbc/decoder/srce/bitstream-decode.c"
|
||||
"bluedroid/external/sbc/decoder/srce/decoder-oina.c"
|
||||
"bluedroid/external/sbc/decoder/srce/decoder-private.c"
|
||||
"bluedroid/external/sbc/decoder/srce/decoder-sbc.c"
|
||||
"bluedroid/external/sbc/decoder/srce/dequant.c"
|
||||
"bluedroid/external/sbc/decoder/srce/framing-sbc.c"
|
||||
"bluedroid/external/sbc/decoder/srce/framing.c"
|
||||
"bluedroid/external/sbc/decoder/srce/oi_codec_version.c"
|
||||
"bluedroid/external/sbc/decoder/srce/synthesis-8-generated.c"
|
||||
"bluedroid/external/sbc/decoder/srce/synthesis-dct8.c"
|
||||
"bluedroid/external/sbc/decoder/srce/synthesis-sbc.c"
|
||||
"bluedroid/external/sbc/encoder/srce/sbc_analysis.c"
|
||||
"bluedroid/external/sbc/encoder/srce/sbc_dct.c"
|
||||
"bluedroid/external/sbc/encoder/srce/sbc_dct_coeffs.c"
|
||||
"bluedroid/external/sbc/encoder/srce/sbc_enc_bit_alloc_mono.c"
|
||||
"bluedroid/external/sbc/encoder/srce/sbc_enc_bit_alloc_ste.c"
|
||||
"bluedroid/external/sbc/encoder/srce/sbc_enc_coeffs.c"
|
||||
"bluedroid/external/sbc/encoder/srce/sbc_encoder.c"
|
||||
"bluedroid/external/sbc/encoder/srce/sbc_packing.c"
|
||||
"bluedroid/hci/hci_audio.c"
|
||||
"bluedroid/hci/hci_hal_h4.c"
|
||||
"bluedroid/hci/hci_layer.c"
|
||||
"bluedroid/hci/hci_packet_factory.c"
|
||||
"bluedroid/hci/hci_packet_parser.c"
|
||||
"bluedroid/hci/packet_fragmenter.c"
|
||||
"bluedroid/main/bte_init.c"
|
||||
"bluedroid/main/bte_main.c"
|
||||
"bluedroid/osi/alarm.c"
|
||||
"bluedroid/osi/allocator.c"
|
||||
"bluedroid/osi/buffer.c"
|
||||
"bluedroid/osi/config.c"
|
||||
"bluedroid/osi/fixed_queue.c"
|
||||
"bluedroid/osi/future.c"
|
||||
"bluedroid/osi/hash_functions.c"
|
||||
"bluedroid/osi/hash_map.c"
|
||||
"bluedroid/osi/list.c"
|
||||
"bluedroid/osi/mutex.c"
|
||||
"bluedroid/osi/osi.c"
|
||||
"bluedroid/osi/semaphore.c"
|
||||
"bluedroid/stack/a2dp/a2d_api.c"
|
||||
"bluedroid/stack/a2dp/a2d_sbc.c"
|
||||
"bluedroid/stack/avct/avct_api.c"
|
||||
"bluedroid/stack/avct/avct_ccb.c"
|
||||
"bluedroid/stack/avct/avct_l2c.c"
|
||||
"bluedroid/stack/avct/avct_lcb.c"
|
||||
"bluedroid/stack/avct/avct_lcb_act.c"
|
||||
"bluedroid/stack/avdt/avdt_ad.c"
|
||||
"bluedroid/stack/avdt/avdt_api.c"
|
||||
"bluedroid/stack/avdt/avdt_ccb.c"
|
||||
"bluedroid/stack/avdt/avdt_ccb_act.c"
|
||||
"bluedroid/stack/avdt/avdt_l2c.c"
|
||||
"bluedroid/stack/avdt/avdt_msg.c"
|
||||
"bluedroid/stack/avdt/avdt_scb.c"
|
||||
"bluedroid/stack/avdt/avdt_scb_act.c"
|
||||
"bluedroid/stack/avrc/avrc_api.c"
|
||||
"bluedroid/stack/avrc/avrc_bld_ct.c"
|
||||
"bluedroid/stack/avrc/avrc_bld_tg.c"
|
||||
"bluedroid/stack/avrc/avrc_opt.c"
|
||||
"bluedroid/stack/avrc/avrc_pars_ct.c"
|
||||
"bluedroid/stack/avrc/avrc_pars_tg.c"
|
||||
"bluedroid/stack/avrc/avrc_sdp.c"
|
||||
"bluedroid/stack/avrc/avrc_utils.c"
|
||||
"bluedroid/stack/btm/btm_acl.c"
|
||||
"bluedroid/stack/btm/btm_ble.c"
|
||||
"bluedroid/stack/btm/btm_ble_addr.c"
|
||||
"bluedroid/stack/btm/btm_ble_adv_filter.c"
|
||||
"bluedroid/stack/btm/btm_ble_batchscan.c"
|
||||
"bluedroid/stack/btm/btm_ble_bgconn.c"
|
||||
"bluedroid/stack/btm/btm_ble_cont_energy.c"
|
||||
"bluedroid/stack/btm/btm_ble_gap.c"
|
||||
"bluedroid/stack/btm/btm_ble_multi_adv.c"
|
||||
"bluedroid/stack/btm/btm_ble_privacy.c"
|
||||
"bluedroid/stack/btm/btm_dev.c"
|
||||
"bluedroid/stack/btm/btm_devctl.c"
|
||||
"bluedroid/stack/btm/btm_inq.c"
|
||||
"bluedroid/stack/btm/btm_main.c"
|
||||
"bluedroid/stack/btm/btm_pm.c"
|
||||
"bluedroid/stack/btm/btm_sco.c"
|
||||
"bluedroid/stack/btm/btm_sec.c"
|
||||
"bluedroid/stack/btu/btu_hcif.c"
|
||||
"bluedroid/stack/btu/btu_init.c"
|
||||
"bluedroid/stack/btu/btu_task.c"
|
||||
"bluedroid/stack/gap/gap_api.c"
|
||||
"bluedroid/stack/gap/gap_ble.c"
|
||||
"bluedroid/stack/gap/gap_conn.c"
|
||||
"bluedroid/stack/gap/gap_utils.c"
|
||||
"bluedroid/stack/gatt/att_protocol.c"
|
||||
"bluedroid/stack/gatt/gatt_api.c"
|
||||
"bluedroid/stack/gatt/gatt_attr.c"
|
||||
"bluedroid/stack/gatt/gatt_auth.c"
|
||||
"bluedroid/stack/gatt/gatt_cl.c"
|
||||
"bluedroid/stack/gatt/gatt_db.c"
|
||||
"bluedroid/stack/gatt/gatt_main.c"
|
||||
"bluedroid/stack/gatt/gatt_sr.c"
|
||||
"bluedroid/stack/gatt/gatt_utils.c"
|
||||
"bluedroid/stack/hcic/hciblecmds.c"
|
||||
"bluedroid/stack/hcic/hcicmds.c"
|
||||
"bluedroid/stack/l2cap/l2c_api.c"
|
||||
"bluedroid/stack/l2cap/l2c_ble.c"
|
||||
"bluedroid/stack/l2cap/l2c_csm.c"
|
||||
"bluedroid/stack/l2cap/l2c_fcr.c"
|
||||
"bluedroid/stack/l2cap/l2c_link.c"
|
||||
"bluedroid/stack/l2cap/l2c_main.c"
|
||||
"bluedroid/stack/l2cap/l2c_ucd.c"
|
||||
"bluedroid/stack/l2cap/l2c_utils.c"
|
||||
"bluedroid/stack/l2cap/l2cap_client.c"
|
||||
"bluedroid/stack/rfcomm/port_api.c"
|
||||
"bluedroid/stack/rfcomm/port_rfc.c"
|
||||
"bluedroid/stack/rfcomm/port_utils.c"
|
||||
"bluedroid/stack/rfcomm/rfc_l2cap_if.c"
|
||||
"bluedroid/stack/rfcomm/rfc_mx_fsm.c"
|
||||
"bluedroid/stack/rfcomm/rfc_port_fsm.c"
|
||||
"bluedroid/stack/rfcomm/rfc_port_if.c"
|
||||
"bluedroid/stack/rfcomm/rfc_ts_frames.c"
|
||||
"bluedroid/stack/rfcomm/rfc_utils.c"
|
||||
"bluedroid/stack/sdp/sdp_api.c"
|
||||
"bluedroid/stack/sdp/sdp_db.c"
|
||||
"bluedroid/stack/sdp/sdp_discovery.c"
|
||||
"bluedroid/stack/sdp/sdp_main.c"
|
||||
"bluedroid/stack/sdp/sdp_server.c"
|
||||
"bluedroid/stack/sdp/sdp_utils.c"
|
||||
"bluedroid/stack/smp/aes.c"
|
||||
"bluedroid/stack/smp/p_256_curvepara.c"
|
||||
"bluedroid/stack/smp/p_256_ecc_pp.c"
|
||||
"bluedroid/stack/smp/p_256_multprecision.c"
|
||||
"bluedroid/stack/smp/smp_act.c"
|
||||
"bluedroid/stack/smp/smp_api.c"
|
||||
"bluedroid/stack/smp/smp_br_main.c"
|
||||
"bluedroid/stack/smp/smp_cmac.c"
|
||||
"bluedroid/stack/smp/smp_keys.c"
|
||||
"bluedroid/stack/smp/smp_l2c.c"
|
||||
"bluedroid/stack/smp/smp_main.c"
|
||||
"bluedroid/stack/smp/smp_utils.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# requirements can't depend on config
|
||||
set(COMPONENT_PRIV_REQUIRES nvs_flash)
|
||||
|
||||
register_component()
|
||||
|
||||
if(CONFIG_BT_ENABLED)
|
||||
if(GCC_NOT_5_2_0)
|
||||
component_compile_options(-Wno-implicit-fallthrough -Wno-unused-const-variable)
|
||||
endif()
|
||||
|
||||
target_link_libraries(bt "-L${CMAKE_CURRENT_LIST_DIR}/lib")
|
||||
target_link_libraries(bt btdm_app)
|
||||
endif()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,17 +12,30 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "common/bt_target.h"
|
||||
#include "bt_target.h"
|
||||
#include <string.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_a2dp_api.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "btc/btc_manage.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_av.h"
|
||||
|
||||
#if BTC_AV_INCLUDED
|
||||
|
||||
#if BTC_AV_SINK_INCLUDED
|
||||
esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (callback == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_profile_cb_set(BTC_PID_A2DP, callback);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_a2d_sink_init(void)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
@@ -30,7 +43,7 @@ esp_err_t esp_a2d_sink_init(void)
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_SINK_API_INIT_EVT;
|
||||
@@ -45,9 +58,9 @@ esp_err_t esp_a2d_sink_deinit(void)
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_SINK_API_DEINIT_EVT;
|
||||
@@ -57,7 +70,7 @@ esp_err_t esp_a2d_sink_deinit(void)
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback)
|
||||
esp_err_t esp_a2d_register_data_callback(esp_a2d_data_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
@@ -69,11 +82,11 @@ esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback)
|
||||
msg.act = BTC_AV_SINK_API_REG_DATA_CB_EVT;
|
||||
|
||||
btc_av_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_av_args_t));
|
||||
memset(&arg, 0, sizeof(btc_av_args_t));
|
||||
arg.data_cb = callback;
|
||||
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_msg_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -82,17 +95,17 @@ esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda)
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
|
||||
bt_status_t stat;
|
||||
btc_av_args_t arg;
|
||||
btc_msg_t msg;
|
||||
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_SINK_API_CONNECT_EVT;
|
||||
|
||||
memset(&arg, 0, sizeof(btc_av_args_t));
|
||||
|
||||
|
||||
/* Switch to BTC context */
|
||||
memcpy(&(arg.connect), remote_bda, sizeof(bt_bdaddr_t));
|
||||
stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
|
||||
@@ -104,10 +117,10 @@ esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda)
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
|
||||
bt_status_t stat;
|
||||
btc_msg_t msg;
|
||||
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_SINK_API_DISCONNECT_EVT;
|
||||
@@ -117,139 +130,4 @@ esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda)
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#endif /* BTC_AV_SINK_INCLUDED */
|
||||
|
||||
esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (callback == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_profile_cb_set(BTC_PID_A2DP, callback);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
bt_status_t stat;
|
||||
btc_av_args_t arg;
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_API_MEDIA_CTRL_EVT;
|
||||
|
||||
memset(&arg, 0, sizeof(btc_av_args_t));
|
||||
|
||||
/* Switch to BTC context */
|
||||
arg.ctrl = ctrl;
|
||||
stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#if BTC_AV_SRC_INCLUDED
|
||||
esp_err_t esp_a2d_source_init(void)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_SRC_API_INIT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_a2d_source_deinit(void)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_SRC_API_DEINIT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_a2d_source_connect(esp_bd_addr_t remote_bda)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
bt_status_t stat;
|
||||
btc_av_args_t arg;
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_SRC_API_CONNECT_EVT;
|
||||
|
||||
memset(&arg, 0, sizeof(btc_av_args_t));
|
||||
|
||||
/* Switch to BTC context */
|
||||
memcpy(&(arg.src_connect), remote_bda, sizeof(bt_bdaddr_t));
|
||||
stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_a2d_source_disconnect(esp_bd_addr_t remote_bda)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
bt_status_t stat;
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_SRC_API_DISCONNECT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_SRC_API_REG_DATA_CB_EVT;
|
||||
|
||||
btc_av_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_av_args_t));
|
||||
arg.src_data_cb = callback;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#endif /* BTC_AV_SRC_INCLUDED */
|
||||
|
||||
#endif /* #if BTC_AV_INCLUDED */
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "common/bt_target.h"
|
||||
#include "bt_target.h"
|
||||
#include <string.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_avrc_api.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "btc/btc_manage.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_avrc.h"
|
||||
|
||||
#if BTC_AV_INCLUDED
|
||||
|
||||
@@ -16,13 +16,12 @@
|
||||
#include "esp_blufi_api.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "btc/btc_task.h"
|
||||
#include "btc_task.h"
|
||||
#include "btc_blufi_prf.h"
|
||||
#include "btc/btc_manage.h"
|
||||
#include "btc/btc_main.h"
|
||||
#include "osi/future.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_main.h"
|
||||
#include "future.h"
|
||||
#include "btc_gatts.h"
|
||||
#include "btc_gatt_util.h"
|
||||
|
||||
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks)
|
||||
{
|
||||
@@ -58,23 +57,6 @@ esp_err_t esp_blufi_send_wifi_conn_report(wifi_mode_t opmode, esp_blufi_sta_conn
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_blufi_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_SEND_WIFI_LIST;
|
||||
arg.wifi_list.apCount = apCount;
|
||||
arg.wifi_list.list = list;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_profile_init(void)
|
||||
{
|
||||
@@ -121,44 +103,7 @@ esp_err_t esp_blufi_close(esp_gatt_if_t gatts_if, uint16_t conn_id)
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_CLOSE;
|
||||
arg.close.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id);
|
||||
arg.close.conn_id = conn_id;
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_send_error_info(esp_blufi_error_state_t state)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_blufi_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_SEND_ERR_INFO;
|
||||
arg.blufi_err_infor.state = state;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_send_custom_data(uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_blufi_args_t arg;
|
||||
if(data == NULL || data_len == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_SEND_CUSTOM_DATA;
|
||||
arg.custom_data.data = data;
|
||||
arg.custom_data.data_len = data_len;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
#include <string.h>
|
||||
#include "esp_bt_device.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "device/controller.h"
|
||||
#include "btc/btc_task.h"
|
||||
#include "btc/btc_dev.h"
|
||||
#include "controller.h"
|
||||
#include "btc_task.h"
|
||||
#include "btc_dev.h"
|
||||
|
||||
const uint8_t *esp_bt_dev_get_address(void)
|
||||
{
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
|
||||
|
||||
#include "esp_bt_main.h"
|
||||
#include "btc/btc_task.h"
|
||||
#include "btc/btc_main.h"
|
||||
#include "btc_task.h"
|
||||
#include "btc_main.h"
|
||||
#include "esp_bt.h"
|
||||
#include "osi/future.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "future.h"
|
||||
#include "allocator.h"
|
||||
|
||||
static bool bd_already_enable = false;
|
||||
static bool bd_already_init = false;
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
#include "esp_bt_device.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_gap_ble_api.h"
|
||||
#include "bta/bta_api.h"
|
||||
#include "common/bt_trace.h"
|
||||
#include "btc/btc_manage.h"
|
||||
#include "bta_api.h"
|
||||
#include "bt_trace.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_gap_ble.h"
|
||||
#include "btc/btc_ble_storage.h"
|
||||
#include "btc_ble_storage.h"
|
||||
|
||||
|
||||
esp_err_t esp_ble_gap_register_callback(esp_gap_ble_cb_t callback)
|
||||
@@ -35,7 +35,7 @@ esp_err_t esp_ble_gap_config_adv_data(esp_ble_adv_data_t *adv_data)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (adv_data == NULL) {
|
||||
@@ -60,7 +60,7 @@ esp_err_t esp_ble_gap_set_scan_params(esp_ble_scan_params_t *scan_params)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (scan_params == NULL) {
|
||||
@@ -179,18 +179,6 @@ esp_err_t esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr)
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_clear_rand_addr(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_CLEAR_RAND_ADDRESS;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable)
|
||||
{
|
||||
@@ -207,86 +195,6 @@ esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable)
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_config_local_icon (uint16_t icon)
|
||||
{
|
||||
esp_err_t ret;
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
switch (icon) {
|
||||
case ESP_BLE_APPEARANCE_GENERIC_PHONE:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_COMPUTER:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_REMOTE:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_THERMOMETER:
|
||||
case ESP_BLE_APPEARANCE_THERMOMETER_EAR:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_HEART_RATE:
|
||||
case ESP_BLE_APPEARANCE_HEART_RATE_BELT:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE:
|
||||
case ESP_BLE_APPEARANCE_BLOOD_PRESSURE_ARM:
|
||||
case ESP_BLE_APPEARANCE_BLOOD_PRESSURE_WRIST:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_PULSE_OXIMETER:
|
||||
case ESP_BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP:
|
||||
case ESP_BLE_APPEARANCE_PULSE_OXIMETER_WRIST:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_GLUCOSE:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_WEIGHT:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_WALKING:
|
||||
case ESP_BLE_APPEARANCE_WALKING_IN_SHOE:
|
||||
case ESP_BLE_APPEARANCE_WALKING_ON_SHOE:
|
||||
case ESP_BLE_APPEARANCE_WALKING_ON_HIP:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_WATCH:
|
||||
case ESP_BLE_APPEARANCE_SPORTS_WATCH:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_EYEGLASSES:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_DISPLAY:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_MEDIA_PLAYER:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_BARCODE_SCANNER:
|
||||
case ESP_BLE_APPEARANCE_HID_BARCODE_SCANNER:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_HID:
|
||||
case ESP_BLE_APPEARANCE_HID_KEYBOARD:
|
||||
case ESP_BLE_APPEARANCE_HID_MOUSE:
|
||||
case ESP_BLE_APPEARANCE_HID_JOYSTICK:
|
||||
case ESP_BLE_APPEARANCE_HID_GAMEPAD:
|
||||
case ESP_BLE_APPEARANCE_HID_DIGITIZER_TABLET:
|
||||
case ESP_BLE_APPEARANCE_HID_CARD_READER:
|
||||
case ESP_BLE_APPEARANCE_HID_DIGITAL_PEN:
|
||||
case ESP_BLE_APPEARANCE_UNKNOWN:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_CLOCK:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_TAG:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_KEYRING:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_CYCLING:
|
||||
case ESP_BLE_APPEARANCE_CYCLING_COMPUTER:
|
||||
case ESP_BLE_APPEARANCE_CYCLING_SPEED:
|
||||
case ESP_BLE_APPEARANCE_CYCLING_CADENCE:
|
||||
case ESP_BLE_APPEARANCE_CYCLING_POWER:
|
||||
case ESP_BLE_APPEARANCE_CYCLING_SPEED_CADENCE:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_PERSONAL_MOBILITY_DEVICE:
|
||||
case ESP_BLE_APPEARANCE_POWERED_WHEELCHAIR:
|
||||
case ESP_BLE_APPEARANCE_MOBILITY_SCOOTER:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_CONTINUOUS_GLUCOSE_MONITOR:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_INSULIN_PUMP:
|
||||
case ESP_BLE_APPEARANCE_INSULIN_PUMP_DURABLE_PUMP:
|
||||
case ESP_BLE_APPEARANCE_INSULIN_PUMP_PATCH_PUMP:
|
||||
case ESP_BLE_APPEARANCE_INSULIN_PEN:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_MEDICATION_DELIVERY:
|
||||
case ESP_BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS:
|
||||
case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION:
|
||||
case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_AND_NAV:
|
||||
case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD:
|
||||
case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD_AND_NAV:
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_CONFIG_LOCAL_ICON;
|
||||
arg.cfg_local_icon.icon = icon;
|
||||
ret = (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
break;
|
||||
default:
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_update_whitelist(bool add_remove, esp_bd_addr_t remote_bda)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
@@ -360,18 +268,6 @@ esp_err_t esp_ble_gap_set_device_name(const char *name)
|
||||
return esp_bt_dev_set_device_name(name);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_get_local_used_addr(esp_bd_addr_t local_used_addr, uint8_t * addr_type)
|
||||
{
|
||||
if(esp_bluedroid_get_status() != (ESP_BLUEDROID_STATUS_ENABLED)) {
|
||||
LOG_ERROR("%s, bluedroid status error", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if(!BTM_BleGetCurrentAddress(local_used_addr, addr_type)) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint8_t *esp_ble_resolve_adv_data( uint8_t *adv_data, uint8_t type, uint8_t *length)
|
||||
{
|
||||
if (((type < ESP_BLE_AD_TYPE_FLAG) || (type > ESP_BLE_AD_TYPE_128SERVICE_DATA)) &&
|
||||
@@ -449,94 +345,10 @@ esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_d
|
||||
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_add_duplicate_scan_exceptional_device(esp_ble_duplicate_exceptional_info_type_t type, esp_duplicate_info_t device_info)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (!device_info && type <= ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_LINK_ID) {
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST;
|
||||
arg.update_duplicate_exceptional_list.subcode = ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_ADD;
|
||||
arg.update_duplicate_exceptional_list.info_type = type;
|
||||
if (device_info) {
|
||||
memcpy(arg.update_duplicate_exceptional_list.device_info, device_info, sizeof(esp_bd_addr_t));
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_remove_duplicate_scan_exceptional_device(esp_ble_duplicate_exceptional_info_type_t type, esp_duplicate_info_t device_info)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (!device_info && type <= ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_LINK_ID) {
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST;
|
||||
arg.update_duplicate_exceptional_list.subcode = ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_REMOVE;
|
||||
arg.update_duplicate_exceptional_list.info_type = type;
|
||||
if (device_info) {
|
||||
memcpy(arg.update_duplicate_exceptional_list.device_info, device_info, sizeof(esp_bd_addr_t));
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_clean_duplicate_scan_exceptional_list(esp_duplicate_scan_exceptional_list_type_t list_type)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST;
|
||||
arg.update_duplicate_exceptional_list.subcode = ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_CLEAN;
|
||||
arg.update_duplicate_exceptional_list.info_type = list_type;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
esp_err_t esp_ble_gap_set_security_param(esp_ble_sm_param_t param_type,
|
||||
void *value, uint8_t len)
|
||||
{
|
||||
if(param_type >= ESP_BLE_SM_MAX_PARAM) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if((param_type != ESP_BLE_SM_CLEAR_STATIC_PASSKEY) && ( value == NULL || len < sizeof(uint8_t) || len > sizeof(uint32_t))) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if((param_type == ESP_BLE_SM_SET_STATIC_PASSKEY)) {
|
||||
uint32_t passkey = 0;
|
||||
for(uint8_t i = 0; i < len; i++)
|
||||
{
|
||||
passkey += (((uint8_t *)value)[i]<<(8*i));
|
||||
}
|
||||
if(passkey > 999999) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
@@ -638,9 +450,7 @@ esp_err_t esp_ble_remove_bond_device(esp_bd_addr_t bd_addr)
|
||||
|
||||
int esp_ble_get_bond_device_num(void)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
return btc_storage_get_num_ble_bond_devices();
|
||||
}
|
||||
|
||||
@@ -12,30 +12,15 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "common/bt_target.h"
|
||||
#include "bt_target.h"
|
||||
#include <string.h>
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_gap_bt_api.h"
|
||||
#include "common/bt_trace.h"
|
||||
#include "btc/btc_manage.h"
|
||||
#include "bt_trace.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_gap_bt.h"
|
||||
#include "btc/btc_storage.h"
|
||||
|
||||
#if (BTC_GAP_BT_INCLUDED == TRUE)
|
||||
|
||||
esp_err_t esp_bt_gap_register_callback(esp_bt_gap_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (callback == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_profile_cb_set(BTC_PID_GAP_BT, callback);
|
||||
return ESP_OK;
|
||||
}
|
||||
#if BTC_GAP_BT_INCLUDED
|
||||
|
||||
esp_err_t esp_bt_gap_set_scan_mode(esp_bt_scan_mode_t mode)
|
||||
{
|
||||
@@ -45,7 +30,7 @@ esp_err_t esp_bt_gap_set_scan_mode(esp_bt_scan_mode_t mode)
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BT;
|
||||
msg.act = BTC_GAP_BT_ACT_SET_SCAN_MODE;
|
||||
@@ -54,297 +39,4 @@ esp_err_t esp_bt_gap_set_scan_mode(esp_bt_scan_mode_t mode)
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_gap_start_discovery(esp_bt_inq_mode_t mode, uint8_t inq_len, uint8_t num_rsps)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_gap_bt_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (mode != ESP_BT_INQ_MODE_GENERAL_INQUIRY &&
|
||||
mode != ESP_BT_INQ_MODE_LIMITED_INQUIRY) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (inq_len < ESP_BT_GAP_MIN_INQ_LEN ||
|
||||
inq_len > ESP_BT_GAP_MAX_INQ_LEN) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BT;
|
||||
msg.act = BTC_GAP_BT_ACT_START_DISCOVERY;
|
||||
|
||||
arg.start_disc.mode = mode;
|
||||
arg.start_disc.inq_len = inq_len;
|
||||
arg.start_disc.num_rsps = num_rsps;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_gap_cancel_discovery(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BT;
|
||||
msg.act = BTC_GAP_BT_ACT_CANCEL_DISCOVERY;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_gap_get_remote_services(esp_bd_addr_t remote_bda)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_gap_bt_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BT;
|
||||
msg.act = BTC_GAP_BT_ACT_GET_REMOTE_SERVICES;
|
||||
|
||||
memcpy(&arg.bda, remote_bda, sizeof(bt_bdaddr_t));
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_gap_get_remote_service_record(esp_bd_addr_t remote_bda, esp_bt_uuid_t *uuid)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_gap_bt_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BT;
|
||||
msg.act = BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD;
|
||||
|
||||
memcpy(&arg.get_rmt_srv_rcd.bda, remote_bda, sizeof(bt_bdaddr_t));
|
||||
memcpy(&arg.get_rmt_srv_rcd.uuid, uuid, sizeof(esp_bt_uuid_t));
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
uint8_t *esp_bt_gap_resolve_eir_data(uint8_t *eir, esp_bt_eir_type_t type, uint8_t *length)
|
||||
{
|
||||
if (!eir) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return BTM_CheckEirData(eir, type, length);
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_gap_set_cod(esp_bt_cod_t cod, esp_bt_cod_mode_t mode)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_gap_bt_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case ESP_BT_SET_COD_MAJOR_MINOR:
|
||||
case ESP_BT_SET_COD_SERVICE_CLASS:
|
||||
case ESP_BT_CLR_COD_SERVICE_CLASS:
|
||||
case ESP_BT_SET_COD_ALL:
|
||||
case ESP_BT_INIT_COD:
|
||||
break;
|
||||
default:
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
break;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BT;
|
||||
msg.act = BTC_GAP_BT_ACT_SET_COD;
|
||||
|
||||
arg.set_cod.mode = mode;
|
||||
memcpy(&arg.set_cod.cod, &cod, sizeof(esp_bt_cod_t));
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_bt_gap_get_cod(esp_bt_cod_t *cod)
|
||||
{
|
||||
return btc_gap_bt_get_cod(cod);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_bt_gap_read_rssi_delta(esp_bd_addr_t remote_addr)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_gap_bt_args_t arg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BT;
|
||||
msg.act = BTC_GAP_BT_ACT_READ_RSSI_DELTA;
|
||||
memcpy(arg.read_rssi_delta.bda.address, remote_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_gap_remove_bond_device(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_gap_bt_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BT;
|
||||
msg.act = BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE;
|
||||
|
||||
memcpy(arg.rm_bond_device.bda.address, bd_addr, sizeof(esp_bd_addr_t));
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
int esp_bt_gap_get_bond_device_num(void)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return btc_storage_get_num_bt_bond_devices();
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_gap_get_bond_device_list(int *dev_num, esp_bd_addr_t *dev_list)
|
||||
{
|
||||
int ret;
|
||||
int dev_num_total;
|
||||
|
||||
if (dev_num == NULL || dev_list == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
dev_num_total = btc_storage_get_num_bt_bond_devices();
|
||||
if (*dev_num > dev_num_total) {
|
||||
*dev_num = dev_num_total;
|
||||
}
|
||||
|
||||
ret = btc_storage_get_bonded_bt_devices_list((bt_bdaddr_t *)dev_list, *dev_num);
|
||||
|
||||
return (ret == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_gap_set_pin(esp_bt_pin_type_t pin_type, uint8_t pin_code_len, esp_bt_pin_code_t pin_code)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_gap_bt_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BT;
|
||||
msg.act = BTC_GAP_BT_ACT_SET_PIN_TYPE;
|
||||
arg.set_pin_type.pin_type = pin_type;
|
||||
if (pin_type == ESP_BT_PIN_TYPE_FIXED){
|
||||
arg.set_pin_type.pin_code_len = pin_code_len;
|
||||
memcpy(arg.set_pin_type.pin_code, pin_code, pin_code_len);
|
||||
} else {
|
||||
arg.set_pin_type.pin_code_len = 0;
|
||||
memset(arg.set_pin_type.pin_code, 0, ESP_BT_PIN_CODE_LEN);
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_gap_pin_reply(esp_bd_addr_t bd_addr, bool accept, uint8_t pin_code_len, esp_bt_pin_code_t pin_code)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_gap_bt_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BT;
|
||||
msg.act = BTC_GAP_BT_ACT_PIN_REPLY;
|
||||
arg.pin_reply.accept = accept;
|
||||
arg.pin_reply.pin_code_len = pin_code_len;
|
||||
memcpy(arg.pin_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t));
|
||||
memcpy(arg.pin_reply.pin_code, pin_code, pin_code_len);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
#if (BT_SSP_INCLUDED == TRUE)
|
||||
esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type,
|
||||
void *value, uint8_t len)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_gap_bt_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BT;
|
||||
msg.act = BTC_GAP_BT_ACT_SET_SECURITY_PARAM;
|
||||
arg.set_security_param.param_type = param_type;
|
||||
arg.set_security_param.len = len;
|
||||
arg.set_security_param.value = value;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_gap_bt_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BT;
|
||||
msg.act = BTC_GAP_BT_ACT_PASSKEY_REPLY;
|
||||
arg.passkey_reply.accept = accept;
|
||||
arg.passkey_reply.passkey = passkey;
|
||||
memcpy(arg.passkey_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t));
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr, bool accept)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_gap_bt_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BT;
|
||||
msg.act = BTC_GAP_BT_ACT_CONFIRM_REPLY;
|
||||
arg.confirm_reply.accept = accept;
|
||||
memcpy(arg.confirm_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t));
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
#endif /*(BT_SSP_INCLUDED == TRUE)*/
|
||||
|
||||
#endif /* #if BTC_GAP_BT_INCLUDED == TRUE */
|
||||
#endif /* #if BTC_GAP_BT_INCLUDED */
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "esp_gatt_common_api.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_gatt_defs.h"
|
||||
#include "btc_gatt_common.h"
|
||||
#include "btc_main.h"
|
||||
|
||||
/**
|
||||
* @brief This function is called to set local MTU,
|
||||
@@ -32,7 +32,7 @@
|
||||
esp_err_t esp_ble_gatt_set_local_mtu (uint16_t mtu)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatt_com_args_t arg;
|
||||
btc_ble_main_args_t arg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
@@ -41,9 +41,9 @@ esp_err_t esp_ble_gatt_set_local_mtu (uint16_t mtu)
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATT_COMMON;
|
||||
msg.pid = BTC_PID_MAIN_INIT;
|
||||
msg.act = BTC_GATT_ACT_SET_LOCAL_MTU;
|
||||
arg.set_mtu.mtu = mtu;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatt_com_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_main_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
@@ -16,12 +16,9 @@
|
||||
|
||||
#include "esp_gattc_api.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "btc/btc_manage.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_gattc.h"
|
||||
#include "btc_gatt_util.h"
|
||||
#include "stack/l2cdefs.h"
|
||||
#include "stack/l2c_api.h"
|
||||
|
||||
|
||||
#if (GATTC_INCLUDED == TRUE)
|
||||
esp_err_t esp_ble_gattc_register_callback(esp_gattc_cb_t callback)
|
||||
@@ -164,7 +161,6 @@ esp_gatt_status_t esp_ble_gattc_get_all_char(esp_gatt_if_t gattc_if,
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if ((start_handle == 0) && (end_handle == 0)) {
|
||||
*count = 0;
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
@@ -207,7 +203,6 @@ esp_gatt_status_t esp_ble_gattc_get_char_by_uuid(esp_gatt_if_t gattc_if,
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (start_handle == 0 && end_handle == 0) {
|
||||
*count = 0;
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
@@ -249,7 +244,6 @@ esp_gatt_status_t esp_ble_gattc_get_descr_by_char_handle(esp_gatt_if_t gattc_if,
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (char_handle == 0) {
|
||||
*count = 0;
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
@@ -272,7 +266,6 @@ esp_gatt_status_t esp_ble_gattc_get_include_service(esp_gatt_if_t gattc_if,
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (start_handle == 0 && end_handle == 0) {
|
||||
*count = 0;
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
@@ -295,7 +288,6 @@ esp_gatt_status_t esp_ble_gattc_get_attr_count(esp_gatt_if_t gattc_if,
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if ((start_handle == 0 && end_handle == 0) && (type != ESP_GATT_DB_DESCRIPTOR)) {
|
||||
*count = 0;
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
@@ -313,7 +305,6 @@ esp_gatt_status_t esp_ble_gattc_get_db(esp_gatt_if_t gattc_if, uint16_t conn_id,
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (start_handle == 0 && end_handle == 0) {
|
||||
*count = 0;
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
@@ -335,11 +326,6 @@ esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if,
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, conn_id)) {
|
||||
LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_READ_CHAR;
|
||||
@@ -359,11 +345,6 @@ esp_err_t esp_ble_gattc_read_multiple(esp_gatt_if_t gattc_if,
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, conn_id)) {
|
||||
LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_READ_MULTIPLE_CHAR;
|
||||
@@ -390,11 +371,6 @@ esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if,
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, conn_id)) {
|
||||
LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_READ_CHAR_DESCR;
|
||||
@@ -417,11 +393,6 @@ esp_err_t esp_ble_gattc_write_char(esp_gatt_if_t gattc_if,
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, conn_id)) {
|
||||
LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_WRITE_CHAR;
|
||||
@@ -447,11 +418,6 @@ esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, conn_id)) {
|
||||
LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_WRITE_CHAR_DESCR;
|
||||
@@ -477,11 +443,6 @@ esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, conn_id)) {
|
||||
LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_PREPARE_WRITE;
|
||||
@@ -507,11 +468,6 @@ esp_err_t esp_ble_gattc_prepare_write_char_descr(esp_gatt_if_t gattc_if,
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (L2CA_CheckIsCongest(L2CAP_ATT_CID, conn_id)) {
|
||||
LOG_DEBUG("%s, the l2cap chanel is congest.", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_PREPARE_WRITE_CHAR_DESCR;
|
||||
@@ -591,37 +547,5 @@ esp_err_t esp_ble_gattc_cache_refresh(esp_bd_addr_t remote_bda)
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_cache_assoc(esp_gatt_if_t gattc_if, esp_bd_addr_t src_addr, esp_bd_addr_t assoc_addr, bool is_assoc)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_CACHE_ASSOC;
|
||||
arg.cache_assoc.is_assoc = is_assoc;
|
||||
arg.cache_assoc.gattc_if = gattc_if;
|
||||
memcpy(arg.cache_assoc.src_addr, src_addr, sizeof(esp_bd_addr_t));
|
||||
memcpy(arg.cache_assoc.assoc_addr, assoc_addr, sizeof(esp_bd_addr_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_cache_get_addr_list(esp_gatt_if_t gattc_if)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ATC_CACHE_GET_ADDR_LIST;
|
||||
arg.get_addr_list.gattc_if = gattc_if;
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
#endif ///GATTC_INCLUDED == TRUE
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user